ccxt 4.1.65 → 4.1.67
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.js +245 -75
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +236 -74
- package/dist/cjs/src/bingx.js +1 -0
- package/dist/cjs/src/coinbase.js +1 -1
- package/dist/cjs/src/gate.js +7 -0
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/base/Exchange.d.ts +20 -1
- package/js/src/base/Exchange.js +236 -74
- package/js/src/base/types.d.ts +2 -0
- package/js/src/bingx.js +1 -0
- package/js/src/coinbase.js +1 -1
- package/js/src/gate.js +7 -0
- package/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.d.ts +1 -1
- package/package.json +1 -1
- package/skip-tests.json +14 -7
package/js/src/base/Exchange.js
CHANGED
|
@@ -40,6 +40,9 @@ export default class Exchange {
|
|
|
40
40
|
this.origin = '*'; // CORS origin
|
|
41
41
|
//
|
|
42
42
|
this.agent = undefined; // maintained for backwards compatibility
|
|
43
|
+
this.nodeHttpModuleLoaded = false;
|
|
44
|
+
this.httpAgent = undefined;
|
|
45
|
+
this.httpsAgent = undefined;
|
|
43
46
|
this.minFundingAddressLength = 1; // used in checkAddress
|
|
44
47
|
this.substituteCommonCurrencyCodes = true; // reserved
|
|
45
48
|
this.quoteJsonNumbers = true; // treat numbers in json as quoted precise strings
|
|
@@ -201,6 +204,12 @@ export default class Exchange {
|
|
|
201
204
|
this.ymd = ymd;
|
|
202
205
|
this.base64ToString = base64ToString;
|
|
203
206
|
this.crc32 = crc32;
|
|
207
|
+
this.httpProxyAgentModule = undefined;
|
|
208
|
+
this.httpsProxyAgentModule = undefined;
|
|
209
|
+
this.socksProxyAgentModule = undefined;
|
|
210
|
+
this.socksProxyAgentModuleChecked = false;
|
|
211
|
+
this.proxyDictionaries = {};
|
|
212
|
+
this.proxyModulesLoaded = false;
|
|
204
213
|
Object.assign(this, functions);
|
|
205
214
|
//
|
|
206
215
|
// if (isNode) {
|
|
@@ -639,39 +648,89 @@ export default class Exchange {
|
|
|
639
648
|
log(...args) {
|
|
640
649
|
console.log(...args);
|
|
641
650
|
}
|
|
651
|
+
async loadProxyModules() {
|
|
652
|
+
this.proxyModulesLoaded = true;
|
|
653
|
+
// todo: possible sync alternatives: https://stackoverflow.com/questions/51069002/convert-import-to-synchronous
|
|
654
|
+
this.httpProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/http-proxy-agent/index.js');
|
|
655
|
+
this.httpsProxyAgentModule = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
|
|
656
|
+
if (this.socksProxyAgentModuleChecked === false) {
|
|
657
|
+
this.socksProxyAgentModuleChecked = true;
|
|
658
|
+
try {
|
|
659
|
+
// @ts-ignore
|
|
660
|
+
this.socksProxyAgentModule = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
|
|
661
|
+
}
|
|
662
|
+
catch (e) { }
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
setProxyAgents(httpProxy, httpsProxy, socksProxy) {
|
|
666
|
+
let chosenAgent = undefined;
|
|
667
|
+
if (httpProxy) {
|
|
668
|
+
if (this.httpProxyAgentModule === undefined) {
|
|
669
|
+
throw new NotSupported(this.id + ' you need to load JS proxy modules with `.loadProxyModules()` method at first to use proxies');
|
|
670
|
+
}
|
|
671
|
+
if (!(httpProxy in this.proxyDictionaries)) {
|
|
672
|
+
this.proxyDictionaries[httpProxy] = new this.httpProxyAgentModule.HttpProxyAgent(httpProxy);
|
|
673
|
+
}
|
|
674
|
+
chosenAgent = this.proxyDictionaries[httpProxy];
|
|
675
|
+
}
|
|
676
|
+
else if (httpsProxy) {
|
|
677
|
+
if (this.httpsProxyAgentModule === undefined) {
|
|
678
|
+
throw new NotSupported(this.id + ' you need to load JS proxy modules with `.loadProxyModules()` method at first to use proxies');
|
|
679
|
+
}
|
|
680
|
+
if (!(httpsProxy in this.proxyDictionaries)) {
|
|
681
|
+
this.proxyDictionaries[httpsProxy] = new this.httpsProxyAgentModule.HttpsProxyAgent(httpsProxy);
|
|
682
|
+
}
|
|
683
|
+
chosenAgent = this.proxyDictionaries[httpsProxy];
|
|
684
|
+
chosenAgent.keepAlive = true;
|
|
685
|
+
}
|
|
686
|
+
else if (socksProxy) {
|
|
687
|
+
if (this.socksProxyAgentModule === undefined) {
|
|
688
|
+
throw new NotSupported(this.id + ' - to use SOCKS proxy with ccxt, at first you need install module "npm i socks-proxy-agent" and then initialize proxies with `.loadProxyModules()` method');
|
|
689
|
+
}
|
|
690
|
+
if (!(socksProxy in this.proxyDictionaries)) {
|
|
691
|
+
this.proxyDictionaries[socksProxy] = new this.socksProxyAgentModule.SocksProxyAgent(socksProxy);
|
|
692
|
+
}
|
|
693
|
+
chosenAgent = this.proxyDictionaries[socksProxy];
|
|
694
|
+
}
|
|
695
|
+
return chosenAgent;
|
|
696
|
+
}
|
|
642
697
|
async fetch(url, method = 'GET', headers = undefined, body = undefined) {
|
|
698
|
+
// load node-http(s) modules only on first call
|
|
699
|
+
if (isNode) {
|
|
700
|
+
if (!this.nodeHttpModuleLoaded) {
|
|
701
|
+
this.nodeHttpModuleLoaded = true;
|
|
702
|
+
const httpsModule = await import(/* webpackIgnore: true */ 'node:https');
|
|
703
|
+
this.httpsAgent = new httpsModule.Agent({ keepAlive: true });
|
|
704
|
+
}
|
|
705
|
+
}
|
|
643
706
|
// ##### PROXY & HEADERS #####
|
|
644
707
|
headers = this.extend(this.headers, headers);
|
|
645
|
-
|
|
708
|
+
// proxy-url
|
|
709
|
+
const proxyUrl = this.checkProxyUrlSettings(url, method, headers, body);
|
|
710
|
+
let isHttpAgentNeeded = false;
|
|
646
711
|
if (proxyUrl !== undefined) {
|
|
647
712
|
// in node we need to set header to *
|
|
648
713
|
if (isNode) {
|
|
649
714
|
headers = this.extend({ 'Origin': this.origin }, headers);
|
|
715
|
+
if (proxyUrl.substring(0, 5) !== 'https') {
|
|
716
|
+
// for `http://` protocol proxy-urls, we need to load `http` module only on first call
|
|
717
|
+
if (!this.httpAgent) {
|
|
718
|
+
const httpModule = await import(/* webpackIgnore: true */ 'node:http');
|
|
719
|
+
this.httpAgent = new httpModule.Agent();
|
|
720
|
+
}
|
|
721
|
+
isHttpAgentNeeded = true;
|
|
722
|
+
}
|
|
650
723
|
}
|
|
651
724
|
url = proxyUrl + url;
|
|
652
725
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
else if (httpsProxy !== undefined) {
|
|
659
|
-
const module = await import(/* webpackIgnore: true */ '../static_dependencies/proxies/https-proxy-agent/index.js');
|
|
660
|
-
const proxyAgent = new module.HttpsProxyAgent(httpsProxy);
|
|
661
|
-
proxyAgent.keepAlive = true;
|
|
662
|
-
this.agent = proxyAgent;
|
|
663
|
-
}
|
|
664
|
-
else if (socksProxy !== undefined) {
|
|
665
|
-
let module = undefined;
|
|
666
|
-
try {
|
|
667
|
-
// @ts-ignore
|
|
668
|
-
module = await import(/* webpackIgnore: true */ 'socks-proxy-agent');
|
|
669
|
-
}
|
|
670
|
-
catch (e) {
|
|
671
|
-
throw new NotSupported(this.id + ' - to use SOCKS proxy with ccxt, at first you need install module "npm i socks-proxy-agent" ');
|
|
672
|
-
}
|
|
673
|
-
this.agent = new module.SocksProxyAgent(socksProxy);
|
|
726
|
+
// proxy agents
|
|
727
|
+
const [httpProxy, httpsProxy, socksProxy] = this.checkProxySettings(url, method, headers, body);
|
|
728
|
+
this.checkConflictingProxies(httpProxy || httpsProxy || socksProxy, proxyUrl);
|
|
729
|
+
if (!this.proxyModulesLoaded) {
|
|
730
|
+
await this.loadProxyModules(); // this is needed in JS, independently whether proxy properties were set or not, we have to load them because of necessity in WS, which would happen beyond 'fetch' method (WS/etc)
|
|
674
731
|
}
|
|
732
|
+
const chosenAgent = this.setProxyAgents(httpProxy, httpsProxy, socksProxy);
|
|
733
|
+
// user-agent
|
|
675
734
|
const userAgent = (this.userAgent !== undefined) ? this.userAgent : this.user_agent;
|
|
676
735
|
if (userAgent && isNode) {
|
|
677
736
|
if (typeof userAgent === 'string') {
|
|
@@ -681,17 +740,18 @@ export default class Exchange {
|
|
|
681
740
|
headers = this.extend(userAgent, headers);
|
|
682
741
|
}
|
|
683
742
|
}
|
|
743
|
+
// set final headers
|
|
684
744
|
headers = this.setHeaders(headers);
|
|
685
|
-
//
|
|
745
|
+
// log
|
|
686
746
|
if (this.verbose) {
|
|
687
747
|
this.log("fetch Request:\n", this.id, method, url, "\nRequestHeaders:\n", headers, "\nRequestBody:\n", body, "\n");
|
|
688
748
|
}
|
|
749
|
+
// end of proxies & headers
|
|
689
750
|
if (this.fetchImplementation === undefined) {
|
|
690
751
|
if (isNode) {
|
|
691
752
|
const module = await import(/* webpackIgnore: true */ '../static_dependencies/node-fetch/index.js');
|
|
692
753
|
if (this.agent === undefined) {
|
|
693
|
-
|
|
694
|
-
this.agent = new Agent({ keepAlive: true });
|
|
754
|
+
this.agent = this.httpsAgent;
|
|
695
755
|
}
|
|
696
756
|
this.AbortError = module.AbortError;
|
|
697
757
|
this.fetchImplementation = module.default;
|
|
@@ -710,6 +770,15 @@ export default class Exchange {
|
|
|
710
770
|
if (this.agent) {
|
|
711
771
|
params['agent'] = this.agent;
|
|
712
772
|
}
|
|
773
|
+
// override agent, if needed
|
|
774
|
+
if (isHttpAgentNeeded) {
|
|
775
|
+
// if proxyUrl is being used, so we don't overwrite `this.agent` itself
|
|
776
|
+
params['agent'] = this.httpAgent;
|
|
777
|
+
}
|
|
778
|
+
else if (chosenAgent) {
|
|
779
|
+
// if http(s)Proxy is being used
|
|
780
|
+
params['agent'] = chosenAgent;
|
|
781
|
+
}
|
|
713
782
|
const controller = new AbortController();
|
|
714
783
|
params['signal'] = controller.signal;
|
|
715
784
|
const timeout = setTimeout(() => {
|
|
@@ -910,6 +979,11 @@ export default class Exchange {
|
|
|
910
979
|
const onConnected = this.onConnected.bind(this);
|
|
911
980
|
// decide client type here: ws / signalr / socketio
|
|
912
981
|
const wsOptions = this.safeValue(this.options, 'ws', {});
|
|
982
|
+
// proxy agents
|
|
983
|
+
const [httpProxy, httpsProxy, socksProxy] = this.checkWsProxySettings();
|
|
984
|
+
const chosenAgent = this.setProxyAgents(httpProxy, httpsProxy, socksProxy);
|
|
985
|
+
const finalAgent = chosenAgent ? chosenAgent : this.agent;
|
|
986
|
+
//
|
|
913
987
|
const options = this.deepExtend(this.streaming, {
|
|
914
988
|
'log': this.log ? this.log.bind(this) : this.log,
|
|
915
989
|
'ping': this.ping ? this.ping.bind(this) : this.ping,
|
|
@@ -917,7 +991,7 @@ export default class Exchange {
|
|
|
917
991
|
'throttler': new Throttler(this.tokenBucket),
|
|
918
992
|
// add support for proxies
|
|
919
993
|
'options': {
|
|
920
|
-
'agent':
|
|
994
|
+
'agent': finalAgent,
|
|
921
995
|
}
|
|
922
996
|
}, wsOptions);
|
|
923
997
|
this.clients[url] = new WsClient(url, onMessage, onError, onClose, onConnected, options);
|
|
@@ -1083,6 +1157,9 @@ export default class Exchange {
|
|
|
1083
1157
|
getProperty(obj, property, defaultValue = undefined) {
|
|
1084
1158
|
return (property in obj ? obj[property] : defaultValue);
|
|
1085
1159
|
}
|
|
1160
|
+
setProperty(obj, property, defaultValue = undefined) {
|
|
1161
|
+
obj[property] = defaultValue;
|
|
1162
|
+
}
|
|
1086
1163
|
axolotl(payload, hexKey, ed25519) {
|
|
1087
1164
|
return axolotl(payload, hexKey, ed25519);
|
|
1088
1165
|
}
|
|
@@ -1151,14 +1228,28 @@ export default class Exchange {
|
|
|
1151
1228
|
}
|
|
1152
1229
|
return undefined;
|
|
1153
1230
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
if (
|
|
1158
|
-
proxyUrl
|
|
1231
|
+
checkProxyUrlSettings(url = undefined, method = undefined, headers = undefined, body = undefined) {
|
|
1232
|
+
const usedProxies = [];
|
|
1233
|
+
let proxyUrl = undefined;
|
|
1234
|
+
if (this.proxyUrl !== undefined) {
|
|
1235
|
+
usedProxies.push('proxyUrl');
|
|
1236
|
+
proxyUrl = this.proxyUrl;
|
|
1237
|
+
}
|
|
1238
|
+
if (this.proxy_url !== undefined) {
|
|
1239
|
+
usedProxies.push('proxy_url');
|
|
1240
|
+
proxyUrl = this.proxy_url;
|
|
1241
|
+
}
|
|
1242
|
+
if (this.proxyUrlCallback !== undefined) {
|
|
1243
|
+
usedProxies.push('proxyUrlCallback');
|
|
1244
|
+
proxyUrl = this.proxyUrlCallback(url, method, headers, body);
|
|
1245
|
+
}
|
|
1246
|
+
if (this.proxy_url_callback !== undefined) {
|
|
1247
|
+
usedProxies.push('proxy_url_callback');
|
|
1248
|
+
proxyUrl = this.proxy_url_callback(url, method, headers, body);
|
|
1159
1249
|
}
|
|
1160
1250
|
// backwards-compatibility
|
|
1161
1251
|
if (this.proxy !== undefined) {
|
|
1252
|
+
usedProxies.push('proxy');
|
|
1162
1253
|
if (typeof this.proxy === 'function') {
|
|
1163
1254
|
proxyUrl = this.proxy(url, method, headers, body);
|
|
1164
1255
|
}
|
|
@@ -1166,50 +1257,111 @@ export default class Exchange {
|
|
|
1166
1257
|
proxyUrl = this.proxy;
|
|
1167
1258
|
}
|
|
1168
1259
|
}
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
let
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
}
|
|
1194
|
-
if (
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
}
|
|
1203
|
-
if (
|
|
1204
|
-
|
|
1260
|
+
const length = usedProxies.length;
|
|
1261
|
+
if (length > 1) {
|
|
1262
|
+
const joinedProxyNames = usedProxies.join(',');
|
|
1263
|
+
throw new ExchangeError(this.id + ' you have multiple conflicting proxy_url settings (' + joinedProxyNames + '), please use only one from : proxyUrl, proxy_url, proxyUrlCallback, proxy_url_callback');
|
|
1264
|
+
}
|
|
1265
|
+
return proxyUrl;
|
|
1266
|
+
}
|
|
1267
|
+
checkProxySettings(url = undefined, method = undefined, headers = undefined, body = undefined) {
|
|
1268
|
+
const usedProxies = [];
|
|
1269
|
+
let httpProxy = undefined;
|
|
1270
|
+
let httpsProxy = undefined;
|
|
1271
|
+
let socksProxy = undefined;
|
|
1272
|
+
// httpProxy
|
|
1273
|
+
if (this.httpProxy !== undefined) {
|
|
1274
|
+
usedProxies.push('httpProxy');
|
|
1275
|
+
httpProxy = this.httpProxy;
|
|
1276
|
+
}
|
|
1277
|
+
if (this.http_proxy !== undefined) {
|
|
1278
|
+
usedProxies.push('http_proxy');
|
|
1279
|
+
httpProxy = this.http_proxy;
|
|
1280
|
+
}
|
|
1281
|
+
if (this.httpProxyCallback !== undefined) {
|
|
1282
|
+
usedProxies.push('httpProxyCallback');
|
|
1283
|
+
httpProxy = this.httpProxyCallback(url, method, headers, body);
|
|
1284
|
+
}
|
|
1285
|
+
if (this.http_proxy_callback !== undefined) {
|
|
1286
|
+
usedProxies.push('http_proxy_callback');
|
|
1287
|
+
httpProxy = this.http_proxy_callback(url, method, headers, body);
|
|
1288
|
+
}
|
|
1289
|
+
// httpsProxy
|
|
1290
|
+
if (this.httpsProxy !== undefined) {
|
|
1291
|
+
usedProxies.push('httpsProxy');
|
|
1292
|
+
httpsProxy = this.httpsProxy;
|
|
1293
|
+
}
|
|
1294
|
+
if (this.https_proxy !== undefined) {
|
|
1295
|
+
usedProxies.push('https_proxy');
|
|
1296
|
+
httpsProxy = this.https_proxy;
|
|
1297
|
+
}
|
|
1298
|
+
if (this.httpsProxyCallback !== undefined) {
|
|
1299
|
+
usedProxies.push('httpsProxyCallback');
|
|
1300
|
+
httpsProxy = this.httpsProxyCallback(url, method, headers, body);
|
|
1301
|
+
}
|
|
1302
|
+
if (this.https_proxy_callback !== undefined) {
|
|
1303
|
+
usedProxies.push('https_proxy_callback');
|
|
1304
|
+
httpsProxy = this.https_proxy_callback(url, method, headers, body);
|
|
1305
|
+
}
|
|
1306
|
+
// socksProxy
|
|
1307
|
+
if (this.socksProxy !== undefined) {
|
|
1308
|
+
usedProxies.push('socksProxy');
|
|
1309
|
+
socksProxy = this.socksProxy;
|
|
1310
|
+
}
|
|
1311
|
+
if (this.socks_proxy !== undefined) {
|
|
1312
|
+
usedProxies.push('socks_proxy');
|
|
1313
|
+
socksProxy = this.socks_proxy;
|
|
1314
|
+
}
|
|
1315
|
+
if (this.socksProxyCallback !== undefined) {
|
|
1316
|
+
usedProxies.push('socksProxyCallback');
|
|
1317
|
+
socksProxy = this.socksProxyCallback(url, method, headers, body);
|
|
1318
|
+
}
|
|
1319
|
+
if (this.socks_proxy_callback !== undefined) {
|
|
1320
|
+
usedProxies.push('socks_proxy_callback');
|
|
1321
|
+
socksProxy = this.socks_proxy_callback(url, method, headers, body);
|
|
1322
|
+
}
|
|
1323
|
+
// check
|
|
1324
|
+
const length = usedProxies.length;
|
|
1325
|
+
if (length > 1) {
|
|
1326
|
+
const joinedProxyNames = usedProxies.join(',');
|
|
1327
|
+
throw new ExchangeError(this.id + ' you have multiple conflicting settings (' + joinedProxyNames + '), please use only one from: httpProxy, httpsProxy, httpProxyCallback, httpsProxyCallback, socksProxy, socksProxyCallback');
|
|
1328
|
+
}
|
|
1329
|
+
return [httpProxy, httpsProxy, socksProxy];
|
|
1330
|
+
}
|
|
1331
|
+
checkWsProxySettings() {
|
|
1332
|
+
const usedProxies = [];
|
|
1333
|
+
let wsProxy = undefined;
|
|
1334
|
+
let wssProxy = undefined;
|
|
1335
|
+
// wsProxy
|
|
1336
|
+
if (this.wsProxy !== undefined) {
|
|
1337
|
+
usedProxies.push('wsProxy');
|
|
1338
|
+
wsProxy = this.wsProxy;
|
|
1339
|
+
}
|
|
1340
|
+
if (this.ws_proxy !== undefined) {
|
|
1341
|
+
usedProxies.push('ws_proxy');
|
|
1342
|
+
wsProxy = this.ws_proxy;
|
|
1343
|
+
}
|
|
1344
|
+
// wsProxy
|
|
1345
|
+
if (this.wssProxy !== undefined) {
|
|
1346
|
+
usedProxies.push('wssProxy');
|
|
1347
|
+
wssProxy = this.wssProxy;
|
|
1348
|
+
}
|
|
1349
|
+
if (this.wss_proxy !== undefined) {
|
|
1350
|
+
usedProxies.push('wss_proxy');
|
|
1351
|
+
wssProxy = this.wss_proxy;
|
|
1352
|
+
}
|
|
1353
|
+
// check
|
|
1354
|
+
const length = usedProxies.length;
|
|
1355
|
+
if (length > 1) {
|
|
1356
|
+
const joinedProxyNames = usedProxies.join(',');
|
|
1357
|
+
throw new ExchangeError(this.id + ' you have multiple conflicting settings (' + joinedProxyNames + '), please use only one from: wsProxy, wssProxy');
|
|
1358
|
+
}
|
|
1359
|
+
return [wsProxy, wssProxy];
|
|
1360
|
+
}
|
|
1361
|
+
checkConflictingProxies(proxyAgentSet, proxyUrlSet) {
|
|
1362
|
+
if (proxyAgentSet && proxyUrlSet) {
|
|
1363
|
+
throw new ExchangeError(this.id + ' you have multiple conflicting proxy settings, please use only one from : proxyUrl, httpProxy, httpsProxy, socksProxy');
|
|
1205
1364
|
}
|
|
1206
|
-
if (socksProxyCallback !== undefined) {
|
|
1207
|
-
val = val + 1;
|
|
1208
|
-
}
|
|
1209
|
-
if (val > 1) {
|
|
1210
|
-
throw new ExchangeError(this.id + ' you have multiple conflicting proxy settings, please use only one from : proxyUrl, httpProxy, httpsProxy, socksProxy, userAgent');
|
|
1211
|
-
}
|
|
1212
|
-
return [proxyUrl, httpProxy, httpsProxy, socksProxy];
|
|
1213
1365
|
}
|
|
1214
1366
|
findMessageHashes(client, element) {
|
|
1215
1367
|
const result = [];
|
|
@@ -1592,6 +1744,7 @@ export default class Exchange {
|
|
|
1592
1744
|
'contract': undefined,
|
|
1593
1745
|
'linear': undefined,
|
|
1594
1746
|
'inverse': undefined,
|
|
1747
|
+
'subType': undefined,
|
|
1595
1748
|
'taker': undefined,
|
|
1596
1749
|
'maker': undefined,
|
|
1597
1750
|
'contractSize': undefined,
|
|
@@ -1669,6 +1822,15 @@ export default class Exchange {
|
|
|
1669
1822
|
'precision': this.precision,
|
|
1670
1823
|
'limits': this.limits,
|
|
1671
1824
|
}, this.fees['trading'], value);
|
|
1825
|
+
if (market['linear']) {
|
|
1826
|
+
market['subType'] = 'linear';
|
|
1827
|
+
}
|
|
1828
|
+
else if (market['inverse']) {
|
|
1829
|
+
market['subType'] = 'inverse';
|
|
1830
|
+
}
|
|
1831
|
+
else {
|
|
1832
|
+
market['subType'] = undefined;
|
|
1833
|
+
}
|
|
1672
1834
|
values.push(market);
|
|
1673
1835
|
}
|
|
1674
1836
|
this.markets = this.indexBy(values, 'symbol');
|
package/js/src/base/types.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare type IndexType = number | string;
|
|
|
7
7
|
export declare type OrderSide = 'buy' | 'sell' | string;
|
|
8
8
|
export declare type OrderType = 'limit' | 'market' | string;
|
|
9
9
|
export declare type MarketType = 'spot' | 'margin' | 'swap' | 'future' | 'option';
|
|
10
|
+
export declare type SubType = 'linear' | 'inverse' | undefined;
|
|
10
11
|
export interface Dictionary<T> {
|
|
11
12
|
[key: string]: T;
|
|
12
13
|
}
|
|
@@ -32,6 +33,7 @@ export interface MarketInterface {
|
|
|
32
33
|
quoteId: string;
|
|
33
34
|
active: Bool;
|
|
34
35
|
type: MarketType;
|
|
36
|
+
subType?: SubType;
|
|
35
37
|
spot: boolean;
|
|
36
38
|
margin: boolean;
|
|
37
39
|
swap: boolean;
|
package/js/src/bingx.js
CHANGED
|
@@ -75,6 +75,7 @@ export default class bingx extends Exchange {
|
|
|
75
75
|
'user': 'https://open-api.{hostname}/openApi',
|
|
76
76
|
'subAccount': 'https://open-api.{hostname}/openApi',
|
|
77
77
|
'account': 'https://open-api.{hostname}/openApi',
|
|
78
|
+
'copyTrading': 'https://open-api.{hostname}/openApi',
|
|
78
79
|
},
|
|
79
80
|
'www': 'https://bingx.com/',
|
|
80
81
|
'doc': 'https://bingx-api.github.io/docs/',
|
package/js/src/coinbase.js
CHANGED
package/js/src/gate.js
CHANGED
|
@@ -945,6 +945,13 @@ export default class gate extends Exchange {
|
|
|
945
945
|
}
|
|
946
946
|
else if (symbol in this.markets_by_id) {
|
|
947
947
|
const markets = this.markets_by_id[symbol];
|
|
948
|
+
const defaultType = this.safeString2(this.options, 'defaultType', 'defaultSubType', 'spot');
|
|
949
|
+
for (let i = 0; i < markets.length; i++) {
|
|
950
|
+
const market = markets[i];
|
|
951
|
+
if (market[defaultType]) {
|
|
952
|
+
return market;
|
|
953
|
+
}
|
|
954
|
+
}
|
|
948
955
|
return markets[0];
|
|
949
956
|
}
|
|
950
957
|
else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1)) {
|
|
@@ -15,7 +15,7 @@ export declare class BigInteger {
|
|
|
15
15
|
protected intValue(): number;
|
|
16
16
|
protected byteValue(): number;
|
|
17
17
|
protected shortValue(): number;
|
|
18
|
-
protected signum():
|
|
18
|
+
protected signum(): 1 | 0 | -1;
|
|
19
19
|
toByteArray(): number[];
|
|
20
20
|
protected equals(a: BigInteger): boolean;
|
|
21
21
|
protected min(a: BigInteger): BigInteger;
|
package/package.json
CHANGED
package/skip-tests.json
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"skipWs": true
|
|
21
21
|
},
|
|
22
22
|
"ascendex": {
|
|
23
|
+
"skipPhpAsync": true,
|
|
23
24
|
"skipMethods": {
|
|
24
25
|
"loadMarkets": {
|
|
25
26
|
"currencyIdAndCode": "broken currencies"
|
|
@@ -48,7 +49,7 @@
|
|
|
48
49
|
}
|
|
49
50
|
},
|
|
50
51
|
"binance": {
|
|
51
|
-
"
|
|
52
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
52
53
|
"skipPhpAsync": true,
|
|
53
54
|
"skipWs": true,
|
|
54
55
|
"skipMethods": {
|
|
@@ -80,7 +81,7 @@
|
|
|
80
81
|
}
|
|
81
82
|
},
|
|
82
83
|
"binancecoinm": {
|
|
83
|
-
"
|
|
84
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
84
85
|
"skipPhpAsync": true,
|
|
85
86
|
"skipWs": true,
|
|
86
87
|
"skipMethods": {
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
}
|
|
100
101
|
},
|
|
101
102
|
"binanceusdm": {
|
|
102
|
-
"
|
|
103
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
103
104
|
"skipPhpAsync": true,
|
|
104
105
|
"skipWs": true,
|
|
105
106
|
"skipMethods": {
|
|
@@ -138,7 +139,7 @@
|
|
|
138
139
|
}
|
|
139
140
|
},
|
|
140
141
|
"tokocrypto": {
|
|
141
|
-
"
|
|
142
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
142
143
|
"skipPhpAsync": true,
|
|
143
144
|
"skipWs": true
|
|
144
145
|
},
|
|
@@ -589,7 +590,7 @@
|
|
|
589
590
|
}
|
|
590
591
|
},
|
|
591
592
|
"buda": {
|
|
592
|
-
"
|
|
593
|
+
"httpProxy": "http://5.75.153.75:8002"
|
|
593
594
|
},
|
|
594
595
|
"bigone": {
|
|
595
596
|
"skipMethods": {
|
|
@@ -679,7 +680,9 @@
|
|
|
679
680
|
},
|
|
680
681
|
"cex": {
|
|
681
682
|
"skipWs": true,
|
|
683
|
+
"skipPhpAsync": true,
|
|
682
684
|
"skipMethods": {
|
|
685
|
+
"proxies": "probably they do not permit our proxy location",
|
|
683
686
|
"loadMarkets": {
|
|
684
687
|
"active":"is undefined"
|
|
685
688
|
},
|
|
@@ -712,7 +715,9 @@
|
|
|
712
715
|
},
|
|
713
716
|
"cryptocom": {
|
|
714
717
|
"skipWs": true,
|
|
718
|
+
"skipPhpAsync": true,
|
|
715
719
|
"skipMethods": {
|
|
720
|
+
"proxies": "probably they do not permit our proxy",
|
|
716
721
|
"loadMarkets": {
|
|
717
722
|
"limits":"max is below min",
|
|
718
723
|
"active":"is undefined",
|
|
@@ -1081,7 +1086,7 @@
|
|
|
1081
1086
|
}
|
|
1082
1087
|
},
|
|
1083
1088
|
"kuna": {
|
|
1084
|
-
"
|
|
1089
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
1085
1090
|
"skipPhpAsync": true,
|
|
1086
1091
|
"skipMethods": {
|
|
1087
1092
|
"loadMarkets": {
|
|
@@ -1270,6 +1275,7 @@
|
|
|
1270
1275
|
}
|
|
1271
1276
|
},
|
|
1272
1277
|
"phemex": {
|
|
1278
|
+
"skipPhpAsync": true,
|
|
1273
1279
|
"skipMethods": {
|
|
1274
1280
|
"loadMarkets": {
|
|
1275
1281
|
"contractSize": "broken for some markets",
|
|
@@ -1378,6 +1384,7 @@
|
|
|
1378
1384
|
},
|
|
1379
1385
|
"kraken": {
|
|
1380
1386
|
"skipWs": true,
|
|
1387
|
+
"skipPhpAsync": true,
|
|
1381
1388
|
"skipMethods": {
|
|
1382
1389
|
"fetchCurrencies": {
|
|
1383
1390
|
"withdraw": "undefined",
|
|
@@ -1417,7 +1424,7 @@
|
|
|
1417
1424
|
}
|
|
1418
1425
|
},
|
|
1419
1426
|
"ripio": {
|
|
1420
|
-
"
|
|
1427
|
+
"httpProxy": "http://5.75.153.75:8002",
|
|
1421
1428
|
"skipWs": true
|
|
1422
1429
|
},
|
|
1423
1430
|
"timex": {
|