ccxt 4.5.2 → 4.5.4
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 +4 -4
- package/dist/ccxt.browser.min.js +2 -2
- package/dist/cjs/ccxt.js +1 -1
- package/dist/cjs/src/base/Exchange.js +78 -5
- package/dist/cjs/src/base/functions/encode.js +8 -0
- package/dist/cjs/src/base/functions/rsa.js +14 -1
- package/dist/cjs/src/base/functions.js +1 -0
- package/dist/cjs/src/binance.js +12 -15
- package/dist/cjs/src/bitget.js +1 -1
- package/dist/cjs/src/bitvavo.js +8 -0
- package/dist/cjs/src/bybit.js +20 -6
- package/dist/cjs/src/coinbase.js +28 -10
- package/dist/cjs/src/coincatch.js +34 -21
- package/dist/cjs/src/delta.js +1 -0
- package/dist/cjs/src/gate.js +27 -12
- package/dist/cjs/src/gemini.js +3 -3
- package/dist/cjs/src/htx.js +4 -4
- package/dist/cjs/src/kucoinfutures.js +11 -10
- package/dist/cjs/src/mexc.js +30 -1
- package/dist/cjs/src/okx.js +19 -4
- package/dist/cjs/src/pro/binance.js +3 -3
- package/dist/cjs/src/pro/bitfinex.js +140 -0
- package/dist/cjs/src/pro/bitget.js +168 -26
- package/dist/cjs/src/pro/bybit.js +67 -11
- package/dist/cjs/src/pro/coinex.js +10 -11
- package/dist/cjs/src/pro/kucoin.js +64 -0
- package/dist/cjs/src/pro/mexc.js +7 -3
- package/js/ccxt.d.ts +1 -1
- package/js/ccxt.js +1 -1
- package/js/src/abstract/myokx.d.ts +1 -0
- package/js/src/abstract/okx.d.ts +1 -0
- package/js/src/abstract/okxus.d.ts +1 -0
- package/js/src/base/Exchange.d.ts +6 -0
- package/js/src/base/Exchange.js +78 -5
- package/js/src/base/functions/encode.d.ts +2 -1
- package/js/src/base/functions/encode.js +8 -1
- package/js/src/base/functions/rsa.js +16 -3
- package/js/src/binance.js +12 -15
- package/js/src/bitget.js +1 -1
- package/js/src/bitvavo.js +8 -0
- package/js/src/bybit.js +20 -6
- package/js/src/coinbase.d.ts +1 -1
- package/js/src/coinbase.js +28 -10
- package/js/src/coincatch.d.ts +2 -0
- package/js/src/coincatch.js +34 -21
- package/js/src/delta.js +1 -0
- package/js/src/gate.js +27 -12
- package/js/src/gemini.js +3 -3
- package/js/src/htx.js +4 -4
- package/js/src/kucoinfutures.js +11 -10
- package/js/src/mexc.d.ts +3 -0
- package/js/src/mexc.js +30 -1
- package/js/src/okx.d.ts +4 -2
- package/js/src/okx.js +19 -4
- package/js/src/pro/binance.js +3 -3
- package/js/src/pro/bitfinex.d.ts +30 -0
- package/js/src/pro/bitfinex.js +140 -0
- package/js/src/pro/bitget.d.ts +9 -1
- package/js/src/pro/bitget.js +168 -26
- package/js/src/pro/bybit.d.ts +6 -2
- package/js/src/pro/bybit.js +67 -11
- package/js/src/pro/coinex.js +11 -12
- package/js/src/pro/kucoin.d.ts +22 -0
- package/js/src/pro/kucoin.js +64 -0
- package/js/src/pro/mexc.js +7 -3
- package/package.json +3 -3
package/dist/cjs/ccxt.js
CHANGED
|
@@ -192,7 +192,7 @@ var xt$1 = require('./src/pro/xt.js');
|
|
|
192
192
|
|
|
193
193
|
//-----------------------------------------------------------------------------
|
|
194
194
|
// this is updated by vss.js when building
|
|
195
|
-
const version = '4.5.
|
|
195
|
+
const version = '4.5.4';
|
|
196
196
|
Exchange["default"].ccxtVersion = version;
|
|
197
197
|
const exchanges = {
|
|
198
198
|
'alpaca': alpaca["default"],
|
|
@@ -1161,6 +1161,7 @@ class Exchange {
|
|
|
1161
1161
|
}
|
|
1162
1162
|
async close() {
|
|
1163
1163
|
// test by running ts/src/pro/test/base/test.close.ts
|
|
1164
|
+
await this.sleep(0); // allow other futures to run
|
|
1164
1165
|
const clients = Object.values(this.clients || {});
|
|
1165
1166
|
const closedClients = [];
|
|
1166
1167
|
for (let i = 0; i < clients.length; i++) {
|
|
@@ -1199,6 +1200,7 @@ class Exchange {
|
|
|
1199
1200
|
}
|
|
1200
1201
|
client.reject(new errors.ExchangeError(this.id + ' nonce is behind the cache after ' + maxRetries.toString() + ' tries.'), messageHash);
|
|
1201
1202
|
delete this.clients[client.url];
|
|
1203
|
+
this.orderbooks[symbol] = this.orderBook(); // clear the orderbook and its cache - issue https://github.com/ccxt/ccxt/issues/26753
|
|
1202
1204
|
}
|
|
1203
1205
|
catch (e) {
|
|
1204
1206
|
client.reject(e, messageHash);
|
|
@@ -2210,6 +2212,9 @@ class Exchange {
|
|
|
2210
2212
|
async unWatchPositions(symbols = undefined, params = {}) {
|
|
2211
2213
|
throw new errors.NotSupported(this.id + ' unWatchPositions() is not supported yet');
|
|
2212
2214
|
}
|
|
2215
|
+
async unWatchTicker(symbol, params = {}) {
|
|
2216
|
+
throw new errors.NotSupported(this.id + ' unWatchTicker() is not supported yet');
|
|
2217
|
+
}
|
|
2213
2218
|
async fetchDepositAddresses(codes = undefined, params = {}) {
|
|
2214
2219
|
throw new errors.NotSupported(this.id + ' fetchDepositAddresses() is not supported yet');
|
|
2215
2220
|
}
|
|
@@ -2443,9 +2448,9 @@ class Exchange {
|
|
|
2443
2448
|
parseToNumeric(number) {
|
|
2444
2449
|
const stringVersion = this.numberToString(number); // this will convert 1.0 and 1 to "1" and 1.1 to "1.1"
|
|
2445
2450
|
// keep this in mind:
|
|
2446
|
-
// in JS:
|
|
2451
|
+
// in JS: 1 === 1.0 is true
|
|
2447
2452
|
// in Python: 1 == 1.0 is true
|
|
2448
|
-
// in PHP
|
|
2453
|
+
// in PHP: 1 == 1.0 is true, but 1 === 1.0 is false.
|
|
2449
2454
|
if (stringVersion.indexOf('.') >= 0) {
|
|
2450
2455
|
return parseFloat(stringVersion);
|
|
2451
2456
|
}
|
|
@@ -2960,6 +2965,26 @@ class Exchange {
|
|
|
2960
2965
|
this.codes = Object.keys(currenciesSortedByCode);
|
|
2961
2966
|
return this.markets;
|
|
2962
2967
|
}
|
|
2968
|
+
setMarketsFromExchange(sourceExchange) {
|
|
2969
|
+
// Validate that both exchanges are of the same type
|
|
2970
|
+
if (this.id !== sourceExchange.id) {
|
|
2971
|
+
throw new errors.ArgumentsRequired(this.id + ' shareMarkets() can only share markets with exchanges of the same type (got ' + sourceExchange['id'] + ')');
|
|
2972
|
+
}
|
|
2973
|
+
// Validate that source exchange has loaded markets
|
|
2974
|
+
if (!sourceExchange.markets) {
|
|
2975
|
+
throw new errors.ExchangeError('setMarketsFromExchange() source exchange must have loaded markets first. Can call by using loadMarkets function');
|
|
2976
|
+
}
|
|
2977
|
+
// Set all market-related data
|
|
2978
|
+
this.markets = sourceExchange.markets;
|
|
2979
|
+
this.markets_by_id = sourceExchange.markets_by_id;
|
|
2980
|
+
this.symbols = sourceExchange.symbols;
|
|
2981
|
+
this.ids = sourceExchange.ids;
|
|
2982
|
+
this.currencies = sourceExchange.currencies;
|
|
2983
|
+
this.baseCurrencies = sourceExchange.baseCurrencies;
|
|
2984
|
+
this.quoteCurrencies = sourceExchange.quoteCurrencies;
|
|
2985
|
+
this.codes = sourceExchange.codes;
|
|
2986
|
+
return this;
|
|
2987
|
+
}
|
|
2963
2988
|
getDescribeForExtendedWsExchange(currentRestInstance, parentRestInstance, wsBaseDescribe) {
|
|
2964
2989
|
const extendedRestDescribe = this.deepExtend(parentRestInstance.describe(), currentRestInstance.describe());
|
|
2965
2990
|
const superWithRestDescribe = this.deepExtend(extendedRestDescribe, wsBaseDescribe);
|
|
@@ -4238,17 +4263,30 @@ class Exchange {
|
|
|
4238
4263
|
}
|
|
4239
4264
|
return result;
|
|
4240
4265
|
}
|
|
4241
|
-
|
|
4266
|
+
parseTradesHelper(isWs, trades, market = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4242
4267
|
trades = this.toArray(trades);
|
|
4243
4268
|
let result = [];
|
|
4244
4269
|
for (let i = 0; i < trades.length; i++) {
|
|
4245
|
-
|
|
4270
|
+
let parsed = undefined;
|
|
4271
|
+
if (isWs) {
|
|
4272
|
+
parsed = this.parseWsTrade(trades[i], market);
|
|
4273
|
+
}
|
|
4274
|
+
else {
|
|
4275
|
+
parsed = this.parseTrade(trades[i], market);
|
|
4276
|
+
}
|
|
4277
|
+
const trade = this.extend(parsed, params);
|
|
4246
4278
|
result.push(trade);
|
|
4247
4279
|
}
|
|
4248
4280
|
result = this.sortBy2(result, 'timestamp', 'id');
|
|
4249
4281
|
const symbol = (market !== undefined) ? market['symbol'] : undefined;
|
|
4250
4282
|
return this.filterBySymbolSinceLimit(result, symbol, since, limit);
|
|
4251
4283
|
}
|
|
4284
|
+
parseTrades(trades, market = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4285
|
+
return this.parseTradesHelper(false, trades, market, since, limit, params);
|
|
4286
|
+
}
|
|
4287
|
+
parseWsTrades(trades, market = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4288
|
+
return this.parseTradesHelper(true, trades, market, since, limit, params);
|
|
4289
|
+
}
|
|
4252
4290
|
parseTransactions(transactions, currency = undefined, since = undefined, limit = undefined, params = {}) {
|
|
4253
4291
|
transactions = this.toArray(transactions);
|
|
4254
4292
|
let result = [];
|
|
@@ -4699,6 +4737,12 @@ class Exchange {
|
|
|
4699
4737
|
}
|
|
4700
4738
|
return result;
|
|
4701
4739
|
}
|
|
4740
|
+
marketOrNull(symbol) {
|
|
4741
|
+
if (symbol === undefined) {
|
|
4742
|
+
return undefined;
|
|
4743
|
+
}
|
|
4744
|
+
return this.market(symbol);
|
|
4745
|
+
}
|
|
4702
4746
|
checkRequiredCredentials(error = true) {
|
|
4703
4747
|
/**
|
|
4704
4748
|
* @ignore
|
|
@@ -6198,6 +6242,35 @@ class Exchange {
|
|
|
6198
6242
|
const symbol = (market === undefined) ? undefined : market['symbol'];
|
|
6199
6243
|
return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
|
|
6200
6244
|
}
|
|
6245
|
+
handleTriggerPricesAndParams(symbol, params, omitParams = true) {
|
|
6246
|
+
//
|
|
6247
|
+
const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
|
|
6248
|
+
let triggerPriceStr = undefined;
|
|
6249
|
+
const stopLossPrice = this.safeString(params, 'stopLossPrice');
|
|
6250
|
+
let stopLossPriceStr = undefined;
|
|
6251
|
+
const takeProfitPrice = this.safeString(params, 'takeProfitPrice');
|
|
6252
|
+
let takeProfitPriceStr = undefined;
|
|
6253
|
+
//
|
|
6254
|
+
if (triggerPrice !== undefined) {
|
|
6255
|
+
if (omitParams) {
|
|
6256
|
+
params = this.omit(params, ['triggerPrice', 'stopPrice']);
|
|
6257
|
+
}
|
|
6258
|
+
triggerPriceStr = this.priceToPrecision(symbol, parseFloat(triggerPrice));
|
|
6259
|
+
}
|
|
6260
|
+
if (stopLossPrice !== undefined) {
|
|
6261
|
+
if (omitParams) {
|
|
6262
|
+
params = this.omit(params, 'stopLossPrice');
|
|
6263
|
+
}
|
|
6264
|
+
stopLossPriceStr = this.priceToPrecision(symbol, parseFloat(stopLossPrice));
|
|
6265
|
+
}
|
|
6266
|
+
if (takeProfitPrice !== undefined) {
|
|
6267
|
+
if (omitParams) {
|
|
6268
|
+
params = this.omit(params, 'takeProfitPrice');
|
|
6269
|
+
}
|
|
6270
|
+
takeProfitPriceStr = this.priceToPrecision(symbol, parseFloat(takeProfitPrice));
|
|
6271
|
+
}
|
|
6272
|
+
return [triggerPriceStr, stopLossPriceStr, takeProfitPriceStr, params];
|
|
6273
|
+
}
|
|
6201
6274
|
handleTriggerDirectionAndParams(params, exchangeSpecificKey = undefined, allowEmpty = false) {
|
|
6202
6275
|
/**
|
|
6203
6276
|
* @ignore
|
|
@@ -7394,7 +7467,7 @@ class Exchange {
|
|
|
7394
7467
|
const clients = Object.values(this.clients);
|
|
7395
7468
|
for (let i = 0; i < clients.length; i++) {
|
|
7396
7469
|
const client = clients[i];
|
|
7397
|
-
const futures =
|
|
7470
|
+
const futures = client.futures;
|
|
7398
7471
|
if ((futures !== undefined) && ('fetchPositionsSnapshot' in futures)) {
|
|
7399
7472
|
delete futures['fetchPositionsSnapshot'];
|
|
7400
7473
|
}
|
|
@@ -24,10 +24,18 @@ const json = (data, params = undefined) => JSON.stringify(data), isJsonEncodedOb
|
|
|
24
24
|
function packb(req) {
|
|
25
25
|
return msgpack.serialize(req);
|
|
26
26
|
}
|
|
27
|
+
function base64ToBase64Url(base64, stripPadding = true) {
|
|
28
|
+
let base64url = base64.replace(/\+/g, "-").replace(/\//g, "_");
|
|
29
|
+
if (stripPadding) {
|
|
30
|
+
base64url = base64url.replace(/=+$/, "");
|
|
31
|
+
}
|
|
32
|
+
return base64url;
|
|
33
|
+
}
|
|
27
34
|
/* ------------------------------------------------------------------------ */
|
|
28
35
|
|
|
29
36
|
exports.base16ToBinary = base16ToBinary;
|
|
30
37
|
exports.base58ToBinary = base58ToBinary;
|
|
38
|
+
exports.base64ToBase64Url = base64ToBase64Url;
|
|
31
39
|
exports.base64ToBinary = base64ToBinary;
|
|
32
40
|
exports.base64ToString = base64ToString;
|
|
33
41
|
exports.binaryConcat = binaryConcat;
|
|
@@ -7,6 +7,7 @@ var index = require('../../static_dependencies/scure-base/index.js');
|
|
|
7
7
|
var encode = require('./encode.js');
|
|
8
8
|
var crypto = require('./crypto.js');
|
|
9
9
|
var p256 = require('../../static_dependencies/noble-curves/p256.js');
|
|
10
|
+
var ed25519 = require('../../static_dependencies/noble-curves/ed25519.js');
|
|
10
11
|
|
|
11
12
|
// ----------------------------------------------------------------------------
|
|
12
13
|
function rsa(request, secret, hash) {
|
|
@@ -28,7 +29,7 @@ function jwt(request, secret, hash, isRSA = false, opts = {}) {
|
|
|
28
29
|
}
|
|
29
30
|
const encodedHeader = encode.urlencodeBase64(JSON.stringify(header));
|
|
30
31
|
const encodedData = encode.urlencodeBase64(JSON.stringify(request));
|
|
31
|
-
|
|
32
|
+
let token = [encodedHeader, encodedData].join('.');
|
|
32
33
|
const algoType = alg.slice(0, 2);
|
|
33
34
|
let signature = undefined;
|
|
34
35
|
if (algoType === 'HS') {
|
|
@@ -43,8 +44,20 @@ function jwt(request, secret, hash, isRSA = false, opts = {}) {
|
|
|
43
44
|
const s = signedHash.s.padStart(64, '0');
|
|
44
45
|
signature = encode.urlencodeBase64(encode.base16ToBinary(r + s));
|
|
45
46
|
}
|
|
47
|
+
else if (algoType === 'ED') {
|
|
48
|
+
const base64str = crypto.eddsa(toHex(token), secret, ed25519.ed25519);
|
|
49
|
+
// we need urlencoded64 not base64
|
|
50
|
+
signature = encode.base64ToBase64Url(base64str);
|
|
51
|
+
}
|
|
46
52
|
return [token, signature].join('.');
|
|
47
53
|
}
|
|
54
|
+
function toHex(str) {
|
|
55
|
+
var result = '';
|
|
56
|
+
for (var i = 0; i < str.length; i++) {
|
|
57
|
+
result += str.charCodeAt(i).toString(16);
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
48
61
|
|
|
49
62
|
exports.jwt = jwt;
|
|
50
63
|
exports.rsa = rsa;
|
|
@@ -105,6 +105,7 @@ exports.truncate = number.truncate;
|
|
|
105
105
|
exports.truncate_to_string = number.truncate_to_string;
|
|
106
106
|
exports.base16ToBinary = encode.base16ToBinary;
|
|
107
107
|
exports.base58ToBinary = encode.base58ToBinary;
|
|
108
|
+
exports.base64ToBase64Url = encode.base64ToBase64Url;
|
|
108
109
|
exports.base64ToBinary = encode.base64ToBinary;
|
|
109
110
|
exports.base64ToString = encode.base64ToString;
|
|
110
111
|
exports.binaryConcat = encode.binaryConcat;
|
package/dist/cjs/src/binance.js
CHANGED
|
@@ -6611,19 +6611,13 @@ class binance extends binance$1["default"] {
|
|
|
6611
6611
|
}
|
|
6612
6612
|
}
|
|
6613
6613
|
if (quantityIsRequired) {
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6614
|
+
const marketAmountPrecision = this.safeString(market['precision'], 'amount');
|
|
6615
|
+
const isPrecisionAvailable = (marketAmountPrecision !== undefined);
|
|
6616
|
+
if (isPrecisionAvailable) {
|
|
6617
|
+
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
6617
6618
|
}
|
|
6618
6619
|
else {
|
|
6619
|
-
|
|
6620
|
-
const isPrecisionAvailable = (marketAmountPrecision !== undefined);
|
|
6621
|
-
if (isPrecisionAvailable) {
|
|
6622
|
-
request['quantity'] = this.amountToPrecision(symbol, amount);
|
|
6623
|
-
}
|
|
6624
|
-
else {
|
|
6625
|
-
request['quantity'] = this.parseToNumeric(amount); // some options don't have the precision available
|
|
6626
|
-
}
|
|
6620
|
+
request['quantity'] = this.parseToNumeric(amount); // some options don't have the precision available
|
|
6627
6621
|
}
|
|
6628
6622
|
}
|
|
6629
6623
|
if (priceIsRequired && !isPriceMatch) {
|
|
@@ -11409,11 +11403,14 @@ class binance extends binance$1["default"] {
|
|
|
11409
11403
|
* @returns {object} response from the exchange
|
|
11410
11404
|
*/
|
|
11411
11405
|
async setPositionMode(hedged, symbol = undefined, params = {}) {
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11406
|
+
let market = undefined;
|
|
11407
|
+
if (symbol !== undefined) {
|
|
11408
|
+
market = this.market(symbol);
|
|
11409
|
+
}
|
|
11410
|
+
let type = undefined;
|
|
11411
|
+
[type, params] = this.handleMarketTypeAndParams('setPositionMode', market, params);
|
|
11415
11412
|
let subType = undefined;
|
|
11416
|
-
[subType, params] = this.handleSubTypeAndParams('setPositionMode',
|
|
11413
|
+
[subType, params] = this.handleSubTypeAndParams('setPositionMode', market, params);
|
|
11417
11414
|
let isPortfolioMargin = undefined;
|
|
11418
11415
|
[isPortfolioMargin, params] = this.handleOptionAndParams2(params, 'setPositionMode', 'papi', 'portfolioMargin', false);
|
|
11419
11416
|
let dualSidePosition = undefined;
|
package/dist/cjs/src/bitget.js
CHANGED
|
@@ -7708,7 +7708,7 @@ class bitget extends bitget$1["default"] {
|
|
|
7708
7708
|
// "requestTime": 1700802995406,
|
|
7709
7709
|
// "data": [
|
|
7710
7710
|
// {
|
|
7711
|
-
// "userId": "
|
|
7711
|
+
// "userId": "7264631751",
|
|
7712
7712
|
// "symbol": "BTCUSDT",
|
|
7713
7713
|
// "orderId": "1098394344925597696",
|
|
7714
7714
|
// "tradeId": "1098394344974925824",
|
package/dist/cjs/src/bitvavo.js
CHANGED
|
@@ -1423,6 +1423,14 @@ class bitvavo extends bitvavo$1["default"] {
|
|
|
1423
1423
|
market = this.market(symbol);
|
|
1424
1424
|
request['market'] = market['id'];
|
|
1425
1425
|
}
|
|
1426
|
+
let operatorId = undefined;
|
|
1427
|
+
[operatorId, params] = this.handleOptionAndParams(params, 'cancelAllOrders', 'operatorId');
|
|
1428
|
+
if (operatorId !== undefined) {
|
|
1429
|
+
request['operatorId'] = this.parseToInt(operatorId);
|
|
1430
|
+
}
|
|
1431
|
+
else {
|
|
1432
|
+
throw new errors.ArgumentsRequired(this.id + ' canceAllOrders() requires an operatorId in params or options, eg: exchange.options[\'operatorId\'] = 1234567890');
|
|
1433
|
+
}
|
|
1426
1434
|
const response = await this.privateDeleteOrders(this.extend(request, params));
|
|
1427
1435
|
//
|
|
1428
1436
|
// [
|
package/dist/cjs/src/bybit.js
CHANGED
|
@@ -2996,17 +2996,31 @@ class bybit extends bybit$1["default"] {
|
|
|
2996
2996
|
// "tradeId": "0e94eaf5-b08e-5505-b43f-7f1f30b1ca80"
|
|
2997
2997
|
// }
|
|
2998
2998
|
//
|
|
2999
|
+
// watchMyTrades execution.fast
|
|
3000
|
+
//
|
|
3001
|
+
// {
|
|
3002
|
+
// "category": "linear",
|
|
3003
|
+
// "symbol": "ICPUSDT",
|
|
3004
|
+
// "execId": "3510f361-0add-5c7b-a2e7-9679810944fc",
|
|
3005
|
+
// "execPrice": "12.015",
|
|
3006
|
+
// "execQty": "3000",
|
|
3007
|
+
// "orderId": "443d63fa-b4c3-4297-b7b1-23bca88b04dc",
|
|
3008
|
+
// "isMaker": false,
|
|
3009
|
+
// "orderLinkId": "test-00001",
|
|
3010
|
+
// "side": "Sell",
|
|
3011
|
+
// "execTime": "1716800399334",
|
|
3012
|
+
// "seq": 34771365464
|
|
3013
|
+
// }
|
|
3014
|
+
//
|
|
2999
3015
|
const id = this.safeStringN(trade, ['execId', 'id', 'tradeId']);
|
|
3000
3016
|
const marketId = this.safeString(trade, 'symbol');
|
|
3001
3017
|
let marketType = ('createType' in trade) ? 'contract' : 'spot';
|
|
3002
|
-
if (market !== undefined) {
|
|
3003
|
-
marketType = market['type'];
|
|
3004
|
-
}
|
|
3005
3018
|
const category = this.safeString(trade, 'category');
|
|
3006
3019
|
if (category !== undefined) {
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3020
|
+
marketType = (category === 'spot') ? 'spot' : 'contract';
|
|
3021
|
+
}
|
|
3022
|
+
if (market !== undefined) {
|
|
3023
|
+
marketType = market['type'];
|
|
3010
3024
|
}
|
|
3011
3025
|
market = this.safeMarket(marketId, market, undefined, marketType);
|
|
3012
3026
|
const symbol = market['symbol'];
|
package/dist/cjs/src/coinbase.js
CHANGED
|
@@ -5014,8 +5014,9 @@ class coinbase extends coinbase$1["default"] {
|
|
|
5014
5014
|
}
|
|
5015
5015
|
return parsedPositions;
|
|
5016
5016
|
}
|
|
5017
|
-
createAuthToken(seconds, method = undefined, url = undefined) {
|
|
5018
|
-
//
|
|
5017
|
+
createAuthToken(seconds, method = undefined, url = undefined, useEddsa = false) {
|
|
5018
|
+
// v1 https://docs.cdp.coinbase.com/api-reference/authentication#php-2
|
|
5019
|
+
// v2 https://docs.cdp.coinbase.com/api-reference/v2/authentication
|
|
5019
5020
|
let uri = undefined;
|
|
5020
5021
|
if (url !== undefined) {
|
|
5021
5022
|
uri = method + ' ' + url.replace('https://', '');
|
|
@@ -5026,20 +5027,35 @@ class coinbase extends coinbase$1["default"] {
|
|
|
5026
5027
|
uri = uri.slice(0, quesPos);
|
|
5027
5028
|
}
|
|
5028
5029
|
}
|
|
5030
|
+
// eddsa {"sub":"d2efa49a-369c-43d7-a60e-ae26e28853c2","iss":"cdp","aud":["cdp_service"],"uris":["GET api.coinbase.com/api/v3/brokerage/transaction_summary"]}
|
|
5029
5031
|
const nonce = this.randomBytes(16);
|
|
5032
|
+
const aud = useEddsa ? 'cdp_service' : 'retail_rest_api_proxy';
|
|
5033
|
+
const iss = useEddsa ? 'cdp' : 'coinbase-cloud';
|
|
5030
5034
|
const request = {
|
|
5031
|
-
'aud': [
|
|
5032
|
-
'iss':
|
|
5035
|
+
'aud': [aud],
|
|
5036
|
+
'iss': iss,
|
|
5033
5037
|
'nbf': seconds,
|
|
5034
5038
|
'exp': seconds + 120,
|
|
5035
5039
|
'sub': this.apiKey,
|
|
5036
5040
|
'iat': seconds,
|
|
5037
5041
|
};
|
|
5038
5042
|
if (uri !== undefined) {
|
|
5039
|
-
|
|
5043
|
+
if (!useEddsa) {
|
|
5044
|
+
request['uri'] = uri;
|
|
5045
|
+
}
|
|
5046
|
+
else {
|
|
5047
|
+
request['uris'] = [uri];
|
|
5048
|
+
}
|
|
5049
|
+
}
|
|
5050
|
+
if (useEddsa) {
|
|
5051
|
+
const byteArray = this.base64ToBinary(this.secret);
|
|
5052
|
+
const seed = this.arraySlice(byteArray, 0, 32);
|
|
5053
|
+
return rsa.jwt(request, seed, sha256.sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'EdDSA' });
|
|
5054
|
+
}
|
|
5055
|
+
else {
|
|
5056
|
+
// ecdsa with p256
|
|
5057
|
+
return rsa.jwt(request, this.encode(this.secret), sha256.sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'ES256' });
|
|
5040
5058
|
}
|
|
5041
|
-
const token = rsa.jwt(request, this.encode(this.secret), sha256.sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'ES256' });
|
|
5042
|
-
return token;
|
|
5043
5059
|
}
|
|
5044
5060
|
nonce() {
|
|
5045
5061
|
return this.milliseconds() - this.options['timeDifference'];
|
|
@@ -5089,8 +5105,10 @@ class coinbase extends coinbase$1["default"] {
|
|
|
5089
5105
|
// v2: 'GET' require payload in the signature
|
|
5090
5106
|
// https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
|
|
5091
5107
|
const isCloudAPiKey = (this.apiKey.indexOf('organizations/') >= 0) || (this.secret.startsWith('-----BEGIN'));
|
|
5092
|
-
if
|
|
5093
|
-
|
|
5108
|
+
// using the size might be fragile, so we add an option to force v2 cloud api key if needed
|
|
5109
|
+
const isV2CloudAPiKey = this.secret.length === 88 || this.safeBool(this.options, 'v2CloudAPiKey', false) || this.secret.endsWith('=');
|
|
5110
|
+
if (isCloudAPiKey || isV2CloudAPiKey) {
|
|
5111
|
+
if (isCloudAPiKey && this.apiKey.startsWith('-----BEGIN')) {
|
|
5094
5112
|
throw new errors.ArgumentsRequired(this.id + ' apiKey should contain the name (eg: organizations/3b910e93....) and not the public key');
|
|
5095
5113
|
}
|
|
5096
5114
|
// // it may not work for v2
|
|
@@ -5111,7 +5129,7 @@ class coinbase extends coinbase$1["default"] {
|
|
|
5111
5129
|
// 'uri': uri,
|
|
5112
5130
|
// 'iat': seconds,
|
|
5113
5131
|
// };
|
|
5114
|
-
const token = this.createAuthToken(seconds, method, url);
|
|
5132
|
+
const token = this.createAuthToken(seconds, method, url, isV2CloudAPiKey);
|
|
5115
5133
|
// const token = jwt (request, this.encode (this.secret), sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'ES256' });
|
|
5116
5134
|
authorizationString = 'Bearer ' + token;
|
|
5117
5135
|
}
|
|
@@ -610,8 +610,8 @@ class coincatch extends coincatch$1["default"] {
|
|
|
610
610
|
for (let j = 0; j < networks.length; j++) {
|
|
611
611
|
const network = networks[j];
|
|
612
612
|
const networkId = this.safeString(network, 'chain');
|
|
613
|
-
const networkCode = this.
|
|
614
|
-
parsedNetworks[
|
|
613
|
+
const networkCode = this.networkIdToCode(networkId);
|
|
614
|
+
parsedNetworks[networkCode] = {
|
|
615
615
|
'id': networkId,
|
|
616
616
|
'network': networkCode,
|
|
617
617
|
'limits': {
|
|
@@ -2306,6 +2306,7 @@ class coincatch extends coincatch$1["default"] {
|
|
|
2306
2306
|
* @param {float} amount how much of you want to trade in units of the base currency
|
|
2307
2307
|
* @param {float} [price] the price that the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2308
2308
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2309
|
+
* @param {bool} [params.hedged] *swap markets only* must be set to true if position mode is hedged (default false)
|
|
2309
2310
|
* @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
|
|
2310
2311
|
* @param {float} [params.triggerPrice] the price that the order is to be triggered
|
|
2311
2312
|
* @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
|
|
@@ -2508,6 +2509,7 @@ class coincatch extends coincatch$1["default"] {
|
|
|
2508
2509
|
* @param {float} amount how much of you want to trade in units of the base currency
|
|
2509
2510
|
* @param {float} [price] the price that the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2510
2511
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2512
|
+
* @param {bool} [params.hedged] must be set to true if position mode is hedged (default false)
|
|
2511
2513
|
* @param {bool} [params.postOnly] *non-trigger orders only* if true, the order will only be posted to the order book and not executed immediately
|
|
2512
2514
|
* @param {bool} [params.reduceOnly] true or false whether the order is reduce only
|
|
2513
2515
|
* @param {string} [params.timeInForce] *non-trigger orders only* 'GTC', 'FOK', 'IOC' or 'PO'
|
|
@@ -2565,7 +2567,7 @@ class coincatch extends coincatch$1["default"] {
|
|
|
2565
2567
|
* @param {float} amount how much of you want to trade in units of the base currency
|
|
2566
2568
|
* @param {float} [price] the price that the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2567
2569
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
2568
|
-
* @param {bool} [params.hedged] default false
|
|
2570
|
+
* @param {bool} [params.hedged] must be set to true if position mode is hedged (default false)
|
|
2569
2571
|
* @param {bool} [params.postOnly] *non-trigger orders only* if true, the order will only be posted to the order book and not executed immediately
|
|
2570
2572
|
* @param {bool} [params.reduceOnly] true or false whether the order is reduce only
|
|
2571
2573
|
* @param {string} [params.timeInForce] *non-trigger orders only* 'GTC', 'FOK', 'IOC' or 'PO'
|
|
@@ -2604,31 +2606,42 @@ class coincatch extends coincatch$1["default"] {
|
|
|
2604
2606
|
}
|
|
2605
2607
|
if ((endpointType !== 'tpsl')) {
|
|
2606
2608
|
request['orderType'] = type;
|
|
2609
|
+
let sideIsExchangeSpecific = false;
|
|
2607
2610
|
let hedged = false;
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2611
|
+
if ((side === 'buy_single') || (side === 'sell_single') || (side === 'open_long') || (side === 'open_short') || (side === 'close_long') || (side === 'close_short')) {
|
|
2612
|
+
sideIsExchangeSpecific = true;
|
|
2613
|
+
if ((side !== 'buy_single') && (side !== 'sell_single')) {
|
|
2614
|
+
hedged = true;
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
if (!sideIsExchangeSpecific) {
|
|
2618
|
+
[hedged, params] = this.handleOptionAndParams(params, methodName, 'hedged', hedged);
|
|
2619
|
+
// hedged and non-hedged orders have different side values and reduceOnly handling
|
|
2620
|
+
const reduceOnly = this.safeBool(params, 'reduceOnly');
|
|
2621
|
+
if (hedged) {
|
|
2622
|
+
if ((reduceOnly !== undefined) && reduceOnly) {
|
|
2623
|
+
if (side === 'buy') {
|
|
2624
|
+
side = 'close_short';
|
|
2625
|
+
}
|
|
2626
|
+
else if (side === 'sell') {
|
|
2627
|
+
side = 'close_long';
|
|
2628
|
+
}
|
|
2616
2629
|
}
|
|
2617
|
-
else
|
|
2618
|
-
side
|
|
2630
|
+
else {
|
|
2631
|
+
if (side === 'buy') {
|
|
2632
|
+
side = 'open_long';
|
|
2633
|
+
}
|
|
2634
|
+
else if (side === 'sell') {
|
|
2635
|
+
side = 'open_short';
|
|
2636
|
+
}
|
|
2619
2637
|
}
|
|
2620
2638
|
}
|
|
2621
2639
|
else {
|
|
2622
|
-
|
|
2623
|
-
side = 'open_long';
|
|
2624
|
-
}
|
|
2625
|
-
else if (side === 'sell') {
|
|
2626
|
-
side = 'open_short';
|
|
2627
|
-
}
|
|
2640
|
+
side = side.toLowerCase() + '_single';
|
|
2628
2641
|
}
|
|
2629
2642
|
}
|
|
2630
|
-
|
|
2631
|
-
|
|
2643
|
+
if (hedged) {
|
|
2644
|
+
params = this.omit(params, 'reduceOnly');
|
|
2632
2645
|
}
|
|
2633
2646
|
request['side'] = side;
|
|
2634
2647
|
}
|
package/dist/cjs/src/delta.js
CHANGED
package/dist/cjs/src/gate.js
CHANGED
|
@@ -56,14 +56,24 @@ class gate extends gate$1["default"] {
|
|
|
56
56
|
},
|
|
57
57
|
'test': {
|
|
58
58
|
'public': {
|
|
59
|
-
'futures': 'https://
|
|
60
|
-
'delivery': 'https://
|
|
61
|
-
'options': 'https://
|
|
59
|
+
'futures': 'https://api-testnet.gateapi.io/api/v4',
|
|
60
|
+
'delivery': 'https://api-testnet.gateapi.io/api/v4',
|
|
61
|
+
'options': 'https://api-testnet.gateapi.io/api/v4',
|
|
62
|
+
'spot': 'https://api-testnet.gateapi.io/api/v4',
|
|
63
|
+
'wallet': 'https://api-testnet.gateapi.io/api/v4',
|
|
64
|
+
'margin': 'https://api-testnet.gateapi.io/api/v4',
|
|
65
|
+
'sub_accounts': 'https://api-testnet.gateapi.io/api/v4',
|
|
66
|
+
'account': 'https://api-testnet.gateapi.io/api/v4',
|
|
62
67
|
},
|
|
63
68
|
'private': {
|
|
64
|
-
'futures': 'https://
|
|
65
|
-
'delivery': 'https://
|
|
66
|
-
'options': 'https://
|
|
69
|
+
'futures': 'https://api-testnet.gateapi.io/api/v4',
|
|
70
|
+
'delivery': 'https://api-testnet.gateapi.io/api/v4',
|
|
71
|
+
'options': 'https://api-testnet.gateapi.io/api/v4',
|
|
72
|
+
'spot': 'https://api-testnet.gateapi.io/api/v4',
|
|
73
|
+
'wallet': 'https://api-testnet.gateapi.io/api/v4',
|
|
74
|
+
'margin': 'https://api-testnet.gateapi.io/api/v4',
|
|
75
|
+
'sub_accounts': 'https://api-testnet.gateapi.io/api/v4',
|
|
76
|
+
'account': 'https://api-testnet.gateapi.io/api/v4',
|
|
67
77
|
},
|
|
68
78
|
},
|
|
69
79
|
'referral': {
|
|
@@ -1230,16 +1240,15 @@ class gate extends gate$1["default"] {
|
|
|
1230
1240
|
await this.loadUnifiedStatus();
|
|
1231
1241
|
}
|
|
1232
1242
|
const rawPromises = [];
|
|
1233
|
-
const sandboxMode = this.safeBool(this.options, 'sandboxMode', false);
|
|
1234
1243
|
const fetchMarketsOptions = this.safeDict(this.options, 'fetchMarkets');
|
|
1235
1244
|
const types = this.safeList(fetchMarketsOptions, 'types', ['spot', 'swap', 'future', 'option']);
|
|
1236
1245
|
for (let i = 0; i < types.length; i++) {
|
|
1237
1246
|
const marketType = types[i];
|
|
1238
1247
|
if (marketType === 'spot') {
|
|
1239
|
-
if (!sandboxMode) {
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
}
|
|
1248
|
+
// if (!sandboxMode) {
|
|
1249
|
+
// gate doesn't have a sandbox for spot markets
|
|
1250
|
+
rawPromises.push(this.fetchSpotMarkets(params));
|
|
1251
|
+
// }
|
|
1243
1252
|
}
|
|
1244
1253
|
else if (marketType === 'swap') {
|
|
1245
1254
|
rawPromises.push(this.fetchSwapMarkets(params));
|
|
@@ -1370,7 +1379,10 @@ class gate extends gate$1["default"] {
|
|
|
1370
1379
|
}
|
|
1371
1380
|
async fetchSwapMarkets(params = {}) {
|
|
1372
1381
|
const result = [];
|
|
1373
|
-
|
|
1382
|
+
let swapSettlementCurrencies = this.getSettlementCurrencies('swap', 'fetchMarkets');
|
|
1383
|
+
if (this.options['sandboxMode']) {
|
|
1384
|
+
swapSettlementCurrencies = ['usdt']; // gate sandbox only has usdt-margined swaps
|
|
1385
|
+
}
|
|
1374
1386
|
for (let c = 0; c < swapSettlementCurrencies.length; c++) {
|
|
1375
1387
|
const settleId = swapSettlementCurrencies[c];
|
|
1376
1388
|
const request = {
|
|
@@ -1385,6 +1397,9 @@ class gate extends gate$1["default"] {
|
|
|
1385
1397
|
return result;
|
|
1386
1398
|
}
|
|
1387
1399
|
async fetchFutureMarkets(params = {}) {
|
|
1400
|
+
if (this.options['sandboxMode']) {
|
|
1401
|
+
return []; // right now sandbox does not have inverse swaps
|
|
1402
|
+
}
|
|
1388
1403
|
const result = [];
|
|
1389
1404
|
const futureSettlementCurrencies = this.getSettlementCurrencies('future', 'fetchMarkets');
|
|
1390
1405
|
for (let c = 0; c < futureSettlementCurrencies.length; c++) {
|
package/dist/cjs/src/gemini.js
CHANGED
|
@@ -693,8 +693,8 @@ class gemini extends gemini$1["default"] {
|
|
|
693
693
|
//
|
|
694
694
|
// [
|
|
695
695
|
// 'BTCUSD', // symbol
|
|
696
|
-
// 2, // priceTickDecimalPlaces
|
|
697
|
-
// 8, // quantityTickDecimalPlaces
|
|
696
|
+
// 2, // tick precision (priceTickDecimalPlaces)
|
|
697
|
+
// 8, // amount precision (quantityTickDecimalPlaces)
|
|
698
698
|
// '0.00001', // quantityMinimum
|
|
699
699
|
// 10, // quantityRoundDecimalPlaces
|
|
700
700
|
// true // minimumsAreInclusive
|
|
@@ -713,7 +713,7 @@ class gemini extends gemini$1["default"] {
|
|
|
713
713
|
// "wrap_enabled": false
|
|
714
714
|
// "product_type": "swap", // only in perps
|
|
715
715
|
// "contract_type": "linear", // only in perps
|
|
716
|
-
// "contract_price_currency": "GUSD"
|
|
716
|
+
// "contract_price_currency": "GUSD"
|
|
717
717
|
// }
|
|
718
718
|
//
|
|
719
719
|
let marketId = undefined;
|