ccxt 4.4.82 → 4.4.85
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 +5 -7
- package/dist/ccxt.browser.min.js +7 -7
- package/dist/cjs/ccxt.js +1 -9
- package/dist/cjs/src/apex.js +2 -1
- package/dist/cjs/src/base/Exchange.js +15 -2
- package/dist/cjs/src/bitget.js +1 -3
- package/dist/cjs/src/bitrue.js +14 -35
- package/dist/cjs/src/bitso.js +33 -0
- package/dist/cjs/src/bitstamp.js +33 -0
- package/dist/cjs/src/blofin.js +154 -13
- package/dist/cjs/src/btcbox.js +25 -5
- package/dist/cjs/src/bybit.js +16 -40
- package/dist/cjs/src/cex.js +2 -4
- package/dist/cjs/src/coinbase.js +56 -40
- package/dist/cjs/src/coinbaseexchange.js +142 -32
- package/dist/cjs/src/coincatch.js +14 -67
- package/dist/cjs/src/coinex.js +29 -32
- package/dist/cjs/src/coinlist.js +16 -15
- package/dist/cjs/src/coinmetro.js +22 -11
- package/dist/cjs/src/coinone.js +8 -10
- package/dist/cjs/src/coinsph.js +126 -1
- package/dist/cjs/src/cryptocom.js +111 -1
- package/dist/cjs/src/cryptomus.js +43 -89
- package/dist/cjs/src/delta.js +76 -36
- package/dist/cjs/src/derive.js +46 -10
- package/dist/cjs/src/ellipx.js +175 -79
- package/dist/cjs/src/gate.js +1 -1
- package/dist/cjs/src/gemini.js +3 -5
- package/dist/cjs/src/hitbtc.js +56 -69
- package/dist/cjs/src/hyperliquid.js +2 -2
- package/dist/cjs/src/kraken.js +29 -24
- package/dist/cjs/src/kucoinfutures.js +6 -0
- package/dist/cjs/src/lbank.js +1 -1
- package/dist/cjs/src/paradex.js +119 -3
- package/dist/cjs/src/pro/binance.js +31 -33
- package/dist/cjs/src/pro/bithumb.js +5 -3
- package/dist/cjs/src/pro/kraken.js +289 -79
- package/dist/cjs/src/pro/mexc.js +302 -8
- package/dist/cjs/src/pro/poloniex.js +6 -2
- package/examples/js/cli.js +127 -13
- package/js/ccxt.d.ts +2 -11
- package/js/ccxt.js +2 -8
- package/js/src/abstract/blofin.d.ts +8 -0
- package/js/src/abstract/btcbox.d.ts +1 -0
- package/js/src/apex.js +2 -1
- package/js/src/base/Exchange.d.ts +15 -1
- package/js/src/base/Exchange.js +15 -2
- package/js/src/base/types.d.ts +3 -0
- package/js/src/bitget.js +1 -3
- package/js/src/bitrue.js +14 -35
- package/js/src/bitso.js +33 -0
- package/js/src/bitstamp.js +33 -0
- package/js/src/blofin.d.ts +42 -2
- package/js/src/blofin.js +154 -13
- package/js/src/btcbox.js +25 -5
- package/js/src/bybit.js +16 -40
- package/js/src/cex.js +2 -4
- package/js/src/coinbase.js +56 -40
- package/js/src/coinbaseexchange.js +142 -32
- package/js/src/coincatch.js +14 -67
- package/js/src/coinex.js +28 -29
- package/js/src/coinlist.js +16 -15
- package/js/src/coinmetro.js +22 -11
- package/js/src/coinone.js +8 -10
- package/js/src/coinsph.d.ts +10 -1
- package/js/src/coinsph.js +126 -1
- package/js/src/cryptocom.d.ts +10 -1
- package/js/src/cryptocom.js +111 -1
- package/js/src/cryptomus.js +43 -89
- package/js/src/delta.js +76 -36
- package/js/src/derive.js +46 -10
- package/js/src/ellipx.d.ts +2 -3
- package/js/src/ellipx.js +175 -80
- package/js/src/gate.js +1 -1
- package/js/src/gemini.js +3 -5
- package/js/src/hitbtc.js +56 -69
- package/js/src/hyperliquid.js +2 -2
- package/js/src/kraken.js +29 -24
- package/js/src/kucoinfutures.d.ts +1 -0
- package/js/src/kucoinfutures.js +6 -0
- package/js/src/lbank.js +1 -1
- package/js/src/paradex.d.ts +12 -1
- package/js/src/paradex.js +119 -3
- package/js/src/pro/binance.d.ts +26 -26
- package/js/src/pro/binance.js +31 -33
- package/js/src/pro/bithumb.js +5 -3
- package/js/src/pro/kraken.d.ts +7 -6
- package/js/src/pro/kraken.js +290 -80
- package/js/src/pro/mexc.d.ts +58 -0
- package/js/src/pro/mexc.js +302 -8
- package/js/src/pro/poloniex.d.ts +1 -1
- package/js/src/pro/poloniex.js +6 -2
- package/package.json +1 -1
- package/js/src/abstract/bl3p.d.ts +0 -22
- package/js/src/abstract/bl3p.js +0 -11
- package/js/src/abstract/idex.d.ts +0 -29
- package/js/src/abstract/idex.js +0 -11
- package/js/src/bl3p.d.ts +0 -116
- package/js/src/bl3p.js +0 -552
- package/js/src/idex.d.ts +0 -312
- package/js/src/idex.js +0 -1961
- package/js/src/pro/idex.d.ts +0 -81
- package/js/src/pro/idex.js +0 -720
package/js/src/idex.js
DELETED
|
@@ -1,1961 +0,0 @@
|
|
|
1
|
-
// ----------------------------------------------------------------------------
|
|
2
|
-
|
|
3
|
-
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
|
4
|
-
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
|
5
|
-
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
|
6
|
-
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
import Exchange from './abstract/idex.js';
|
|
9
|
-
import { TICK_SIZE, PAD_WITH_ZERO, ROUND, TRUNCATE } from './base/functions/number.js';
|
|
10
|
-
import { InvalidOrder, InsufficientFunds, ExchangeError, ExchangeNotAvailable, DDoSProtection, BadRequest, NotSupported, InvalidAddress, AuthenticationError } from './base/errors.js';
|
|
11
|
-
import { Precise } from './base/Precise.js';
|
|
12
|
-
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
|
|
13
|
-
import { keccak_256 as keccak } from './static_dependencies/noble-hashes/sha3.js';
|
|
14
|
-
import { secp256k1 } from './static_dependencies/noble-curves/secp256k1.js';
|
|
15
|
-
import { ecdsa } from './base/functions/crypto.js';
|
|
16
|
-
// ---------------------------------------------------------------------------
|
|
17
|
-
/**
|
|
18
|
-
* @class idex
|
|
19
|
-
* @augments Exchange
|
|
20
|
-
*/
|
|
21
|
-
export default class idex extends Exchange {
|
|
22
|
-
describe() {
|
|
23
|
-
return this.deepExtend(super.describe(), {
|
|
24
|
-
'id': 'idex',
|
|
25
|
-
'name': 'IDEX',
|
|
26
|
-
'countries': ['US'],
|
|
27
|
-
'rateLimit': 1000,
|
|
28
|
-
'version': 'v3',
|
|
29
|
-
'pro': true,
|
|
30
|
-
'dex': true,
|
|
31
|
-
'certified': false,
|
|
32
|
-
'requiresWeb3': true,
|
|
33
|
-
'has': {
|
|
34
|
-
'CORS': undefined,
|
|
35
|
-
'spot': true,
|
|
36
|
-
'margin': false,
|
|
37
|
-
'swap': false,
|
|
38
|
-
'future': false,
|
|
39
|
-
'option': false,
|
|
40
|
-
'addMargin': false,
|
|
41
|
-
'cancelAllOrders': true,
|
|
42
|
-
'cancelOrder': true,
|
|
43
|
-
'cancelOrders': false,
|
|
44
|
-
'closeAllPositions': false,
|
|
45
|
-
'closePosition': false,
|
|
46
|
-
'createDepositAddress': false,
|
|
47
|
-
'createOrder': true,
|
|
48
|
-
'createReduceOnlyOrder': false,
|
|
49
|
-
'createStopLimitOrder': true,
|
|
50
|
-
'createStopMarketOrder': true,
|
|
51
|
-
'createStopOrder': true,
|
|
52
|
-
'fetchBalance': true,
|
|
53
|
-
'fetchBorrowRateHistories': false,
|
|
54
|
-
'fetchBorrowRateHistory': false,
|
|
55
|
-
'fetchClosedOrders': true,
|
|
56
|
-
'fetchCrossBorrowRate': false,
|
|
57
|
-
'fetchCrossBorrowRates': false,
|
|
58
|
-
'fetchCurrencies': true,
|
|
59
|
-
'fetchDeposit': true,
|
|
60
|
-
'fetchDepositAddress': true,
|
|
61
|
-
'fetchDepositAddresses': false,
|
|
62
|
-
'fetchDepositAddressesByNetwork': false,
|
|
63
|
-
'fetchDeposits': true,
|
|
64
|
-
'fetchFundingHistory': false,
|
|
65
|
-
'fetchFundingRate': false,
|
|
66
|
-
'fetchFundingRateHistory': false,
|
|
67
|
-
'fetchFundingRates': false,
|
|
68
|
-
'fetchIndexOHLCV': false,
|
|
69
|
-
'fetchIsolatedBorrowRate': false,
|
|
70
|
-
'fetchIsolatedBorrowRates': false,
|
|
71
|
-
'fetchLeverage': false,
|
|
72
|
-
'fetchLeverageTiers': false,
|
|
73
|
-
'fetchMarginMode': false,
|
|
74
|
-
'fetchMarkets': true,
|
|
75
|
-
'fetchMarkOHLCV': false,
|
|
76
|
-
'fetchMyTrades': true,
|
|
77
|
-
'fetchOHLCV': true,
|
|
78
|
-
'fetchOpenInterestHistory': false,
|
|
79
|
-
'fetchOpenOrders': true,
|
|
80
|
-
'fetchOrder': true,
|
|
81
|
-
'fetchOrderBook': true,
|
|
82
|
-
'fetchOrders': false,
|
|
83
|
-
'fetchPosition': false,
|
|
84
|
-
'fetchPositionHistory': false,
|
|
85
|
-
'fetchPositionMode': false,
|
|
86
|
-
'fetchPositions': false,
|
|
87
|
-
'fetchPositionsForSymbol': false,
|
|
88
|
-
'fetchPositionsHistory': false,
|
|
89
|
-
'fetchPositionsRisk': false,
|
|
90
|
-
'fetchPremiumIndexOHLCV': false,
|
|
91
|
-
'fetchStatus': true,
|
|
92
|
-
'fetchTicker': true,
|
|
93
|
-
'fetchTickers': true,
|
|
94
|
-
'fetchTime': true,
|
|
95
|
-
'fetchTrades': true,
|
|
96
|
-
'fetchTradingFee': false,
|
|
97
|
-
'fetchTradingFees': true,
|
|
98
|
-
'fetchTransactions': false,
|
|
99
|
-
'fetchWithdrawal': true,
|
|
100
|
-
'fetchWithdrawals': true,
|
|
101
|
-
'reduceMargin': false,
|
|
102
|
-
'sandbox': true,
|
|
103
|
-
'setLeverage': false,
|
|
104
|
-
'setMarginMode': false,
|
|
105
|
-
'setPositionMode': false,
|
|
106
|
-
'transfer': false,
|
|
107
|
-
'withdraw': true,
|
|
108
|
-
},
|
|
109
|
-
'timeframes': {
|
|
110
|
-
'1m': '1m',
|
|
111
|
-
'5m': '5m',
|
|
112
|
-
'15m': '15m',
|
|
113
|
-
'30m': '30m',
|
|
114
|
-
'1h': '1h',
|
|
115
|
-
'6h': '6h',
|
|
116
|
-
'1d': '1d',
|
|
117
|
-
},
|
|
118
|
-
'urls': {
|
|
119
|
-
'test': {
|
|
120
|
-
'MATIC': 'https://api-sandbox-matic.idex.io',
|
|
121
|
-
},
|
|
122
|
-
'logo': 'https://user-images.githubusercontent.com/51840849/94481303-2f222100-01e0-11eb-97dd-bc14c5943a86.jpg',
|
|
123
|
-
'api': {
|
|
124
|
-
'MATIC': 'https://api-matic.idex.io',
|
|
125
|
-
},
|
|
126
|
-
'www': 'https://idex.io',
|
|
127
|
-
'doc': [
|
|
128
|
-
'https://api-docs-v3.idex.io/',
|
|
129
|
-
],
|
|
130
|
-
},
|
|
131
|
-
'api': {
|
|
132
|
-
'public': {
|
|
133
|
-
'get': {
|
|
134
|
-
'ping': 1,
|
|
135
|
-
'time': 1,
|
|
136
|
-
'exchange': 1,
|
|
137
|
-
'assets': 1,
|
|
138
|
-
'markets': 1,
|
|
139
|
-
'tickers': 1,
|
|
140
|
-
'candles': 1,
|
|
141
|
-
'trades': 1,
|
|
142
|
-
'orderbook': 1,
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
'private': {
|
|
146
|
-
'get': {
|
|
147
|
-
'user': 1,
|
|
148
|
-
'wallets': 1,
|
|
149
|
-
'balances': 1,
|
|
150
|
-
'orders': 0.1,
|
|
151
|
-
'fills': 0.1,
|
|
152
|
-
'deposits': 1,
|
|
153
|
-
'withdrawals': 1,
|
|
154
|
-
'wsToken': 1,
|
|
155
|
-
},
|
|
156
|
-
'post': {
|
|
157
|
-
'wallets': 1,
|
|
158
|
-
'orders': 0.1,
|
|
159
|
-
'orders/test': 0.1,
|
|
160
|
-
'withdrawals': 1,
|
|
161
|
-
},
|
|
162
|
-
'delete': {
|
|
163
|
-
'orders': 0.1,
|
|
164
|
-
},
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
'options': {
|
|
168
|
-
'defaultTimeInForce': 'gtc',
|
|
169
|
-
'defaultSelfTradePrevention': 'cn',
|
|
170
|
-
'network': 'MATIC',
|
|
171
|
-
},
|
|
172
|
-
'features': {
|
|
173
|
-
'spot': {
|
|
174
|
-
'sandbox': false,
|
|
175
|
-
'createOrder': {
|
|
176
|
-
'marginMode': false,
|
|
177
|
-
'triggerPrice': true,
|
|
178
|
-
// todo: revise
|
|
179
|
-
'triggerPriceType': {
|
|
180
|
-
'last': true,
|
|
181
|
-
'mark': true,
|
|
182
|
-
'index': true,
|
|
183
|
-
},
|
|
184
|
-
'triggerDirection': false,
|
|
185
|
-
'stopLossPrice': false,
|
|
186
|
-
'takeProfitPrice': false,
|
|
187
|
-
'attachedStopLossTakeProfit': undefined,
|
|
188
|
-
'timeInForce': {
|
|
189
|
-
'IOC': true,
|
|
190
|
-
'FOK': true,
|
|
191
|
-
'PO': true,
|
|
192
|
-
'GTD': false,
|
|
193
|
-
},
|
|
194
|
-
'hedged': false,
|
|
195
|
-
'selfTradePrevention': true,
|
|
196
|
-
'trailing': false,
|
|
197
|
-
'leverage': false,
|
|
198
|
-
'marketBuyByCost': false,
|
|
199
|
-
'marketBuyRequiresPrice': false,
|
|
200
|
-
'iceberg': false,
|
|
201
|
-
},
|
|
202
|
-
'createOrders': undefined,
|
|
203
|
-
'fetchMyTrades': {
|
|
204
|
-
'marginMode': false,
|
|
205
|
-
'limit': 1000,
|
|
206
|
-
'daysBack': 100000,
|
|
207
|
-
'untilDays': 100000,
|
|
208
|
-
'symbolRequired': false,
|
|
209
|
-
},
|
|
210
|
-
'fetchOrder': {
|
|
211
|
-
'marginMode': false,
|
|
212
|
-
'trigger': false,
|
|
213
|
-
'trailing': false,
|
|
214
|
-
'symbolRequired': false,
|
|
215
|
-
},
|
|
216
|
-
'fetchOpenOrders': {
|
|
217
|
-
'marginMode': false,
|
|
218
|
-
'limit': 1000,
|
|
219
|
-
'trigger': false,
|
|
220
|
-
'trailing': false,
|
|
221
|
-
'symbolRequired': false,
|
|
222
|
-
},
|
|
223
|
-
'fetchOrders': undefined,
|
|
224
|
-
'fetchClosedOrders': {
|
|
225
|
-
'marginMode': false,
|
|
226
|
-
'limit': 1000,
|
|
227
|
-
'daysBack': 1000000,
|
|
228
|
-
'daysBackCanceled': 1,
|
|
229
|
-
'untilDays': 1000000,
|
|
230
|
-
'trigger': false,
|
|
231
|
-
'trailing': false,
|
|
232
|
-
'symbolRequired': false,
|
|
233
|
-
},
|
|
234
|
-
'fetchOHLCV': {
|
|
235
|
-
'limit': 1000,
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
'swap': {
|
|
239
|
-
'linear': undefined,
|
|
240
|
-
'inverse': undefined,
|
|
241
|
-
},
|
|
242
|
-
'future': {
|
|
243
|
-
'linear': undefined,
|
|
244
|
-
'inverse': undefined,
|
|
245
|
-
},
|
|
246
|
-
},
|
|
247
|
-
'exceptions': {
|
|
248
|
-
'exact': {
|
|
249
|
-
'INVALID_ORDER_QUANTITY': InvalidOrder,
|
|
250
|
-
'INSUFFICIENT_FUNDS': InsufficientFunds,
|
|
251
|
-
'SERVICE_UNAVAILABLE': ExchangeNotAvailable,
|
|
252
|
-
'EXCEEDED_RATE_LIMIT': DDoSProtection,
|
|
253
|
-
'INVALID_PARAMETER': BadRequest,
|
|
254
|
-
'WALLET_NOT_ASSOCIATED': InvalidAddress,
|
|
255
|
-
'INVALID_WALLET_SIGNATURE': AuthenticationError,
|
|
256
|
-
},
|
|
257
|
-
},
|
|
258
|
-
'requiredCredentials': {
|
|
259
|
-
'walletAddress': true,
|
|
260
|
-
'privateKey': true,
|
|
261
|
-
'apiKey': true,
|
|
262
|
-
'secret': true,
|
|
263
|
-
},
|
|
264
|
-
'precisionMode': TICK_SIZE,
|
|
265
|
-
'paddingMode': PAD_WITH_ZERO,
|
|
266
|
-
'commonCurrencies': {},
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
priceToPrecision(symbol, price) {
|
|
270
|
-
//
|
|
271
|
-
// we override priceToPrecision to fix the following issue
|
|
272
|
-
// https://github.com/ccxt/ccxt/issues/13367
|
|
273
|
-
// {"code":"INVALID_PARAMETER","message":"invalid value provided for request parameter \"price\": all quantities and prices must be below 100 billion, above 0, need to be provided as strings, and always require 4 decimals ending with 4 zeroes"}
|
|
274
|
-
//
|
|
275
|
-
const market = this.market(symbol);
|
|
276
|
-
price = this.decimalToPrecision(price, ROUND, market['precision']['price'], this.precisionMode);
|
|
277
|
-
return this.decimalToPrecision(price, TRUNCATE, market['precision']['quote'], TICK_SIZE, PAD_WITH_ZERO);
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* @method
|
|
281
|
-
* @name idex#fetchMarkets
|
|
282
|
-
* @description retrieves data on all markets for idex
|
|
283
|
-
* @see https://api-docs-v3.idex.io/#get-markets
|
|
284
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
285
|
-
* @returns {object[]} an array of objects representing market data
|
|
286
|
-
*/
|
|
287
|
-
async fetchMarkets(params = {}) {
|
|
288
|
-
const response = await this.publicGetMarkets(params);
|
|
289
|
-
//
|
|
290
|
-
// [
|
|
291
|
-
// {
|
|
292
|
-
// "market": "ETH-USDC",
|
|
293
|
-
// "type": "hybrid",
|
|
294
|
-
// "status": "activeHybrid",
|
|
295
|
-
// "baseAsset": "ETH",
|
|
296
|
-
// "baseAssetPrecision": "8",
|
|
297
|
-
// "quoteAsset": "USDC",
|
|
298
|
-
// "quoteAssetPrecision": "8",
|
|
299
|
-
// "makerFeeRate": "0.0000",
|
|
300
|
-
// "takerFeeRate": "0.2500",
|
|
301
|
-
// "takerIdexFeeRate": "0.0500",
|
|
302
|
-
// "takerLiquidityProviderFeeRate": "0.2000",
|
|
303
|
-
// "tickSize": "0.01000000"
|
|
304
|
-
// },
|
|
305
|
-
// ]
|
|
306
|
-
//
|
|
307
|
-
const response2 = await this.publicGetExchange();
|
|
308
|
-
//
|
|
309
|
-
// {
|
|
310
|
-
// "timeZone": "UTC",
|
|
311
|
-
// "serverTime": "1654460599952",
|
|
312
|
-
// "maticDepositContractAddress": "0x3253a7e75539edaeb1db608ce6ef9aa1ac9126b6",
|
|
313
|
-
// "maticCustodyContractAddress": "0x3bcc4eca0a40358558ca8d1bcd2d1dbde63eb468",
|
|
314
|
-
// "maticUsdPrice": "0.60",
|
|
315
|
-
// "gasPrice": "180",
|
|
316
|
-
// "volume24hUsd": "10015814.46",
|
|
317
|
-
// "totalVolumeUsd": "1589273533.28",
|
|
318
|
-
// "totalTrades": "1534904",
|
|
319
|
-
// "totalValueLockedUsd": "12041929.44",
|
|
320
|
-
// "idexStakingValueLockedUsd": "20133816.98",
|
|
321
|
-
// "idexTokenAddress": "0x9Cb74C8032b007466865f060ad2c46145d45553D",
|
|
322
|
-
// "idexUsdPrice": "0.07",
|
|
323
|
-
// "idexMarketCapUsd": "48012346.00",
|
|
324
|
-
// "makerFeeRate": "0.0000",
|
|
325
|
-
// "takerFeeRate": "0.0025",
|
|
326
|
-
// "takerIdexFeeRate": "0.0005",
|
|
327
|
-
// "takerLiquidityProviderFeeRate": "0.0020",
|
|
328
|
-
// "makerTradeMinimum": "10.00000000",
|
|
329
|
-
// "takerTradeMinimum": "1.00000000",
|
|
330
|
-
// "withdrawMinimum": "0.50000000",
|
|
331
|
-
// "liquidityAdditionMinimum": "0.50000000",
|
|
332
|
-
// "liquidityRemovalMinimum": "0.40000000",
|
|
333
|
-
// "blockConfirmationDelay": "64"
|
|
334
|
-
// }
|
|
335
|
-
//
|
|
336
|
-
const maker = this.safeNumber(response2, 'makerFeeRate');
|
|
337
|
-
const taker = this.safeNumber(response2, 'takerFeeRate');
|
|
338
|
-
const makerMin = this.safeString(response2, 'makerTradeMinimum');
|
|
339
|
-
const takerMin = this.safeString(response2, 'takerTradeMinimum');
|
|
340
|
-
const minCostETH = this.parseNumber(Precise.stringMin(makerMin, takerMin));
|
|
341
|
-
const result = [];
|
|
342
|
-
for (let i = 0; i < response.length; i++) {
|
|
343
|
-
const entry = response[i];
|
|
344
|
-
const marketId = this.safeString(entry, 'market');
|
|
345
|
-
const baseId = this.safeString(entry, 'baseAsset');
|
|
346
|
-
const quoteId = this.safeString(entry, 'quoteAsset');
|
|
347
|
-
const base = this.safeCurrencyCode(baseId);
|
|
348
|
-
const quote = this.safeCurrencyCode(quoteId);
|
|
349
|
-
const basePrecision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'baseAssetPrecision')));
|
|
350
|
-
const quotePrecision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'quoteAssetPrecision')));
|
|
351
|
-
const status = this.safeString(entry, 'status');
|
|
352
|
-
let minCost = undefined;
|
|
353
|
-
if (quote === 'ETH') {
|
|
354
|
-
minCost = minCostETH;
|
|
355
|
-
}
|
|
356
|
-
result.push({
|
|
357
|
-
'id': marketId,
|
|
358
|
-
'symbol': base + '/' + quote,
|
|
359
|
-
'base': base,
|
|
360
|
-
'quote': quote,
|
|
361
|
-
'settle': undefined,
|
|
362
|
-
'baseId': baseId,
|
|
363
|
-
'quoteId': quoteId,
|
|
364
|
-
'settleId': undefined,
|
|
365
|
-
'type': 'spot',
|
|
366
|
-
'spot': true,
|
|
367
|
-
'margin': false,
|
|
368
|
-
'swap': false,
|
|
369
|
-
'future': false,
|
|
370
|
-
'option': false,
|
|
371
|
-
'active': (status !== 'inactive'),
|
|
372
|
-
'contract': false,
|
|
373
|
-
'linear': undefined,
|
|
374
|
-
'inverse': undefined,
|
|
375
|
-
'taker': taker,
|
|
376
|
-
'maker': maker,
|
|
377
|
-
'contractSize': undefined,
|
|
378
|
-
'expiry': undefined,
|
|
379
|
-
'expiryDatetime': undefined,
|
|
380
|
-
'strike': undefined,
|
|
381
|
-
'optionType': undefined,
|
|
382
|
-
'precision': {
|
|
383
|
-
'amount': basePrecision,
|
|
384
|
-
'price': this.safeNumber(entry, 'tickSize'),
|
|
385
|
-
'base': basePrecision,
|
|
386
|
-
'quote': quotePrecision,
|
|
387
|
-
},
|
|
388
|
-
'limits': {
|
|
389
|
-
'leverage': {
|
|
390
|
-
'min': undefined,
|
|
391
|
-
'max': undefined,
|
|
392
|
-
},
|
|
393
|
-
'amount': {
|
|
394
|
-
'min': basePrecision,
|
|
395
|
-
'max': undefined,
|
|
396
|
-
},
|
|
397
|
-
'price': {
|
|
398
|
-
'min': quotePrecision,
|
|
399
|
-
'max': undefined,
|
|
400
|
-
},
|
|
401
|
-
'cost': {
|
|
402
|
-
'min': minCost,
|
|
403
|
-
'max': undefined,
|
|
404
|
-
},
|
|
405
|
-
},
|
|
406
|
-
'created': undefined,
|
|
407
|
-
'info': entry,
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
return result;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* @method
|
|
414
|
-
* @name idex#fetchTicker
|
|
415
|
-
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
416
|
-
* @see https://api-docs-v3.idex.io/#get-tickers
|
|
417
|
-
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
|
418
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
419
|
-
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
420
|
-
*/
|
|
421
|
-
async fetchTicker(symbol, params = {}) {
|
|
422
|
-
await this.loadMarkets();
|
|
423
|
-
const market = this.market(symbol);
|
|
424
|
-
const request = {
|
|
425
|
-
'market': market['id'],
|
|
426
|
-
};
|
|
427
|
-
// [
|
|
428
|
-
// {
|
|
429
|
-
// "market": "DIL-ETH",
|
|
430
|
-
// "time": 1598367493008,
|
|
431
|
-
// "open": "0.09695361",
|
|
432
|
-
// "high": "0.10245881",
|
|
433
|
-
// "low": "0.09572507",
|
|
434
|
-
// "close": "0.09917079",
|
|
435
|
-
// "closeQuantity": "0.71320950",
|
|
436
|
-
// "baseVolume": "309.17380612",
|
|
437
|
-
// "quoteVolume": "30.57633981",
|
|
438
|
-
// "percentChange": "2.28",
|
|
439
|
-
// "numTrades": 205,
|
|
440
|
-
// "ask": "0.09910476",
|
|
441
|
-
// "bid": "0.09688340",
|
|
442
|
-
// "sequence": 3902
|
|
443
|
-
// }
|
|
444
|
-
// ]
|
|
445
|
-
const response = await this.publicGetTickers(this.extend(request, params));
|
|
446
|
-
const ticker = this.safeDict(response, 0);
|
|
447
|
-
return this.parseTicker(ticker, market);
|
|
448
|
-
}
|
|
449
|
-
/**
|
|
450
|
-
* @method
|
|
451
|
-
* @name idex#fetchTickers
|
|
452
|
-
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
453
|
-
* @see https://api-docs-v3.idex.io/#get-tickers
|
|
454
|
-
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
455
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
456
|
-
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
457
|
-
*/
|
|
458
|
-
async fetchTickers(symbols = undefined, params = {}) {
|
|
459
|
-
await this.loadMarkets();
|
|
460
|
-
// [
|
|
461
|
-
// {
|
|
462
|
-
// "market": "DIL-ETH",
|
|
463
|
-
// "time": 1598367493008,
|
|
464
|
-
// "open": "0.09695361",
|
|
465
|
-
// "high": "0.10245881",
|
|
466
|
-
// "low": "0.09572507",
|
|
467
|
-
// "close": "0.09917079",
|
|
468
|
-
// "closeQuantity": "0.71320950",
|
|
469
|
-
// "baseVolume": "309.17380612",
|
|
470
|
-
// "quoteVolume": "30.57633981",
|
|
471
|
-
// "percentChange": "2.28",
|
|
472
|
-
// "numTrades": 205,
|
|
473
|
-
// "ask": "0.09910476",
|
|
474
|
-
// "bid": "0.09688340",
|
|
475
|
-
// "sequence": 3902
|
|
476
|
-
// }, ...
|
|
477
|
-
// ]
|
|
478
|
-
const response = await this.publicGetTickers(params);
|
|
479
|
-
return this.parseTickers(response, symbols);
|
|
480
|
-
}
|
|
481
|
-
parseTicker(ticker, market = undefined) {
|
|
482
|
-
// {
|
|
483
|
-
// "market": "DIL-ETH",
|
|
484
|
-
// "time": 1598367493008,
|
|
485
|
-
// "open": "0.09695361",
|
|
486
|
-
// "high": "0.10245881",
|
|
487
|
-
// "low": "0.09572507",
|
|
488
|
-
// "close": "0.09917079",
|
|
489
|
-
// "closeQuantity": "0.71320950",
|
|
490
|
-
// "baseVolume": "309.17380612",
|
|
491
|
-
// "quoteVolume": "30.57633981",
|
|
492
|
-
// "percentChange": "2.28",
|
|
493
|
-
// "numTrades": 205,
|
|
494
|
-
// "ask": "0.09910476",
|
|
495
|
-
// "bid": "0.09688340",
|
|
496
|
-
// "sequence": 3902
|
|
497
|
-
// }
|
|
498
|
-
const marketId = this.safeString(ticker, 'market');
|
|
499
|
-
market = this.safeMarket(marketId, market, '-');
|
|
500
|
-
const symbol = market['symbol'];
|
|
501
|
-
const timestamp = this.safeInteger(ticker, 'time');
|
|
502
|
-
const close = this.safeString(ticker, 'close');
|
|
503
|
-
return this.safeTicker({
|
|
504
|
-
'symbol': symbol,
|
|
505
|
-
'timestamp': timestamp,
|
|
506
|
-
'datetime': this.iso8601(timestamp),
|
|
507
|
-
'high': this.safeString(ticker, 'high'),
|
|
508
|
-
'low': this.safeString(ticker, 'low'),
|
|
509
|
-
'bid': this.safeString(ticker, 'bid'),
|
|
510
|
-
'bidVolume': undefined,
|
|
511
|
-
'ask': this.safeString(ticker, 'ask'),
|
|
512
|
-
'askVolume': undefined,
|
|
513
|
-
'vwap': undefined,
|
|
514
|
-
'open': this.safeString(ticker, 'open'),
|
|
515
|
-
'close': close,
|
|
516
|
-
'last': close,
|
|
517
|
-
'previousClose': undefined,
|
|
518
|
-
'change': undefined,
|
|
519
|
-
'percentage': this.safeString(ticker, 'percentChange'),
|
|
520
|
-
'average': undefined,
|
|
521
|
-
'baseVolume': this.safeString(ticker, 'baseVolume'),
|
|
522
|
-
'quoteVolume': this.safeString(ticker, 'quoteVolume'),
|
|
523
|
-
'info': ticker,
|
|
524
|
-
}, market);
|
|
525
|
-
}
|
|
526
|
-
/**
|
|
527
|
-
* @method
|
|
528
|
-
* @name idex#fetchOHLCV
|
|
529
|
-
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
530
|
-
* @see https://api-docs-v3.idex.io/#get-candles
|
|
531
|
-
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
|
532
|
-
* @param {string} timeframe the length of time each candle represents
|
|
533
|
-
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
|
534
|
-
* @param {int} [limit] the maximum amount of candles to fetch
|
|
535
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
536
|
-
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
537
|
-
*/
|
|
538
|
-
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
|
539
|
-
await this.loadMarkets();
|
|
540
|
-
const market = this.market(symbol);
|
|
541
|
-
const request = {
|
|
542
|
-
'market': market['id'],
|
|
543
|
-
'interval': timeframe,
|
|
544
|
-
};
|
|
545
|
-
if (since !== undefined) {
|
|
546
|
-
request['start'] = since;
|
|
547
|
-
}
|
|
548
|
-
if (limit !== undefined) {
|
|
549
|
-
request['limit'] = Math.min(limit, 1000);
|
|
550
|
-
}
|
|
551
|
-
const response = await this.publicGetCandles(this.extend(request, params));
|
|
552
|
-
if (Array.isArray(response)) {
|
|
553
|
-
// [
|
|
554
|
-
// {
|
|
555
|
-
// "start": 1598345580000,
|
|
556
|
-
// "open": "0.09771286",
|
|
557
|
-
// "high": "0.09771286",
|
|
558
|
-
// "low": "0.09771286",
|
|
559
|
-
// "close": "0.09771286",
|
|
560
|
-
// "volume": "1.45340410",
|
|
561
|
-
// "sequence": 3853
|
|
562
|
-
// }, ...
|
|
563
|
-
// ]
|
|
564
|
-
return this.parseOHLCVs(response, market, timeframe, since, limit);
|
|
565
|
-
}
|
|
566
|
-
else {
|
|
567
|
-
// {"nextTime":1595536440000}
|
|
568
|
-
return [];
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
parseOHLCV(ohlcv, market = undefined) {
|
|
572
|
-
// {
|
|
573
|
-
// "start": 1598345580000,
|
|
574
|
-
// "open": "0.09771286",
|
|
575
|
-
// "high": "0.09771286",
|
|
576
|
-
// "low": "0.09771286",
|
|
577
|
-
// "close": "0.09771286",
|
|
578
|
-
// "volume": "1.45340410",
|
|
579
|
-
// "sequence": 3853
|
|
580
|
-
// }
|
|
581
|
-
const timestamp = this.safeInteger(ohlcv, 'start');
|
|
582
|
-
const open = this.safeNumber(ohlcv, 'open');
|
|
583
|
-
const high = this.safeNumber(ohlcv, 'high');
|
|
584
|
-
const low = this.safeNumber(ohlcv, 'low');
|
|
585
|
-
const close = this.safeNumber(ohlcv, 'close');
|
|
586
|
-
const volume = this.safeNumber(ohlcv, 'volume');
|
|
587
|
-
return [timestamp, open, high, low, close, volume];
|
|
588
|
-
}
|
|
589
|
-
/**
|
|
590
|
-
* @method
|
|
591
|
-
* @name idex#fetchTrades
|
|
592
|
-
* @description get the list of most recent trades for a particular symbol
|
|
593
|
-
* @see https://api-docs-v3.idex.io/#get-trades
|
|
594
|
-
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
595
|
-
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
596
|
-
* @param {int} [limit] the maximum amount of trades to fetch
|
|
597
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
598
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
599
|
-
*/
|
|
600
|
-
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
|
|
601
|
-
await this.loadMarkets();
|
|
602
|
-
const market = this.market(symbol);
|
|
603
|
-
const request = {
|
|
604
|
-
'market': market['id'],
|
|
605
|
-
};
|
|
606
|
-
if (since !== undefined) {
|
|
607
|
-
request['start'] = since;
|
|
608
|
-
}
|
|
609
|
-
if (limit !== undefined) {
|
|
610
|
-
request['limit'] = Math.min(limit, 1000);
|
|
611
|
-
}
|
|
612
|
-
// [
|
|
613
|
-
// {
|
|
614
|
-
// "fillId": "b5467d00-b13e-3fa9-8216-dd66735550fc",
|
|
615
|
-
// "price": "0.09771286",
|
|
616
|
-
// "quantity": "1.45340410",
|
|
617
|
-
// "quoteQuantity": "0.14201627",
|
|
618
|
-
// "time": 1598345638994,
|
|
619
|
-
// "makerSide": "buy",
|
|
620
|
-
// "sequence": 3853
|
|
621
|
-
// }, ...
|
|
622
|
-
// ]
|
|
623
|
-
const response = await this.publicGetTrades(this.extend(request, params));
|
|
624
|
-
return this.parseTrades(response, market, since, limit);
|
|
625
|
-
}
|
|
626
|
-
parseTrade(trade, market = undefined) {
|
|
627
|
-
//
|
|
628
|
-
// public trades
|
|
629
|
-
// {
|
|
630
|
-
// "fillId":"a4883704-850b-3c4b-8588-020b5e4c62f1",
|
|
631
|
-
// "price":"0.20377008",
|
|
632
|
-
// "quantity":"47.58448728",
|
|
633
|
-
// "quoteQuantity":"9.69629509",
|
|
634
|
-
// "time":1642091300873,
|
|
635
|
-
// "makerSide":"buy",
|
|
636
|
-
// "type":"hybrid", // one of either: "orderBook", "hybrid", or "pool"
|
|
637
|
-
// "sequence":31876
|
|
638
|
-
// }
|
|
639
|
-
//
|
|
640
|
-
// private trades
|
|
641
|
-
// {
|
|
642
|
-
// "fillId":"83429066-9334-3582-b710-78858b2f0d6b",
|
|
643
|
-
// "price":"0.20717368",
|
|
644
|
-
// "quantity":"15.00000000",
|
|
645
|
-
// "quoteQuantity":"3.10760523",
|
|
646
|
-
// "orderBookQuantity":"0.00000003",
|
|
647
|
-
// "orderBookQuoteQuantity":"0.00000001",
|
|
648
|
-
// "poolQuantity":"14.99999997",
|
|
649
|
-
// "poolQuoteQuantity":"3.10760522",
|
|
650
|
-
// "time":1642083351215,
|
|
651
|
-
// "makerSide":"sell",
|
|
652
|
-
// "sequence":31795,
|
|
653
|
-
// "market":"IDEX-USDC",
|
|
654
|
-
// "orderId":"4fe993f0-747b-11ec-bd08-79d4a0b6e47c",
|
|
655
|
-
// "side":"buy",
|
|
656
|
-
// "fee":"0.03749989",
|
|
657
|
-
// "feeAsset":"IDEX",
|
|
658
|
-
// "gas":"0.40507261",
|
|
659
|
-
// "liquidity":"taker",
|
|
660
|
-
// "type":"hybrid",
|
|
661
|
-
// "txId":"0x69f6d82a762d12e3201efd0b3e9cc1969351e3c6ea3cf07c47c66bf24a459815",
|
|
662
|
-
// "txStatus":"mined"
|
|
663
|
-
// }
|
|
664
|
-
//
|
|
665
|
-
const id = this.safeString(trade, 'fillId');
|
|
666
|
-
const priceString = this.safeString(trade, 'price');
|
|
667
|
-
const amountString = this.safeString(trade, 'quantity');
|
|
668
|
-
const costString = this.safeString(trade, 'quoteQuantity');
|
|
669
|
-
const timestamp = this.safeInteger(trade, 'time');
|
|
670
|
-
const marketId = this.safeString(trade, 'market');
|
|
671
|
-
const symbol = this.safeSymbol(marketId, market, '-');
|
|
672
|
-
// this code handles the duality of public vs private trades
|
|
673
|
-
const makerSide = this.safeString(trade, 'makerSide');
|
|
674
|
-
const oppositeSide = (makerSide === 'buy') ? 'sell' : 'buy';
|
|
675
|
-
const side = this.safeString(trade, 'side', oppositeSide);
|
|
676
|
-
const takerOrMaker = this.safeString(trade, 'liquidity', 'taker');
|
|
677
|
-
const feeCostString = this.safeString(trade, 'fee');
|
|
678
|
-
let fee = undefined;
|
|
679
|
-
if (feeCostString !== undefined) {
|
|
680
|
-
const feeCurrencyId = this.safeString(trade, 'feeAsset');
|
|
681
|
-
fee = {
|
|
682
|
-
'cost': feeCostString,
|
|
683
|
-
'currency': this.safeCurrencyCode(feeCurrencyId),
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
const orderId = this.safeString(trade, 'orderId');
|
|
687
|
-
return this.safeTrade({
|
|
688
|
-
'info': trade,
|
|
689
|
-
'timestamp': timestamp,
|
|
690
|
-
'datetime': this.iso8601(timestamp),
|
|
691
|
-
'symbol': symbol,
|
|
692
|
-
'id': id,
|
|
693
|
-
'order': orderId,
|
|
694
|
-
'type': 'limit',
|
|
695
|
-
'side': side,
|
|
696
|
-
'takerOrMaker': takerOrMaker,
|
|
697
|
-
'price': priceString,
|
|
698
|
-
'amount': amountString,
|
|
699
|
-
'cost': costString,
|
|
700
|
-
'fee': fee,
|
|
701
|
-
}, market);
|
|
702
|
-
}
|
|
703
|
-
/**
|
|
704
|
-
* @method
|
|
705
|
-
* @name idex#fetchTradingFees
|
|
706
|
-
* @description fetch the trading fees for multiple markets
|
|
707
|
-
* @see https://api-docs-v3.idex.io/#get-api-account
|
|
708
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
709
|
-
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
710
|
-
*/
|
|
711
|
-
async fetchTradingFees(params = {}) {
|
|
712
|
-
this.checkRequiredCredentials();
|
|
713
|
-
await this.loadMarkets();
|
|
714
|
-
const nonce = this.uuidv1();
|
|
715
|
-
const request = {
|
|
716
|
-
'nonce': nonce,
|
|
717
|
-
};
|
|
718
|
-
let response = undefined;
|
|
719
|
-
response = await this.privateGetUser(this.extend(request, params));
|
|
720
|
-
//
|
|
721
|
-
// {
|
|
722
|
-
// "depositEnabled": true,
|
|
723
|
-
// "orderEnabled": true,
|
|
724
|
-
// "cancelEnabled": true,
|
|
725
|
-
// "withdrawEnabled": true,
|
|
726
|
-
// "totalPortfolioValueUsd": "0.00",
|
|
727
|
-
// "makerFeeRate": "0.0000",
|
|
728
|
-
// "takerFeeRate": "0.0025",
|
|
729
|
-
// "takerIdexFeeRate": "0.0005",
|
|
730
|
-
// "takerLiquidityProviderFeeRate": "0.0020"
|
|
731
|
-
// }
|
|
732
|
-
//
|
|
733
|
-
const maker = this.safeNumber(response, 'makerFeeRate');
|
|
734
|
-
const taker = this.safeNumber(response, 'takerFeeRate');
|
|
735
|
-
const result = {};
|
|
736
|
-
for (let i = 0; i < this.symbols.length; i++) {
|
|
737
|
-
const symbol = this.symbols[i];
|
|
738
|
-
result[symbol] = {
|
|
739
|
-
'info': response,
|
|
740
|
-
'symbol': symbol,
|
|
741
|
-
'maker': maker,
|
|
742
|
-
'taker': taker,
|
|
743
|
-
'percentage': true,
|
|
744
|
-
'tierBased': false,
|
|
745
|
-
};
|
|
746
|
-
}
|
|
747
|
-
return result;
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* @method
|
|
751
|
-
* @name idex#fetchOrderBook
|
|
752
|
-
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
753
|
-
* @see https://api-docs-v3.idex.io/#get-order-books
|
|
754
|
-
* @param {string} symbol unified symbol of the market to fetch the order book for
|
|
755
|
-
* @param {int} [limit] the maximum amount of order book entries to return
|
|
756
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
757
|
-
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
758
|
-
*/
|
|
759
|
-
async fetchOrderBook(symbol, limit = undefined, params = {}) {
|
|
760
|
-
await this.loadMarkets();
|
|
761
|
-
const market = this.market(symbol);
|
|
762
|
-
const request = {
|
|
763
|
-
'market': market['id'],
|
|
764
|
-
'level': 2,
|
|
765
|
-
};
|
|
766
|
-
if (limit !== undefined) {
|
|
767
|
-
request['limit'] = limit;
|
|
768
|
-
}
|
|
769
|
-
// {
|
|
770
|
-
// "sequence": 36416753,
|
|
771
|
-
// "bids": [
|
|
772
|
-
// [ '0.09672815', "8.22284267", 1 ],
|
|
773
|
-
// [ '0.09672814', "1.83685554", 1 ],
|
|
774
|
-
// [ '0.09672143', "4.10962617", 1 ],
|
|
775
|
-
// [ '0.09658884', "4.03863759", 1 ],
|
|
776
|
-
// [ '0.09653781', "3.35730684", 1 ],
|
|
777
|
-
// [ '0.09624660', "2.54163586", 1 ],
|
|
778
|
-
// [ '0.09617490', "1.93065030", 1 ]
|
|
779
|
-
// ],
|
|
780
|
-
// "asks": [
|
|
781
|
-
// [ '0.09910476', "3.22840154", 1 ],
|
|
782
|
-
// [ '0.09940587', "3.39796593", 1 ],
|
|
783
|
-
// [ '0.09948189', "4.25088898", 1 ],
|
|
784
|
-
// [ '0.09958362', "2.42195784", 1 ],
|
|
785
|
-
// [ '0.09974393', "4.25234367", 1 ],
|
|
786
|
-
// [ '0.09995250', "3.40192141", 1 ]
|
|
787
|
-
// ]
|
|
788
|
-
// }
|
|
789
|
-
const response = await this.publicGetOrderbook(this.extend(request, params));
|
|
790
|
-
const nonce = this.safeInteger(response, 'sequence');
|
|
791
|
-
return {
|
|
792
|
-
'symbol': symbol,
|
|
793
|
-
'timestamp': undefined,
|
|
794
|
-
'datetime': undefined,
|
|
795
|
-
'nonce': nonce,
|
|
796
|
-
'bids': this.parseSide(response, 'bids'),
|
|
797
|
-
'asks': this.parseSide(response, 'asks'),
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
parseSide(book, side) {
|
|
801
|
-
const bookSide = this.safeValue(book, side, []);
|
|
802
|
-
const result = [];
|
|
803
|
-
for (let i = 0; i < bookSide.length; i++) {
|
|
804
|
-
const order = bookSide[i];
|
|
805
|
-
const price = this.safeNumber(order, 0);
|
|
806
|
-
const amount = this.safeNumber(order, 1);
|
|
807
|
-
const orderCount = this.safeInteger(order, 2);
|
|
808
|
-
result.push([price, amount, orderCount]);
|
|
809
|
-
}
|
|
810
|
-
const descending = side === 'bids';
|
|
811
|
-
return this.sortBy(result, 0, descending);
|
|
812
|
-
}
|
|
813
|
-
/**
|
|
814
|
-
* @method
|
|
815
|
-
* @name idex#fetchCurrencies
|
|
816
|
-
* @description fetches all available currencies on an exchange
|
|
817
|
-
* @see https://api-docs-v3.idex.io/#get-assets
|
|
818
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
819
|
-
* @returns {object} an associative dictionary of currencies
|
|
820
|
-
*/
|
|
821
|
-
async fetchCurrencies(params = {}) {
|
|
822
|
-
const response = await this.publicGetAssets(params);
|
|
823
|
-
//
|
|
824
|
-
// [
|
|
825
|
-
// {
|
|
826
|
-
// "name": "Ethereum",
|
|
827
|
-
// "symbol": "ETH",
|
|
828
|
-
// "contractAddress": "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
|
|
829
|
-
// "assetDecimals": "18",
|
|
830
|
-
// "exchangeDecimals": "8",
|
|
831
|
-
// "maticPrice": "3029.38503483"
|
|
832
|
-
// },
|
|
833
|
-
// ]
|
|
834
|
-
//
|
|
835
|
-
const result = {};
|
|
836
|
-
for (let i = 0; i < response.length; i++) {
|
|
837
|
-
const entry = response[i];
|
|
838
|
-
const name = this.safeString(entry, 'name');
|
|
839
|
-
const currencyId = this.safeString(entry, 'symbol');
|
|
840
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
841
|
-
const precision = this.parseNumber(this.parsePrecision(this.safeString(entry, 'exchangeDecimals')));
|
|
842
|
-
result[code] = {
|
|
843
|
-
'id': currencyId,
|
|
844
|
-
'code': code,
|
|
845
|
-
'info': entry,
|
|
846
|
-
'type': undefined,
|
|
847
|
-
'name': name,
|
|
848
|
-
'active': undefined,
|
|
849
|
-
'deposit': undefined,
|
|
850
|
-
'withdraw': undefined,
|
|
851
|
-
'fee': undefined,
|
|
852
|
-
'precision': precision,
|
|
853
|
-
'limits': {
|
|
854
|
-
'amount': { 'min': precision, 'max': undefined },
|
|
855
|
-
'withdraw': { 'min': precision, 'max': undefined },
|
|
856
|
-
},
|
|
857
|
-
};
|
|
858
|
-
}
|
|
859
|
-
return result;
|
|
860
|
-
}
|
|
861
|
-
parseBalance(response) {
|
|
862
|
-
const result = {
|
|
863
|
-
'info': response,
|
|
864
|
-
'timestamp': undefined,
|
|
865
|
-
'datetime': undefined,
|
|
866
|
-
};
|
|
867
|
-
for (let i = 0; i < response.length; i++) {
|
|
868
|
-
const entry = response[i];
|
|
869
|
-
const currencyId = this.safeString(entry, 'asset');
|
|
870
|
-
const code = this.safeCurrencyCode(currencyId);
|
|
871
|
-
const account = this.account();
|
|
872
|
-
account['total'] = this.safeString(entry, 'quantity');
|
|
873
|
-
account['free'] = this.safeString(entry, 'availableForTrade');
|
|
874
|
-
account['used'] = this.safeString(entry, 'locked');
|
|
875
|
-
result[code] = account;
|
|
876
|
-
}
|
|
877
|
-
return this.safeBalance(result);
|
|
878
|
-
}
|
|
879
|
-
/**
|
|
880
|
-
* @method
|
|
881
|
-
* @name idex#fetchBalance
|
|
882
|
-
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
883
|
-
* @see https://api-docs-v3.idex.io/#get-balances
|
|
884
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
885
|
-
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
886
|
-
*/
|
|
887
|
-
async fetchBalance(params = {}) {
|
|
888
|
-
this.checkRequiredCredentials();
|
|
889
|
-
await this.loadMarkets();
|
|
890
|
-
const nonce1 = this.uuidv1();
|
|
891
|
-
const request = {
|
|
892
|
-
'nonce': nonce1,
|
|
893
|
-
'wallet': this.walletAddress,
|
|
894
|
-
};
|
|
895
|
-
// [
|
|
896
|
-
// {
|
|
897
|
-
// "asset": "DIL",
|
|
898
|
-
// "quantity": "0.00000000",
|
|
899
|
-
// "availableForTrade": "0.00000000",
|
|
900
|
-
// "locked": "0.00000000",
|
|
901
|
-
// "usdValue": null
|
|
902
|
-
// }, ...
|
|
903
|
-
// ]
|
|
904
|
-
const extendedRequest = this.extend(request, params);
|
|
905
|
-
if (extendedRequest['wallet'] === undefined) {
|
|
906
|
-
throw new BadRequest(this.id + ' fetchBalance() wallet is undefined, set this.walletAddress or "address" in params');
|
|
907
|
-
}
|
|
908
|
-
let response = undefined;
|
|
909
|
-
try {
|
|
910
|
-
response = await this.privateGetBalances(extendedRequest);
|
|
911
|
-
}
|
|
912
|
-
catch (e) {
|
|
913
|
-
if (e instanceof InvalidAddress) {
|
|
914
|
-
const walletAddress = extendedRequest['wallet'];
|
|
915
|
-
await this.associateWallet(walletAddress);
|
|
916
|
-
response = await this.privateGetBalances(extendedRequest);
|
|
917
|
-
}
|
|
918
|
-
else {
|
|
919
|
-
throw e;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
return this.parseBalance(response);
|
|
923
|
-
}
|
|
924
|
-
/**
|
|
925
|
-
* @method
|
|
926
|
-
* @name idex#fetchMyTrades
|
|
927
|
-
* @description fetch all trades made by the user
|
|
928
|
-
* @see https://api-docs-v3.idex.io/#get-fills
|
|
929
|
-
* @param {string} symbol unified market symbol
|
|
930
|
-
* @param {int} [since] the earliest time in ms to fetch trades for
|
|
931
|
-
* @param {int} [limit] the maximum number of trades structures to retrieve
|
|
932
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
933
|
-
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
|
934
|
-
*/
|
|
935
|
-
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
936
|
-
this.checkRequiredCredentials();
|
|
937
|
-
await this.loadMarkets();
|
|
938
|
-
let market = undefined;
|
|
939
|
-
const request = {
|
|
940
|
-
'nonce': this.uuidv1(),
|
|
941
|
-
'wallet': this.walletAddress,
|
|
942
|
-
};
|
|
943
|
-
if (symbol !== undefined) {
|
|
944
|
-
market = this.market(symbol);
|
|
945
|
-
request['market'] = market['id'];
|
|
946
|
-
}
|
|
947
|
-
if (since !== undefined) {
|
|
948
|
-
request['start'] = since;
|
|
949
|
-
}
|
|
950
|
-
if (limit !== undefined) {
|
|
951
|
-
request['limit'] = limit;
|
|
952
|
-
}
|
|
953
|
-
// [
|
|
954
|
-
// {
|
|
955
|
-
// "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
|
|
956
|
-
// "price": "0.09905990",
|
|
957
|
-
// "quantity": "0.40000000",
|
|
958
|
-
// "quoteQuantity": "0.03962396",
|
|
959
|
-
// "time": 1598873478762,
|
|
960
|
-
// "makerSide": "sell",
|
|
961
|
-
// "sequence": 5053,
|
|
962
|
-
// "market": "DIL-ETH",
|
|
963
|
-
// "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
|
|
964
|
-
// "side": "buy",
|
|
965
|
-
// "fee": "0.00080000",
|
|
966
|
-
// "feeAsset": "DIL",
|
|
967
|
-
// "gas": "0.00857497",
|
|
968
|
-
// "liquidity": "taker",
|
|
969
|
-
// "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
|
|
970
|
-
// "txStatus": "mined"
|
|
971
|
-
// }
|
|
972
|
-
// ]
|
|
973
|
-
const extendedRequest = this.extend(request, params);
|
|
974
|
-
if (extendedRequest['wallet'] === undefined) {
|
|
975
|
-
throw new BadRequest(this.id + ' fetchMyTrades() walletAddress is undefined, set this.walletAddress or "address" in params');
|
|
976
|
-
}
|
|
977
|
-
let response = undefined;
|
|
978
|
-
try {
|
|
979
|
-
response = await this.privateGetFills(extendedRequest);
|
|
980
|
-
}
|
|
981
|
-
catch (e) {
|
|
982
|
-
if (e instanceof InvalidAddress) {
|
|
983
|
-
const walletAddress = extendedRequest['wallet'];
|
|
984
|
-
await this.associateWallet(walletAddress);
|
|
985
|
-
response = await this.privateGetFills(extendedRequest);
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
throw e;
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
return this.parseTrades(response, market, since, limit);
|
|
992
|
-
}
|
|
993
|
-
/**
|
|
994
|
-
* @method
|
|
995
|
-
* @name idex#fetchOrder
|
|
996
|
-
* @description fetches information on an order made by the user
|
|
997
|
-
* @see https://api-docs-v3.idex.io/#get-orders
|
|
998
|
-
* @param {string} id order id
|
|
999
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1000
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1001
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1002
|
-
*/
|
|
1003
|
-
async fetchOrder(id, symbol = undefined, params = {}) {
|
|
1004
|
-
const request = {
|
|
1005
|
-
'orderId': id,
|
|
1006
|
-
};
|
|
1007
|
-
return await this.fetchOrdersHelper(symbol, undefined, undefined, this.extend(request, params));
|
|
1008
|
-
}
|
|
1009
|
-
/**
|
|
1010
|
-
* @method
|
|
1011
|
-
* @name idex#fetchOpenOrders
|
|
1012
|
-
* @description fetch all unfilled currently open orders
|
|
1013
|
-
* @see https://api-docs-v3.idex.io/#get-orders
|
|
1014
|
-
* @param {string} symbol unified market symbol
|
|
1015
|
-
* @param {int} [since] the earliest time in ms to fetch open orders for
|
|
1016
|
-
* @param {int} [limit] the maximum number of open orders structures to retrieve
|
|
1017
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1018
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1019
|
-
*/
|
|
1020
|
-
async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1021
|
-
const request = {
|
|
1022
|
-
'closed': false,
|
|
1023
|
-
};
|
|
1024
|
-
return await this.fetchOrdersHelper(symbol, since, limit, this.extend(request, params));
|
|
1025
|
-
}
|
|
1026
|
-
/**
|
|
1027
|
-
* @method
|
|
1028
|
-
* @name idex#fetchClosedOrders
|
|
1029
|
-
* @description fetches information on multiple closed orders made by the user
|
|
1030
|
-
* @see https://api-docs-v3.idex.io/#get-orders
|
|
1031
|
-
* @param {string} symbol unified market symbol of the market orders were made in
|
|
1032
|
-
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
1033
|
-
* @param {int} [limit] the maximum number of order structures to retrieve
|
|
1034
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1035
|
-
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1036
|
-
*/
|
|
1037
|
-
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1038
|
-
const request = {
|
|
1039
|
-
'closed': true,
|
|
1040
|
-
};
|
|
1041
|
-
return await this.fetchOrdersHelper(symbol, since, limit, this.extend(request, params));
|
|
1042
|
-
}
|
|
1043
|
-
async fetchOrdersHelper(symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1044
|
-
await this.loadMarkets();
|
|
1045
|
-
const request = {
|
|
1046
|
-
'nonce': this.uuidv1(),
|
|
1047
|
-
'wallet': this.walletAddress,
|
|
1048
|
-
};
|
|
1049
|
-
let market = undefined;
|
|
1050
|
-
if (symbol !== undefined) {
|
|
1051
|
-
market = this.market(symbol);
|
|
1052
|
-
request['market'] = market['id'];
|
|
1053
|
-
}
|
|
1054
|
-
if (since !== undefined) {
|
|
1055
|
-
request['start'] = since;
|
|
1056
|
-
}
|
|
1057
|
-
if (limit !== undefined) {
|
|
1058
|
-
request['limit'] = limit;
|
|
1059
|
-
}
|
|
1060
|
-
const response = await this.privateGetOrders(this.extend(request, params));
|
|
1061
|
-
// fetchClosedOrders / fetchOpenOrders
|
|
1062
|
-
// [
|
|
1063
|
-
// {
|
|
1064
|
-
// "market": "DIL-ETH",
|
|
1065
|
-
// "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
|
|
1066
|
-
// "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
|
|
1067
|
-
// "time": 1598873478650,
|
|
1068
|
-
// "status": "filled",
|
|
1069
|
-
// "type": "limit",
|
|
1070
|
-
// "side": "buy",
|
|
1071
|
-
// "originalQuantity": "0.40000000",
|
|
1072
|
-
// "executedQuantity": "0.40000000",
|
|
1073
|
-
// "cumulativeQuoteQuantity": "0.03962396",
|
|
1074
|
-
// "avgExecutionPrice": "0.09905990",
|
|
1075
|
-
// "price": "1.00000000",
|
|
1076
|
-
// "fills": [
|
|
1077
|
-
// {
|
|
1078
|
-
// "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
|
|
1079
|
-
// "price": "0.09905990",
|
|
1080
|
-
// "quantity": "0.40000000",
|
|
1081
|
-
// "quoteQuantity": "0.03962396",
|
|
1082
|
-
// "time": 1598873478650,
|
|
1083
|
-
// "makerSide": "sell",
|
|
1084
|
-
// "sequence": 5053,
|
|
1085
|
-
// "fee": "0.00080000",
|
|
1086
|
-
// "feeAsset": "DIL",
|
|
1087
|
-
// "gas": "0.00857497",
|
|
1088
|
-
// "liquidity": "taker",
|
|
1089
|
-
// "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
|
|
1090
|
-
// "txStatus": "mined"
|
|
1091
|
-
// }
|
|
1092
|
-
// ]
|
|
1093
|
-
// }
|
|
1094
|
-
// ]
|
|
1095
|
-
// fetchOrder
|
|
1096
|
-
// { market: "DIL-ETH",
|
|
1097
|
-
// "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
|
|
1098
|
-
// "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
|
|
1099
|
-
// "time": 1598873478650,
|
|
1100
|
-
// "status": "filled",
|
|
1101
|
-
// "type": "limit",
|
|
1102
|
-
// "side": "buy",
|
|
1103
|
-
// "originalQuantity": "0.40000000",
|
|
1104
|
-
// "executedQuantity": "0.40000000",
|
|
1105
|
-
// "cumulativeQuoteQuantity": "0.03962396",
|
|
1106
|
-
// "avgExecutionPrice": "0.09905990",
|
|
1107
|
-
// "price": "1.00000000",
|
|
1108
|
-
// "fills":
|
|
1109
|
-
// [ { fillId: "48582d10-b9bb-3c4b-94d3-e67537cf2472",
|
|
1110
|
-
// "price": "0.09905990",
|
|
1111
|
-
// "quantity": "0.40000000",
|
|
1112
|
-
// "quoteQuantity": "0.03962396",
|
|
1113
|
-
// "time": 1598873478650,
|
|
1114
|
-
// "makerSide": "sell",
|
|
1115
|
-
// "sequence": 5053,
|
|
1116
|
-
// "fee": "0.00080000",
|
|
1117
|
-
// "feeAsset": "DIL",
|
|
1118
|
-
// "gas": "0.00857497",
|
|
1119
|
-
// "liquidity": "taker",
|
|
1120
|
-
// "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
|
|
1121
|
-
// "txStatus": "mined" } ] }
|
|
1122
|
-
if (Array.isArray(response)) {
|
|
1123
|
-
return this.parseOrders(response, market, since, limit);
|
|
1124
|
-
}
|
|
1125
|
-
else {
|
|
1126
|
-
return this.parseOrder(response, market);
|
|
1127
|
-
}
|
|
1128
|
-
}
|
|
1129
|
-
parseOrderStatus(status) {
|
|
1130
|
-
// https://docs.idex.io/#order-states-amp-lifecycle
|
|
1131
|
-
const statuses = {
|
|
1132
|
-
'active': 'open',
|
|
1133
|
-
'partiallyFilled': 'open',
|
|
1134
|
-
'rejected': 'canceled',
|
|
1135
|
-
'filled': 'closed',
|
|
1136
|
-
};
|
|
1137
|
-
return this.safeString(statuses, status, status);
|
|
1138
|
-
}
|
|
1139
|
-
parseOrder(order, market = undefined) {
|
|
1140
|
-
//
|
|
1141
|
-
// {
|
|
1142
|
-
// "market": "DIL-ETH",
|
|
1143
|
-
// "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
|
|
1144
|
-
// "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
|
|
1145
|
-
// "time": 1598873478650,
|
|
1146
|
-
// "status": "filled",
|
|
1147
|
-
// "type": "limit",
|
|
1148
|
-
// "side": "buy",
|
|
1149
|
-
// "originalQuantity": "0.40000000",
|
|
1150
|
-
// "executedQuantity": "0.40000000",
|
|
1151
|
-
// "cumulativeQuoteQuantity": "0.03962396",
|
|
1152
|
-
// "avgExecutionPrice": "0.09905990",
|
|
1153
|
-
// "price": "1.00000000",
|
|
1154
|
-
// "fills": [
|
|
1155
|
-
// {
|
|
1156
|
-
// "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
|
|
1157
|
-
// "price": "0.09905990",
|
|
1158
|
-
// "quantity": "0.40000000",
|
|
1159
|
-
// "quoteQuantity": "0.03962396",
|
|
1160
|
-
// "time": 1598873478650,
|
|
1161
|
-
// "makerSide": "sell",
|
|
1162
|
-
// "sequence": 5053,
|
|
1163
|
-
// "fee": "0.00080000",
|
|
1164
|
-
// "feeAsset": "DIL",
|
|
1165
|
-
// "gas": "0.00857497",
|
|
1166
|
-
// "liquidity": "taker",
|
|
1167
|
-
// "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
|
|
1168
|
-
// "txStatus": "mined"
|
|
1169
|
-
// }
|
|
1170
|
-
// ]
|
|
1171
|
-
// }
|
|
1172
|
-
//
|
|
1173
|
-
const timestamp = this.safeInteger(order, 'time');
|
|
1174
|
-
const fills = this.safeValue(order, 'fills', []);
|
|
1175
|
-
const id = this.safeString(order, 'orderId');
|
|
1176
|
-
const clientOrderId = this.safeString(order, 'clientOrderId');
|
|
1177
|
-
const marketId = this.safeString(order, 'market');
|
|
1178
|
-
const side = this.safeString(order, 'side');
|
|
1179
|
-
const symbol = this.safeSymbol(marketId, market, '-');
|
|
1180
|
-
const type = this.safeString(order, 'type');
|
|
1181
|
-
const amount = this.safeString(order, 'originalQuantity');
|
|
1182
|
-
const filled = this.safeString(order, 'executedQuantity');
|
|
1183
|
-
const average = this.safeString(order, 'avgExecutionPrice');
|
|
1184
|
-
const price = this.safeString(order, 'price');
|
|
1185
|
-
const rawStatus = this.safeString(order, 'status');
|
|
1186
|
-
const timeInForce = this.safeStringUpper(order, 'timeInForce');
|
|
1187
|
-
const status = this.parseOrderStatus(rawStatus);
|
|
1188
|
-
return this.safeOrder({
|
|
1189
|
-
'info': order,
|
|
1190
|
-
'id': id,
|
|
1191
|
-
'clientOrderId': clientOrderId,
|
|
1192
|
-
'timestamp': timestamp,
|
|
1193
|
-
'datetime': this.iso8601(timestamp),
|
|
1194
|
-
'lastTradeTimestamp': undefined,
|
|
1195
|
-
'symbol': symbol,
|
|
1196
|
-
'type': type,
|
|
1197
|
-
'timeInForce': timeInForce,
|
|
1198
|
-
'postOnly': undefined,
|
|
1199
|
-
'side': side,
|
|
1200
|
-
'price': price,
|
|
1201
|
-
'triggerPrice': undefined,
|
|
1202
|
-
'amount': amount,
|
|
1203
|
-
'cost': undefined,
|
|
1204
|
-
'average': average,
|
|
1205
|
-
'filled': filled,
|
|
1206
|
-
'remaining': undefined,
|
|
1207
|
-
'status': status,
|
|
1208
|
-
'fee': undefined,
|
|
1209
|
-
'trades': fills,
|
|
1210
|
-
}, market);
|
|
1211
|
-
}
|
|
1212
|
-
async associateWallet(walletAddress, params = {}) {
|
|
1213
|
-
const nonce = this.uuidv1();
|
|
1214
|
-
const noPrefix = this.remove0xPrefix(walletAddress);
|
|
1215
|
-
const byteArray = [
|
|
1216
|
-
this.base16ToBinary(nonce),
|
|
1217
|
-
this.base16ToBinary(noPrefix),
|
|
1218
|
-
];
|
|
1219
|
-
const binary = this.binaryConcatArray(byteArray);
|
|
1220
|
-
const hash = this.hash(binary, keccak, 'hex');
|
|
1221
|
-
const signature = this.signMessageString(hash, this.privateKey);
|
|
1222
|
-
// {
|
|
1223
|
-
// "address": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
|
|
1224
|
-
// "totalPortfolioValueUsd": "0.00",
|
|
1225
|
-
// "time": 1598468353626
|
|
1226
|
-
// }
|
|
1227
|
-
const request = {
|
|
1228
|
-
'parameters': {
|
|
1229
|
-
'nonce': nonce,
|
|
1230
|
-
'wallet': walletAddress,
|
|
1231
|
-
},
|
|
1232
|
-
'signature': signature,
|
|
1233
|
-
};
|
|
1234
|
-
const result = await this.privatePostWallets(request);
|
|
1235
|
-
return result;
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* @method
|
|
1239
|
-
* @name idex#createOrder
|
|
1240
|
-
* @description create a trade order, https://docs.idex.io/#create-order
|
|
1241
|
-
* @see https://api-docs-v3.idex.io/#create-order
|
|
1242
|
-
* @param {string} symbol unified symbol of the market to create an order in
|
|
1243
|
-
* @param {string} type 'market' or 'limit'
|
|
1244
|
-
* @param {string} side 'buy' or 'sell'
|
|
1245
|
-
* @param {float} amount how much of currency you want to trade in units of base currency
|
|
1246
|
-
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1247
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1248
|
-
* @param {bool} [params.test] set to true to test an order, no order will be created but the request will be validated
|
|
1249
|
-
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1250
|
-
*/
|
|
1251
|
-
async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
|
|
1252
|
-
this.checkRequiredCredentials();
|
|
1253
|
-
await this.loadMarkets();
|
|
1254
|
-
const testOrder = this.safeBool(params, 'test', false);
|
|
1255
|
-
params = this.omit(params, 'test');
|
|
1256
|
-
const market = this.market(symbol);
|
|
1257
|
-
const nonce = this.uuidv1();
|
|
1258
|
-
let typeEnum = undefined;
|
|
1259
|
-
const stopLossTypeEnums = {
|
|
1260
|
-
'stopLoss': 3,
|
|
1261
|
-
'stopLossLimit': 4,
|
|
1262
|
-
'takeProfit': 5,
|
|
1263
|
-
'takeProfitLimit': 6,
|
|
1264
|
-
};
|
|
1265
|
-
const triggerPrice = this.safeString(params, 'triggerPrice', 'stopPrice');
|
|
1266
|
-
let triggerPriceString = undefined;
|
|
1267
|
-
if ((type === 'stopLossLimit') || (type === 'takeProfitLimit')) {
|
|
1268
|
-
if (triggerPrice === undefined) {
|
|
1269
|
-
throw new BadRequest(this.id + ' createOrder() triggerPrice is a required parameter for ' + type + 'orders');
|
|
1270
|
-
}
|
|
1271
|
-
triggerPriceString = this.priceToPrecision(symbol, triggerPrice);
|
|
1272
|
-
}
|
|
1273
|
-
const limitTypeEnums = {
|
|
1274
|
-
'limit': 1,
|
|
1275
|
-
'limitMaker': 2,
|
|
1276
|
-
};
|
|
1277
|
-
let priceString = undefined;
|
|
1278
|
-
const typeLower = type.toLowerCase();
|
|
1279
|
-
const limitOrder = typeLower.indexOf('limit') >= 0;
|
|
1280
|
-
if (type in limitTypeEnums) {
|
|
1281
|
-
typeEnum = limitTypeEnums[type];
|
|
1282
|
-
priceString = this.priceToPrecision(symbol, price);
|
|
1283
|
-
}
|
|
1284
|
-
else if (type in stopLossTypeEnums) {
|
|
1285
|
-
typeEnum = stopLossTypeEnums[type];
|
|
1286
|
-
priceString = this.priceToPrecision(symbol, price);
|
|
1287
|
-
}
|
|
1288
|
-
else if (type === 'market') {
|
|
1289
|
-
typeEnum = 0;
|
|
1290
|
-
}
|
|
1291
|
-
else {
|
|
1292
|
-
throw new BadRequest(this.id + ' ' + type + ' is not a valid order type');
|
|
1293
|
-
}
|
|
1294
|
-
let amountEnum = 0; // base quantity
|
|
1295
|
-
if ('quoteOrderQuantity' in params) {
|
|
1296
|
-
if (type !== 'market') {
|
|
1297
|
-
throw new NotSupported(this.id + ' createOrder() quoteOrderQuantity is not supported for ' + type + ' orders, only supported for market orders');
|
|
1298
|
-
}
|
|
1299
|
-
amountEnum = 1;
|
|
1300
|
-
amount = this.safeNumber(params, 'quoteOrderQuantity');
|
|
1301
|
-
}
|
|
1302
|
-
const sideEnum = (side === 'buy') ? 0 : 1;
|
|
1303
|
-
const walletBytes = this.remove0xPrefix(this.walletAddress);
|
|
1304
|
-
const network = this.safeString(this.options, 'network', 'ETH');
|
|
1305
|
-
const orderVersion = this.getSupportedMapping(network, {
|
|
1306
|
-
'ETH': 1,
|
|
1307
|
-
'BSC': 2,
|
|
1308
|
-
'MATIC': 4,
|
|
1309
|
-
});
|
|
1310
|
-
const amountString = this.amountToPrecision(symbol, amount);
|
|
1311
|
-
// https://docs.idex.io/#time-in-force
|
|
1312
|
-
const timeInForceEnums = {
|
|
1313
|
-
'gtc': 0,
|
|
1314
|
-
'ioc': 2,
|
|
1315
|
-
'fok': 3,
|
|
1316
|
-
};
|
|
1317
|
-
const defaultTimeInForce = this.safeString(this.options, 'defaultTimeInForce', 'gtc');
|
|
1318
|
-
const timeInForce = this.safeString(params, 'timeInForce', defaultTimeInForce);
|
|
1319
|
-
let timeInForceEnum = undefined;
|
|
1320
|
-
if (timeInForce in timeInForceEnums) {
|
|
1321
|
-
timeInForceEnum = timeInForceEnums[timeInForce];
|
|
1322
|
-
}
|
|
1323
|
-
else {
|
|
1324
|
-
const allOptions = Object.keys(timeInForceEnums);
|
|
1325
|
-
const asString = allOptions.join(', ');
|
|
1326
|
-
throw new BadRequest(this.id + ' ' + timeInForce + ' is not a valid timeInForce, please choose one of ' + asString);
|
|
1327
|
-
}
|
|
1328
|
-
// https://docs.idex.io/#self-trade-prevention
|
|
1329
|
-
const selfTradePreventionEnums = {
|
|
1330
|
-
'dc': 0,
|
|
1331
|
-
'co': 1,
|
|
1332
|
-
'cn': 2,
|
|
1333
|
-
'cb': 3,
|
|
1334
|
-
};
|
|
1335
|
-
const defaultSelfTradePrevention = this.safeString(this.options, 'defaultSelfTradePrevention', 'cn');
|
|
1336
|
-
const selfTradePrevention = this.safeString(params, 'selfTradePrevention', defaultSelfTradePrevention);
|
|
1337
|
-
let selfTradePreventionEnum = undefined;
|
|
1338
|
-
if (selfTradePrevention in selfTradePreventionEnums) {
|
|
1339
|
-
selfTradePreventionEnum = selfTradePreventionEnums[selfTradePrevention];
|
|
1340
|
-
}
|
|
1341
|
-
else {
|
|
1342
|
-
const allOptions = Object.keys(selfTradePreventionEnums);
|
|
1343
|
-
const asString = allOptions.join(', ');
|
|
1344
|
-
throw new BadRequest(this.id + ' ' + selfTradePrevention + ' is not a valid selfTradePrevention, please choose one of ' + asString);
|
|
1345
|
-
}
|
|
1346
|
-
const byteArray = [
|
|
1347
|
-
this.numberToBE(orderVersion, 1),
|
|
1348
|
-
this.base16ToBinary(nonce),
|
|
1349
|
-
this.base16ToBinary(walletBytes),
|
|
1350
|
-
this.encode(market['id']),
|
|
1351
|
-
this.numberToBE(typeEnum, 1),
|
|
1352
|
-
this.numberToBE(sideEnum, 1),
|
|
1353
|
-
this.encode(amountString),
|
|
1354
|
-
this.numberToBE(amountEnum, 1),
|
|
1355
|
-
];
|
|
1356
|
-
if (limitOrder) {
|
|
1357
|
-
const encodedPrice = this.encode(priceString);
|
|
1358
|
-
byteArray.push(encodedPrice);
|
|
1359
|
-
}
|
|
1360
|
-
if (type in stopLossTypeEnums) {
|
|
1361
|
-
const encodedPrice = this.encode(triggerPriceString || priceString);
|
|
1362
|
-
byteArray.push(encodedPrice);
|
|
1363
|
-
}
|
|
1364
|
-
const clientOrderId = this.safeString(params, 'clientOrderId');
|
|
1365
|
-
if (clientOrderId !== undefined) {
|
|
1366
|
-
byteArray.push(this.encode(clientOrderId));
|
|
1367
|
-
}
|
|
1368
|
-
const after = [
|
|
1369
|
-
this.numberToBE(timeInForceEnum, 1),
|
|
1370
|
-
this.numberToBE(selfTradePreventionEnum, 1),
|
|
1371
|
-
this.numberToBE(0, 8), // unused
|
|
1372
|
-
];
|
|
1373
|
-
const allBytes = this.arrayConcat(byteArray, after);
|
|
1374
|
-
const binary = this.binaryConcatArray(allBytes);
|
|
1375
|
-
const hash = this.hash(binary, keccak, 'hex');
|
|
1376
|
-
const signature = this.signMessageString(hash, this.privateKey);
|
|
1377
|
-
const request = {
|
|
1378
|
-
'parameters': {
|
|
1379
|
-
'nonce': nonce,
|
|
1380
|
-
'market': market['id'],
|
|
1381
|
-
'side': side,
|
|
1382
|
-
'type': type,
|
|
1383
|
-
'wallet': this.walletAddress,
|
|
1384
|
-
'selfTradePrevention': selfTradePrevention,
|
|
1385
|
-
},
|
|
1386
|
-
'signature': signature,
|
|
1387
|
-
};
|
|
1388
|
-
if (type !== 'market') {
|
|
1389
|
-
request['parameters']['timeInForce'] = timeInForce;
|
|
1390
|
-
}
|
|
1391
|
-
if (limitOrder) {
|
|
1392
|
-
request['parameters']['price'] = priceString;
|
|
1393
|
-
}
|
|
1394
|
-
if (type in stopLossTypeEnums) {
|
|
1395
|
-
request['parameters']['stopPrice'] = triggerPriceString || priceString;
|
|
1396
|
-
}
|
|
1397
|
-
if (amountEnum === 0) {
|
|
1398
|
-
request['parameters']['quantity'] = amountString;
|
|
1399
|
-
}
|
|
1400
|
-
else {
|
|
1401
|
-
request['parameters']['quoteOrderQuantity'] = amountString;
|
|
1402
|
-
}
|
|
1403
|
-
if (clientOrderId !== undefined) {
|
|
1404
|
-
request['parameters']['clientOrderId'] = clientOrderId;
|
|
1405
|
-
}
|
|
1406
|
-
// {
|
|
1407
|
-
// "market": "DIL-ETH",
|
|
1408
|
-
// "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
|
|
1409
|
-
// "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
|
|
1410
|
-
// "time": 1598873478650,
|
|
1411
|
-
// "status": "filled",
|
|
1412
|
-
// "type": "limit",
|
|
1413
|
-
// "side": "buy",
|
|
1414
|
-
// "originalQuantity": "0.40000000",
|
|
1415
|
-
// "executedQuantity": "0.40000000",
|
|
1416
|
-
// "cumulativeQuoteQuantity": "0.03962396",
|
|
1417
|
-
// "price": "1.00000000",
|
|
1418
|
-
// "fills": [
|
|
1419
|
-
// {
|
|
1420
|
-
// "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
|
|
1421
|
-
// "price": "0.09905990",
|
|
1422
|
-
// "quantity": "0.40000000",
|
|
1423
|
-
// "quoteQuantity": "0.03962396",
|
|
1424
|
-
// "time": 1598873478650,
|
|
1425
|
-
// "makerSide": "sell",
|
|
1426
|
-
// "sequence": 5053,
|
|
1427
|
-
// "fee": "0.00080000",
|
|
1428
|
-
// "feeAsset": "DIL",
|
|
1429
|
-
// "gas": "0.00857497",
|
|
1430
|
-
// "liquidity": "taker",
|
|
1431
|
-
// "txStatus": "pending"
|
|
1432
|
-
// }
|
|
1433
|
-
// ],
|
|
1434
|
-
// "avgExecutionPrice": "0.09905990"
|
|
1435
|
-
// }
|
|
1436
|
-
// we don't use extend here because it is a signed endpoint
|
|
1437
|
-
let response = undefined;
|
|
1438
|
-
if (testOrder) {
|
|
1439
|
-
response = await this.privatePostOrdersTest(request);
|
|
1440
|
-
}
|
|
1441
|
-
else {
|
|
1442
|
-
response = await this.privatePostOrders(request);
|
|
1443
|
-
}
|
|
1444
|
-
return this.parseOrder(response, market);
|
|
1445
|
-
}
|
|
1446
|
-
/**
|
|
1447
|
-
* @method
|
|
1448
|
-
* @name idex#withdraw
|
|
1449
|
-
* @description make a withdrawal
|
|
1450
|
-
* @see https://api-docs-v3.idex.io/#withdraw-funds
|
|
1451
|
-
* @param {string} code unified currency code
|
|
1452
|
-
* @param {float} amount the amount to withdraw
|
|
1453
|
-
* @param {string} address the address to withdraw to
|
|
1454
|
-
* @param {string} tag
|
|
1455
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1456
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1457
|
-
*/
|
|
1458
|
-
async withdraw(code, amount, address, tag = undefined, params = {}) {
|
|
1459
|
-
[tag, params] = this.handleWithdrawTagAndParams(tag, params);
|
|
1460
|
-
this.checkRequiredCredentials();
|
|
1461
|
-
await this.loadMarkets();
|
|
1462
|
-
const nonce = this.uuidv1();
|
|
1463
|
-
const amountString = this.currencyToPrecision(code, amount);
|
|
1464
|
-
const currency = this.currency(code);
|
|
1465
|
-
const walletBytes = this.remove0xPrefix(this.walletAddress);
|
|
1466
|
-
const byteArray = [
|
|
1467
|
-
this.base16ToBinary(nonce),
|
|
1468
|
-
this.base16ToBinary(walletBytes),
|
|
1469
|
-
this.encode(currency['id']),
|
|
1470
|
-
this.encode(amountString),
|
|
1471
|
-
this.numberToBE(1, 1), // bool set to true
|
|
1472
|
-
];
|
|
1473
|
-
const binary = this.binaryConcatArray(byteArray);
|
|
1474
|
-
const hash = this.hash(binary, keccak, 'hex');
|
|
1475
|
-
const signature = this.signMessageString(hash, this.privateKey);
|
|
1476
|
-
const request = {
|
|
1477
|
-
'parameters': {
|
|
1478
|
-
'nonce': nonce,
|
|
1479
|
-
'wallet': address,
|
|
1480
|
-
'asset': currency['id'],
|
|
1481
|
-
'quantity': amountString,
|
|
1482
|
-
},
|
|
1483
|
-
'signature': signature,
|
|
1484
|
-
};
|
|
1485
|
-
const response = await this.privatePostWithdrawals(request);
|
|
1486
|
-
//
|
|
1487
|
-
// {
|
|
1488
|
-
// "withdrawalId": "a61dcff0-ec4d-11ea-8b83-c78a6ecb3180",
|
|
1489
|
-
// "asset": "ETH",
|
|
1490
|
-
// "assetContractAddress": "0x0000000000000000000000000000000000000000",
|
|
1491
|
-
// "quantity": "0.20000000",
|
|
1492
|
-
// "time": 1598962883190,
|
|
1493
|
-
// "fee": "0.00024000",
|
|
1494
|
-
// "txStatus": "pending",
|
|
1495
|
-
// "txId": null
|
|
1496
|
-
// }
|
|
1497
|
-
//
|
|
1498
|
-
return this.parseTransaction(response, currency);
|
|
1499
|
-
}
|
|
1500
|
-
/**
|
|
1501
|
-
* @method
|
|
1502
|
-
* @name idex#cancelAllOrders
|
|
1503
|
-
* @description cancel all open orders
|
|
1504
|
-
* @see https://api-docs-v3.idex.io/#cancel-order
|
|
1505
|
-
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
|
|
1506
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1507
|
-
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1508
|
-
*/
|
|
1509
|
-
async cancelAllOrders(symbol = undefined, params = {}) {
|
|
1510
|
-
this.checkRequiredCredentials();
|
|
1511
|
-
await this.loadMarkets();
|
|
1512
|
-
let market = undefined;
|
|
1513
|
-
if (symbol !== undefined) {
|
|
1514
|
-
market = this.market(symbol);
|
|
1515
|
-
}
|
|
1516
|
-
const nonce = this.uuidv1();
|
|
1517
|
-
const request = {
|
|
1518
|
-
'parameters': {
|
|
1519
|
-
'nonce': nonce,
|
|
1520
|
-
'wallet': this.walletAddress,
|
|
1521
|
-
},
|
|
1522
|
-
};
|
|
1523
|
-
const walletBytes = this.remove0xPrefix(this.walletAddress);
|
|
1524
|
-
const byteArray = [
|
|
1525
|
-
this.base16ToBinary(nonce),
|
|
1526
|
-
this.base16ToBinary(walletBytes),
|
|
1527
|
-
];
|
|
1528
|
-
if (market !== undefined) {
|
|
1529
|
-
byteArray.push(this.encode(market['id']));
|
|
1530
|
-
request['parameters']['market'] = market['id'];
|
|
1531
|
-
}
|
|
1532
|
-
const binary = this.binaryConcatArray(byteArray);
|
|
1533
|
-
const hash = this.hash(binary, keccak, 'hex');
|
|
1534
|
-
const signature = this.signMessageString(hash, this.privateKey);
|
|
1535
|
-
request['signature'] = signature;
|
|
1536
|
-
// [ { orderId: "688336f0-ec50-11ea-9842-b332f8a34d0e" } ]
|
|
1537
|
-
const response = await this.privateDeleteOrders(this.extend(request, params));
|
|
1538
|
-
return this.parseOrders(response, market);
|
|
1539
|
-
}
|
|
1540
|
-
/**
|
|
1541
|
-
* @method
|
|
1542
|
-
* @name idex#cancelOrder
|
|
1543
|
-
* @description cancels an open order
|
|
1544
|
-
* @see https://api-docs-v3.idex.io/#cancel-order
|
|
1545
|
-
* @param {string} id order id
|
|
1546
|
-
* @param {string} symbol unified symbol of the market the order was made in
|
|
1547
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1548
|
-
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
1549
|
-
*/
|
|
1550
|
-
async cancelOrder(id, symbol = undefined, params = {}) {
|
|
1551
|
-
this.checkRequiredCredentials();
|
|
1552
|
-
await this.loadMarkets();
|
|
1553
|
-
let market = undefined;
|
|
1554
|
-
if (symbol !== undefined) {
|
|
1555
|
-
market = this.market(symbol);
|
|
1556
|
-
}
|
|
1557
|
-
const nonce = this.uuidv1();
|
|
1558
|
-
const walletBytes = this.remove0xPrefix(this.walletAddress);
|
|
1559
|
-
const byteArray = [
|
|
1560
|
-
this.base16ToBinary(nonce),
|
|
1561
|
-
this.base16ToBinary(walletBytes),
|
|
1562
|
-
this.encode(id),
|
|
1563
|
-
];
|
|
1564
|
-
const binary = this.binaryConcatArray(byteArray);
|
|
1565
|
-
const hash = this.hash(binary, keccak, 'hex');
|
|
1566
|
-
const signature = this.signMessageString(hash, this.privateKey);
|
|
1567
|
-
const request = {
|
|
1568
|
-
'parameters': {
|
|
1569
|
-
'nonce': nonce,
|
|
1570
|
-
'wallet': this.walletAddress,
|
|
1571
|
-
'orderId': id,
|
|
1572
|
-
},
|
|
1573
|
-
'signature': signature,
|
|
1574
|
-
};
|
|
1575
|
-
// [ { orderId: "688336f0-ec50-11ea-9842-b332f8a34d0e" } ]
|
|
1576
|
-
const response = await this.privateDeleteOrders(this.extend(request, params));
|
|
1577
|
-
const canceledOrder = this.safeDict(response, 0);
|
|
1578
|
-
return this.parseOrder(canceledOrder, market);
|
|
1579
|
-
}
|
|
1580
|
-
handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
|
1581
|
-
const errorCode = this.safeString(response, 'code');
|
|
1582
|
-
const message = this.safeString(response, 'message');
|
|
1583
|
-
if (errorCode !== undefined) {
|
|
1584
|
-
this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, message);
|
|
1585
|
-
throw new ExchangeError(this.id + ' ' + message);
|
|
1586
|
-
}
|
|
1587
|
-
return undefined;
|
|
1588
|
-
}
|
|
1589
|
-
/**
|
|
1590
|
-
* @method
|
|
1591
|
-
* @name idex#fetchDeposit
|
|
1592
|
-
* @description fetch information on a deposit
|
|
1593
|
-
* @see https://api-docs-v3.idex.io/#get-deposits
|
|
1594
|
-
* @param {string} id deposit id
|
|
1595
|
-
* @param {string} code not used by idex fetchDeposit ()
|
|
1596
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1597
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1598
|
-
*/
|
|
1599
|
-
async fetchDeposit(id, code = undefined, params = {}) {
|
|
1600
|
-
await this.loadMarkets();
|
|
1601
|
-
const nonce = this.uuidv1();
|
|
1602
|
-
const request = {
|
|
1603
|
-
'nonce': nonce,
|
|
1604
|
-
'wallet': this.walletAddress,
|
|
1605
|
-
'depositId': id,
|
|
1606
|
-
};
|
|
1607
|
-
const response = await this.privateGetDeposits(this.extend(request, params));
|
|
1608
|
-
return this.parseTransaction(response);
|
|
1609
|
-
}
|
|
1610
|
-
/**
|
|
1611
|
-
* @method
|
|
1612
|
-
* @name idex#fetchDeposits
|
|
1613
|
-
* @description fetch all deposits made to an account
|
|
1614
|
-
* @see https://api-docs-v3.idex.io/#get-deposits
|
|
1615
|
-
* @param {string} code unified currency code
|
|
1616
|
-
* @param {int} [since] the earliest time in ms to fetch deposits for
|
|
1617
|
-
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
|
1618
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1619
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1620
|
-
*/
|
|
1621
|
-
async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1622
|
-
params = this.extend({
|
|
1623
|
-
'method': 'privateGetDeposits',
|
|
1624
|
-
}, params);
|
|
1625
|
-
return await this.fetchTransactionsHelper(code, since, limit, params);
|
|
1626
|
-
}
|
|
1627
|
-
/**
|
|
1628
|
-
* @method
|
|
1629
|
-
* @name idex#fetchStatus
|
|
1630
|
-
* @description the latest known information on the availability of the exchange API
|
|
1631
|
-
* @see https://api-docs-v3.idex.io/#get-ping
|
|
1632
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1633
|
-
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
|
|
1634
|
-
*/
|
|
1635
|
-
async fetchStatus(params = {}) {
|
|
1636
|
-
const response = await this.publicGetPing(params);
|
|
1637
|
-
return {
|
|
1638
|
-
'status': 'ok',
|
|
1639
|
-
'updated': undefined,
|
|
1640
|
-
'eta': undefined,
|
|
1641
|
-
'url': undefined,
|
|
1642
|
-
'info': response,
|
|
1643
|
-
};
|
|
1644
|
-
}
|
|
1645
|
-
/**
|
|
1646
|
-
* @method
|
|
1647
|
-
* @name idex#fetchTime
|
|
1648
|
-
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
1649
|
-
* @see https://api-docs-v3.idex.io/#get-time
|
|
1650
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1651
|
-
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
1652
|
-
*/
|
|
1653
|
-
async fetchTime(params = {}) {
|
|
1654
|
-
const response = await this.publicGetTime(params);
|
|
1655
|
-
//
|
|
1656
|
-
// { serverTime: "1655258263236" }
|
|
1657
|
-
//
|
|
1658
|
-
return this.safeInteger(response, 'serverTime');
|
|
1659
|
-
}
|
|
1660
|
-
/**
|
|
1661
|
-
* @method
|
|
1662
|
-
* @name idex#fetchWithdrawal
|
|
1663
|
-
* @description fetch data on a currency withdrawal via the withdrawal id
|
|
1664
|
-
* @see https://api-docs-v3.idex.io/#get-withdrawals
|
|
1665
|
-
* @param {string} id withdrawal id
|
|
1666
|
-
* @param {string} code not used by idex.fetchWithdrawal
|
|
1667
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1668
|
-
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1669
|
-
*/
|
|
1670
|
-
async fetchWithdrawal(id, code = undefined, params = {}) {
|
|
1671
|
-
await this.loadMarkets();
|
|
1672
|
-
const nonce = this.uuidv1();
|
|
1673
|
-
const request = {
|
|
1674
|
-
'nonce': nonce,
|
|
1675
|
-
'wallet': this.walletAddress,
|
|
1676
|
-
'withdrawalId': id,
|
|
1677
|
-
};
|
|
1678
|
-
const response = await this.privateGetWithdrawals(this.extend(request, params));
|
|
1679
|
-
return this.parseTransaction(response);
|
|
1680
|
-
}
|
|
1681
|
-
/**
|
|
1682
|
-
* @method
|
|
1683
|
-
* @name idex#fetchWithdrawals
|
|
1684
|
-
* @description fetch all withdrawals made from an account
|
|
1685
|
-
* @see https://api-docs-v3.idex.io/#get-withdrawals
|
|
1686
|
-
* @param {string} code unified currency code
|
|
1687
|
-
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
|
1688
|
-
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
|
1689
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1690
|
-
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
|
1691
|
-
*/
|
|
1692
|
-
async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1693
|
-
params = this.extend({
|
|
1694
|
-
'method': 'privateGetWithdrawals',
|
|
1695
|
-
}, params);
|
|
1696
|
-
return await this.fetchTransactionsHelper(code, since, limit, params);
|
|
1697
|
-
}
|
|
1698
|
-
async fetchTransactionsHelper(code = undefined, since = undefined, limit = undefined, params = {}) {
|
|
1699
|
-
await this.loadMarkets();
|
|
1700
|
-
const nonce = this.uuidv1();
|
|
1701
|
-
const request = {
|
|
1702
|
-
'nonce': nonce,
|
|
1703
|
-
'wallet': this.walletAddress,
|
|
1704
|
-
};
|
|
1705
|
-
let currency = undefined;
|
|
1706
|
-
if (code !== undefined) {
|
|
1707
|
-
currency = this.currency(code);
|
|
1708
|
-
request['asset'] = currency['id'];
|
|
1709
|
-
}
|
|
1710
|
-
if (since !== undefined) {
|
|
1711
|
-
request['start'] = since;
|
|
1712
|
-
}
|
|
1713
|
-
if (limit !== undefined) {
|
|
1714
|
-
request['limit'] = limit;
|
|
1715
|
-
}
|
|
1716
|
-
// [
|
|
1717
|
-
// {
|
|
1718
|
-
// "depositId": "e9970cc0-eb6b-11ea-9e89-09a5ebc1f98e",
|
|
1719
|
-
// "asset": "ETH",
|
|
1720
|
-
// "quantity": "1.00000000",
|
|
1721
|
-
// "txId": "0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142",
|
|
1722
|
-
// "txTime": 1598865853000,
|
|
1723
|
-
// "confirmationTime": 1598865930231
|
|
1724
|
-
// }
|
|
1725
|
-
// ]
|
|
1726
|
-
const method = params['method'];
|
|
1727
|
-
params = this.omit(params, 'method');
|
|
1728
|
-
let response = undefined;
|
|
1729
|
-
if (method === 'privateGetDeposits') {
|
|
1730
|
-
response = await this.privateGetDeposits(this.extend(request, params));
|
|
1731
|
-
}
|
|
1732
|
-
else if (method === 'privateGetWithdrawals') {
|
|
1733
|
-
response = await this.privateGetWithdrawals(this.extend(request, params));
|
|
1734
|
-
}
|
|
1735
|
-
else {
|
|
1736
|
-
throw new NotSupported(this.id + ' fetchTransactionsHelper() not support this method');
|
|
1737
|
-
}
|
|
1738
|
-
return this.parseTransactions(response, currency, since, limit);
|
|
1739
|
-
}
|
|
1740
|
-
parseTransactionStatus(status) {
|
|
1741
|
-
const statuses = {
|
|
1742
|
-
'mined': 'ok',
|
|
1743
|
-
};
|
|
1744
|
-
return this.safeString(statuses, status, status);
|
|
1745
|
-
}
|
|
1746
|
-
parseTransaction(transaction, currency = undefined) {
|
|
1747
|
-
//
|
|
1748
|
-
// fetchDeposits
|
|
1749
|
-
//
|
|
1750
|
-
// {
|
|
1751
|
-
// "depositId": "e9970cc0-eb6b-11ea-9e89-09a5ebc1f98f",
|
|
1752
|
-
// "asset": "ETH",
|
|
1753
|
-
// "quantity": "1.00000000",
|
|
1754
|
-
// "txId": "0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142",
|
|
1755
|
-
// "txTime": 1598865853000,
|
|
1756
|
-
// "confirmationTime": 1598865930231
|
|
1757
|
-
// }
|
|
1758
|
-
//
|
|
1759
|
-
// fetchWithdrwalas
|
|
1760
|
-
//
|
|
1761
|
-
// {
|
|
1762
|
-
// "withdrawalId": "a62d8760-ec4d-11ea-9fa6-47904c19499b",
|
|
1763
|
-
// "asset": "ETH",
|
|
1764
|
-
// "assetContractAddress": "0x0000000000000000000000000000000000000000",
|
|
1765
|
-
// "quantity": "0.20000000",
|
|
1766
|
-
// "time": 1598962883288,
|
|
1767
|
-
// "fee": "0.00024000",
|
|
1768
|
-
// "txId": "0x305e9cdbaa85ad029f50578d13d31d777c085de573ed5334d95c19116d8c03ce",
|
|
1769
|
-
// "txStatus": "mined"
|
|
1770
|
-
// }
|
|
1771
|
-
//
|
|
1772
|
-
// withdraw
|
|
1773
|
-
//
|
|
1774
|
-
// {
|
|
1775
|
-
// "withdrawalId": "a61dcff0-ec4d-11ea-8b83-c78a6ecb3180",
|
|
1776
|
-
// "asset": "ETH",
|
|
1777
|
-
// "assetContractAddress": "0x0000000000000000000000000000000000000000",
|
|
1778
|
-
// "quantity": "0.20000000",
|
|
1779
|
-
// "time": 1598962883190,
|
|
1780
|
-
// "fee": "0.00024000",
|
|
1781
|
-
// "txStatus": "pending",
|
|
1782
|
-
// "txId": null
|
|
1783
|
-
// }
|
|
1784
|
-
//
|
|
1785
|
-
let type = undefined;
|
|
1786
|
-
if ('depositId' in transaction) {
|
|
1787
|
-
type = 'deposit';
|
|
1788
|
-
}
|
|
1789
|
-
else if (('withdrawId' in transaction) || ('withdrawalId' in transaction)) {
|
|
1790
|
-
type = 'withdrawal';
|
|
1791
|
-
}
|
|
1792
|
-
let id = this.safeString2(transaction, 'depositId', 'withdrawId');
|
|
1793
|
-
id = this.safeString(transaction, 'withdrawalId', id);
|
|
1794
|
-
const code = this.safeCurrencyCode(this.safeString(transaction, 'asset'), currency);
|
|
1795
|
-
const amount = this.safeNumber(transaction, 'quantity');
|
|
1796
|
-
const txid = this.safeString(transaction, 'txId');
|
|
1797
|
-
const timestamp = this.safeInteger2(transaction, 'txTime', 'time');
|
|
1798
|
-
let fee = undefined;
|
|
1799
|
-
if ('fee' in transaction) {
|
|
1800
|
-
fee = {
|
|
1801
|
-
'cost': this.safeNumber(transaction, 'fee'),
|
|
1802
|
-
'currency': 'ETH',
|
|
1803
|
-
};
|
|
1804
|
-
}
|
|
1805
|
-
const rawStatus = this.safeString(transaction, 'txStatus');
|
|
1806
|
-
const status = this.parseTransactionStatus(rawStatus);
|
|
1807
|
-
const updated = this.safeInteger(transaction, 'confirmationTime');
|
|
1808
|
-
return {
|
|
1809
|
-
'info': transaction,
|
|
1810
|
-
'id': id,
|
|
1811
|
-
'txid': txid,
|
|
1812
|
-
'timestamp': timestamp,
|
|
1813
|
-
'datetime': this.iso8601(timestamp),
|
|
1814
|
-
'network': undefined,
|
|
1815
|
-
'address': undefined,
|
|
1816
|
-
'addressTo': undefined,
|
|
1817
|
-
'addressFrom': undefined,
|
|
1818
|
-
'tag': undefined,
|
|
1819
|
-
'tagTo': undefined,
|
|
1820
|
-
'tagFrom': undefined,
|
|
1821
|
-
'type': type,
|
|
1822
|
-
'amount': amount,
|
|
1823
|
-
'currency': code,
|
|
1824
|
-
'status': status,
|
|
1825
|
-
'updated': updated,
|
|
1826
|
-
'comment': undefined,
|
|
1827
|
-
'internal': undefined,
|
|
1828
|
-
'fee': fee,
|
|
1829
|
-
};
|
|
1830
|
-
}
|
|
1831
|
-
calculateRateLimiterCost(api, method, path, params, config = {}) {
|
|
1832
|
-
const hasApiKey = (this.apiKey !== undefined);
|
|
1833
|
-
const hasSecret = (this.secret !== undefined);
|
|
1834
|
-
const hasWalletAddress = (this.walletAddress !== undefined);
|
|
1835
|
-
const hasPrivateKey = (this.privateKey !== undefined);
|
|
1836
|
-
const defaultCost = this.safeValue(config, 'cost', 1);
|
|
1837
|
-
const authenticated = hasApiKey && hasSecret && hasWalletAddress && hasPrivateKey;
|
|
1838
|
-
return authenticated ? (defaultCost / 2) : defaultCost;
|
|
1839
|
-
}
|
|
1840
|
-
/**
|
|
1841
|
-
* @method
|
|
1842
|
-
* @name idex#fetchDepositAddress
|
|
1843
|
-
* @description fetch the Polygon address of the wallet
|
|
1844
|
-
* @see https://api-docs-v3.idex.io/#get-wallets
|
|
1845
|
-
* @param {string} code not used by idex
|
|
1846
|
-
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
1847
|
-
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
1848
|
-
*/
|
|
1849
|
-
async fetchDepositAddress(code, params = {}) {
|
|
1850
|
-
const request = {};
|
|
1851
|
-
request['nonce'] = this.uuidv1();
|
|
1852
|
-
const response = await this.privateGetWallets(this.extend(request, params));
|
|
1853
|
-
//
|
|
1854
|
-
// [
|
|
1855
|
-
// {
|
|
1856
|
-
// address: "0x37A1827CA64C94A26028bDCb43FBDCB0bf6DAf5B",
|
|
1857
|
-
// totalPortfolioValueUsd: "0.00",
|
|
1858
|
-
// time: "1678342148086"
|
|
1859
|
-
// },
|
|
1860
|
-
// {
|
|
1861
|
-
// address: "0x0Ef3456E616552238B0c562d409507Ed6051A7b3",
|
|
1862
|
-
// totalPortfolioValueUsd: "15.90",
|
|
1863
|
-
// time: "1691697811659"
|
|
1864
|
-
// }
|
|
1865
|
-
// ]
|
|
1866
|
-
//
|
|
1867
|
-
return this.parseDepositAddress(response);
|
|
1868
|
-
}
|
|
1869
|
-
parseDepositAddress(depositAddress, currency = undefined) {
|
|
1870
|
-
//
|
|
1871
|
-
// [
|
|
1872
|
-
// {
|
|
1873
|
-
// address: "0x37A1827CA64C94A26028bDCb43FBDCB0bf6DAf5B",
|
|
1874
|
-
// totalPortfolioValueUsd: "0.00",
|
|
1875
|
-
// time: "1678342148086"
|
|
1876
|
-
// },
|
|
1877
|
-
// {
|
|
1878
|
-
// address: "0x0Ef3456E616552238B0c562d409507Ed6051A7b3",
|
|
1879
|
-
// totalPortfolioValueUsd: "15.90",
|
|
1880
|
-
// time: "1691697811659"
|
|
1881
|
-
// }
|
|
1882
|
-
// ]
|
|
1883
|
-
//
|
|
1884
|
-
const length = depositAddress.length;
|
|
1885
|
-
const entry = this.safeDict(depositAddress, length - 1);
|
|
1886
|
-
const address = this.safeString(entry, 'address');
|
|
1887
|
-
this.checkAddress(address);
|
|
1888
|
-
return {
|
|
1889
|
-
'info': depositAddress,
|
|
1890
|
-
'currency': undefined,
|
|
1891
|
-
'network': 'MATIC',
|
|
1892
|
-
'address': address,
|
|
1893
|
-
'tag': undefined,
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
|
1897
|
-
const network = this.safeString(this.options, 'network', 'ETH');
|
|
1898
|
-
const version = this.safeString(this.options, 'version', 'v1');
|
|
1899
|
-
let url = this.urls['api'][network] + '/' + version + '/' + path;
|
|
1900
|
-
const keys = Object.keys(params);
|
|
1901
|
-
const length = keys.length;
|
|
1902
|
-
let query = undefined;
|
|
1903
|
-
if (length > 0) {
|
|
1904
|
-
if (method === 'GET') {
|
|
1905
|
-
query = this.urlencode(params);
|
|
1906
|
-
url = url + '?' + query;
|
|
1907
|
-
}
|
|
1908
|
-
else {
|
|
1909
|
-
body = this.json(params);
|
|
1910
|
-
}
|
|
1911
|
-
}
|
|
1912
|
-
headers = {
|
|
1913
|
-
'Content-Type': 'application/json',
|
|
1914
|
-
};
|
|
1915
|
-
if (this.apiKey !== undefined) {
|
|
1916
|
-
headers['IDEX-API-Key'] = this.apiKey;
|
|
1917
|
-
}
|
|
1918
|
-
if (api === 'private') {
|
|
1919
|
-
let payload = undefined;
|
|
1920
|
-
if (method === 'GET') {
|
|
1921
|
-
payload = query;
|
|
1922
|
-
}
|
|
1923
|
-
else {
|
|
1924
|
-
payload = body;
|
|
1925
|
-
}
|
|
1926
|
-
headers['IDEX-HMAC-Signature'] = this.hmac(this.encode(payload), this.encode(this.secret), sha256, 'hex');
|
|
1927
|
-
}
|
|
1928
|
-
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
|
1929
|
-
}
|
|
1930
|
-
remove0xPrefix(hexData) {
|
|
1931
|
-
if (hexData.slice(0, 2) === '0x') {
|
|
1932
|
-
return hexData.slice(2);
|
|
1933
|
-
}
|
|
1934
|
-
else {
|
|
1935
|
-
return hexData;
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
hashMessage(message) {
|
|
1939
|
-
// takes a hex encoded message
|
|
1940
|
-
const binaryMessage = this.base16ToBinary(this.remove0xPrefix(message));
|
|
1941
|
-
const prefix = this.encode('\x19Ethereum Signed Message:\n' + binaryMessage.byteLength);
|
|
1942
|
-
return '0x' + this.hash(this.binaryConcat(prefix, binaryMessage), keccak, 'hex');
|
|
1943
|
-
}
|
|
1944
|
-
signHash(hash, privateKey) {
|
|
1945
|
-
const signature = ecdsa(hash.slice(-64), privateKey.slice(-64), secp256k1, undefined);
|
|
1946
|
-
return {
|
|
1947
|
-
'r': '0x' + signature['r'],
|
|
1948
|
-
's': '0x' + signature['s'],
|
|
1949
|
-
'v': 27 + signature['v'],
|
|
1950
|
-
};
|
|
1951
|
-
}
|
|
1952
|
-
signMessage(message, privateKey) {
|
|
1953
|
-
return this.signHash(this.hashMessage(message), privateKey.slice(-64));
|
|
1954
|
-
}
|
|
1955
|
-
signMessageString(message, privateKey) {
|
|
1956
|
-
// still takes the input as a hex string
|
|
1957
|
-
// same as above but returns a string instead of an object
|
|
1958
|
-
const signature = this.signMessage(message, privateKey);
|
|
1959
|
-
return signature['r'] + this.remove0xPrefix(signature['s']) + this.binaryToBase16(this.numberToBE(signature['v'], 1));
|
|
1960
|
-
}
|
|
1961
|
-
}
|