ccxt-look 1.81.50

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.
Files changed (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
package/js/idex.js ADDED
@@ -0,0 +1,1439 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { PAD_WITH_ZERO } = require ('./base/functions/number');
7
+ const { InvalidOrder, InsufficientFunds, ExchangeError, ExchangeNotAvailable, DDoSProtection, BadRequest, NotSupported, InvalidAddress, AuthenticationError } = require ('./base/errors');
8
+ const Precise = require ('./base/Precise');
9
+
10
+ // ---------------------------------------------------------------------------
11
+
12
+ module.exports = class idex extends Exchange {
13
+ describe () {
14
+ return this.deepExtend (super.describe (), {
15
+ 'id': 'idex',
16
+ 'name': 'IDEX',
17
+ 'countries': [ 'US' ],
18
+ // public data endpoints 5 requests a second => 1000ms / 5 = 200ms between requests roughly (without Authentication)
19
+ // all endpoints 10 requests a second => (1000ms / rateLimit) / 10 => 1 / 2 (with Authentication)
20
+ 'rateLimit': 200,
21
+ 'version': 'v3',
22
+ 'pro': true,
23
+ 'certified': true,
24
+ 'requiresWeb3': true,
25
+ 'has': {
26
+ 'CORS': undefined,
27
+ 'spot': true,
28
+ 'margin': false,
29
+ 'swap': false,
30
+ 'future': false,
31
+ 'option': false,
32
+ 'addMargin': false,
33
+ 'cancelOrder': true,
34
+ 'createOrder': true,
35
+ 'createReduceOnlyOrder': false,
36
+ 'createStopLimitOrder': true,
37
+ 'createStopMarketOrder': true,
38
+ 'createStopOrder': true,
39
+ 'fetchBalance': true,
40
+ 'fetchBorrowRate': false,
41
+ 'fetchBorrowRateHistories': false,
42
+ 'fetchBorrowRateHistory': false,
43
+ 'fetchBorrowRates': false,
44
+ 'fetchBorrowRatesPerSymbol': false,
45
+ 'fetchClosedOrders': true,
46
+ 'fetchCurrencies': true,
47
+ 'fetchDeposits': true,
48
+ 'fetchFundingHistory': false,
49
+ 'fetchFundingRate': false,
50
+ 'fetchFundingRateHistory': false,
51
+ 'fetchFundingRates': false,
52
+ 'fetchIndexOHLCV': false,
53
+ 'fetchLeverage': false,
54
+ 'fetchLeverageTiers': false,
55
+ 'fetchMarkets': true,
56
+ 'fetchMarkOHLCV': false,
57
+ 'fetchMyTrades': true,
58
+ 'fetchOHLCV': true,
59
+ 'fetchOpenOrders': true,
60
+ 'fetchOrder': true,
61
+ 'fetchOrderBook': true,
62
+ 'fetchOrders': undefined,
63
+ 'fetchPosition': false,
64
+ 'fetchPositions': false,
65
+ 'fetchPositionsRisk': false,
66
+ 'fetchPremiumIndexOHLCV': false,
67
+ 'fetchTicker': true,
68
+ 'fetchTickers': true,
69
+ 'fetchTrades': true,
70
+ 'fetchTradingFee': false,
71
+ 'fetchTradingFees': true,
72
+ 'fetchTransactions': undefined,
73
+ 'fetchWithdrawals': true,
74
+ 'reduceMargin': false,
75
+ 'setLeverage': false,
76
+ 'setMarginMode': false,
77
+ 'setPositionMode': false,
78
+ 'transfer': false,
79
+ 'withdraw': true,
80
+ },
81
+ 'timeframes': {
82
+ '1m': '1m',
83
+ '5m': '5m',
84
+ '15m': '15m',
85
+ '30m': '30m',
86
+ '1h': '1h',
87
+ '6h': '6h',
88
+ '1d': '1d',
89
+ },
90
+ 'urls': {
91
+ 'test': {
92
+ 'MATIC': 'https://api-sandbox-matic.idex.io',
93
+ },
94
+ 'logo': 'https://user-images.githubusercontent.com/51840849/94481303-2f222100-01e0-11eb-97dd-bc14c5943a86.jpg',
95
+ 'api': {
96
+ 'MATIC': 'https://api-matic.idex.io',
97
+ },
98
+ 'www': 'https://idex.io',
99
+ 'doc': [
100
+ 'https://docs.idex.io/',
101
+ ],
102
+ },
103
+ 'api': {
104
+ 'public': {
105
+ 'get': {
106
+ 'ping': 1,
107
+ 'time': 1,
108
+ 'exchange': 1,
109
+ 'assets': 1,
110
+ 'markets': 1,
111
+ 'tickers': 1,
112
+ 'candles': 1,
113
+ 'trades': 1,
114
+ 'orderbook': 1,
115
+ },
116
+ },
117
+ 'private': {
118
+ 'get': {
119
+ 'user': 1,
120
+ 'wallets': 1,
121
+ 'balances': 1,
122
+ 'orders': 1,
123
+ 'fills': 1,
124
+ 'deposits': 1,
125
+ 'withdrawals': 1,
126
+ 'wsToken': 1,
127
+ },
128
+ 'post': {
129
+ 'wallets': 1,
130
+ 'orders': 1,
131
+ 'orders/test': 1,
132
+ 'withdrawals': 1,
133
+ },
134
+ 'delete': {
135
+ 'orders': 1,
136
+ },
137
+ },
138
+ },
139
+ 'options': {
140
+ 'defaultTimeInForce': 'gtc',
141
+ 'defaultSelfTradePrevention': 'cn',
142
+ 'network': 'MATIC',
143
+ },
144
+ 'exceptions': {
145
+ 'INVALID_ORDER_QUANTITY': InvalidOrder,
146
+ 'INSUFFICIENT_FUNDS': InsufficientFunds,
147
+ 'SERVICE_UNAVAILABLE': ExchangeNotAvailable,
148
+ 'EXCEEDED_RATE_LIMIT': DDoSProtection,
149
+ 'INVALID_PARAMETER': BadRequest,
150
+ 'WALLET_NOT_ASSOCIATED': InvalidAddress,
151
+ 'INVALID_WALLET_SIGNATURE': AuthenticationError,
152
+ },
153
+ 'requiredCredentials': {
154
+ 'walletAddress': true,
155
+ 'privateKey': true,
156
+ 'apiKey': true,
157
+ 'secret': true,
158
+ },
159
+ 'paddingMode': PAD_WITH_ZERO,
160
+ 'commonCurrencies': {},
161
+ });
162
+ }
163
+
164
+ async fetchMarkets (params = {}) {
165
+ const response = await this.publicGetMarkets (params);
166
+ //
167
+ // [
168
+ // {
169
+ // market: 'DIL-ETH',
170
+ // status: 'active',
171
+ // baseAsset: 'DIL',
172
+ // baseAssetPrecision: 8,
173
+ // quoteAsset: 'ETH',
174
+ // quoteAssetPrecision: 8
175
+ // }, ...
176
+ // ]
177
+ //
178
+ const response2 = await this.publicGetExchange ();
179
+ //
180
+ // {
181
+ // "timeZone": "UTC",
182
+ // "serverTime": 1590408000000,
183
+ // "ethereumDepositContractAddress": "0x...",
184
+ // "ethUsdPrice": "206.46",
185
+ // "gasPrice": 7,
186
+ // "volume24hUsd": "10416227.98",
187
+ // "makerFeeRate": "0.001",
188
+ // "takerFeeRate": "0.002",
189
+ // "makerTradeMinimum": "0.15000000",
190
+ // "takerTradeMinimum": "0.05000000",
191
+ // "withdrawalMinimum": "0.04000000"
192
+ // }
193
+ //
194
+ const maker = this.safeNumber (response2, 'makerFeeRate');
195
+ const taker = this.safeNumber (response2, 'takerFeeRate');
196
+ const makerMin = this.safeString (response2, 'makerTradeMinimum');
197
+ const takerMin = this.safeString (response2, 'takerTradeMinimum');
198
+ const minCostETH = this.parseNumber (Precise.stringMin (makerMin, takerMin));
199
+ const result = [];
200
+ for (let i = 0; i < response.length; i++) {
201
+ const entry = response[i];
202
+ const marketId = this.safeString (entry, 'market');
203
+ const baseId = this.safeString (entry, 'baseAsset');
204
+ const quoteId = this.safeString (entry, 'quoteAsset');
205
+ const base = this.safeCurrencyCode (baseId);
206
+ const quote = this.safeCurrencyCode (quoteId);
207
+ const basePrecisionString = this.safeString (entry, 'baseAssetPrecision');
208
+ const quotePrecisionString = this.safeString (entry, 'quoteAssetPrecision');
209
+ const basePrecision = this.parsePrecision (basePrecisionString);
210
+ const quotePrecision = this.parsePrecision (quotePrecisionString);
211
+ const status = this.safeString (entry, 'status');
212
+ let minCost = undefined;
213
+ if (quote === 'ETH') {
214
+ minCost = minCostETH;
215
+ }
216
+ result.push ({
217
+ 'id': marketId,
218
+ 'symbol': base + '/' + quote,
219
+ 'base': base,
220
+ 'quote': quote,
221
+ 'settle': undefined,
222
+ 'baseId': baseId,
223
+ 'quoteId': quoteId,
224
+ 'settleId': undefined,
225
+ 'type': 'spot',
226
+ 'spot': true,
227
+ 'margin': false,
228
+ 'swap': false,
229
+ 'future': false,
230
+ 'option': false,
231
+ 'active': (status === 'active'),
232
+ 'contract': false,
233
+ 'linear': undefined,
234
+ 'inverse': undefined,
235
+ 'taker': taker,
236
+ 'maker': maker,
237
+ 'contractSize': undefined,
238
+ 'expiry': undefined,
239
+ 'expiryDatetime': undefined,
240
+ 'strike': undefined,
241
+ 'optionType': undefined,
242
+ 'precision': {
243
+ 'amount': parseInt (basePrecisionString),
244
+ 'price': parseInt (quotePrecisionString),
245
+ },
246
+ 'limits': {
247
+ 'leverage': {
248
+ 'min': undefined,
249
+ 'max': undefined,
250
+ },
251
+ 'amount': {
252
+ 'min': this.parseNumber (basePrecision),
253
+ 'max': undefined,
254
+ },
255
+ 'price': {
256
+ 'min': this.parseNumber (quotePrecision),
257
+ 'max': undefined,
258
+ },
259
+ 'cost': {
260
+ 'min': minCost,
261
+ 'max': undefined,
262
+ },
263
+ },
264
+ 'info': entry,
265
+ });
266
+ }
267
+ return result;
268
+ }
269
+
270
+ async fetchTicker (symbol, params = {}) {
271
+ await this.loadMarkets ();
272
+ const market = this.market (symbol);
273
+ const request = {
274
+ 'market': market['id'],
275
+ };
276
+ // [
277
+ // {
278
+ // market: 'DIL-ETH',
279
+ // time: 1598367493008,
280
+ // open: '0.09695361',
281
+ // high: '0.10245881',
282
+ // low: '0.09572507',
283
+ // close: '0.09917079',
284
+ // closeQuantity: '0.71320950',
285
+ // baseVolume: '309.17380612',
286
+ // quoteVolume: '30.57633981',
287
+ // percentChange: '2.28',
288
+ // numTrades: 205,
289
+ // ask: '0.09910476',
290
+ // bid: '0.09688340',
291
+ // sequence: 3902
292
+ // }
293
+ // ]
294
+ const response = await this.publicGetTickers (this.extend (request, params));
295
+ const ticker = this.safeValue (response, 0);
296
+ return this.parseTicker (ticker, market);
297
+ }
298
+
299
+ async fetchTickers (symbols = undefined, params = {}) {
300
+ await this.loadMarkets ();
301
+ // [
302
+ // {
303
+ // market: 'DIL-ETH',
304
+ // time: 1598367493008,
305
+ // open: '0.09695361',
306
+ // high: '0.10245881',
307
+ // low: '0.09572507',
308
+ // close: '0.09917079',
309
+ // closeQuantity: '0.71320950',
310
+ // baseVolume: '309.17380612',
311
+ // quoteVolume: '30.57633981',
312
+ // percentChange: '2.28',
313
+ // numTrades: 205,
314
+ // ask: '0.09910476',
315
+ // bid: '0.09688340',
316
+ // sequence: 3902
317
+ // }, ...
318
+ // ]
319
+ const response = await this.publicGetTickers (params);
320
+ return this.parseTickers (response, symbols);
321
+ }
322
+
323
+ parseTicker (ticker, market = undefined) {
324
+ // {
325
+ // market: 'DIL-ETH',
326
+ // time: 1598367493008,
327
+ // open: '0.09695361',
328
+ // high: '0.10245881',
329
+ // low: '0.09572507',
330
+ // close: '0.09917079',
331
+ // closeQuantity: '0.71320950',
332
+ // baseVolume: '309.17380612',
333
+ // quoteVolume: '30.57633981',
334
+ // percentChange: '2.28',
335
+ // numTrades: 205,
336
+ // ask: '0.09910476',
337
+ // bid: '0.09688340',
338
+ // sequence: 3902
339
+ // }
340
+ const marketId = this.safeString (ticker, 'market');
341
+ market = this.safeMarket (marketId, market, '-');
342
+ const symbol = market['symbol'];
343
+ const timestamp = this.safeInteger (ticker, 'time');
344
+ const close = this.safeString (ticker, 'close');
345
+ return this.safeTicker ({
346
+ 'symbol': symbol,
347
+ 'timestamp': timestamp,
348
+ 'datetime': this.iso8601 (timestamp),
349
+ 'high': this.safeString (ticker, 'high'),
350
+ 'low': this.safeString (ticker, 'low'),
351
+ 'bid': this.safeString (ticker, 'bid'),
352
+ 'bidVolume': undefined,
353
+ 'ask': this.safeString (ticker, 'ask'),
354
+ 'askVolume': undefined,
355
+ 'vwap': undefined,
356
+ 'open': this.safeString (ticker, 'open'),
357
+ 'close': close,
358
+ 'last': close,
359
+ 'previousClose': undefined,
360
+ 'change': undefined,
361
+ 'percentage': this.safeString (ticker, 'percentChange'),
362
+ 'average': undefined,
363
+ 'baseVolume': this.safeString (ticker, 'baseVolume'),
364
+ 'quoteVolume': this.safeString (ticker, 'quoteVolume'),
365
+ 'info': ticker,
366
+ }, market, false);
367
+ }
368
+
369
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
370
+ await this.loadMarkets ();
371
+ const market = this.market (symbol);
372
+ const request = {
373
+ 'market': market['id'],
374
+ 'interval': timeframe,
375
+ };
376
+ if (since !== undefined) {
377
+ request['start'] = since;
378
+ }
379
+ if (limit !== undefined) {
380
+ request['limit'] = limit;
381
+ }
382
+ const response = await this.publicGetCandles (this.extend (request, params));
383
+ if (Array.isArray (response)) {
384
+ // [
385
+ // {
386
+ // start: 1598345580000,
387
+ // open: '0.09771286',
388
+ // high: '0.09771286',
389
+ // low: '0.09771286',
390
+ // close: '0.09771286',
391
+ // volume: '1.45340410',
392
+ // sequence: 3853
393
+ // }, ...
394
+ // ]
395
+ return this.parseOHLCVs (response, market, timeframe, since, limit);
396
+ } else {
397
+ // {"nextTime":1595536440000}
398
+ return [];
399
+ }
400
+ }
401
+
402
+ parseOHLCV (ohlcv, market = undefined) {
403
+ // {
404
+ // start: 1598345580000,
405
+ // open: '0.09771286',
406
+ // high: '0.09771286',
407
+ // low: '0.09771286',
408
+ // close: '0.09771286',
409
+ // volume: '1.45340410',
410
+ // sequence: 3853
411
+ // }
412
+ const timestamp = this.safeInteger (ohlcv, 'start');
413
+ const open = this.safeNumber (ohlcv, 'open');
414
+ const high = this.safeNumber (ohlcv, 'high');
415
+ const low = this.safeNumber (ohlcv, 'low');
416
+ const close = this.safeNumber (ohlcv, 'close');
417
+ const volume = this.safeNumber (ohlcv, 'volume');
418
+ return [ timestamp, open, high, low, close, volume ];
419
+ }
420
+
421
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
422
+ await this.loadMarkets ();
423
+ const market = this.market (symbol);
424
+ const request = {
425
+ 'market': market['id'],
426
+ };
427
+ if (since !== undefined) {
428
+ request['start'] = since;
429
+ }
430
+ if (limit !== undefined) {
431
+ request['limit'] = limit;
432
+ }
433
+ // [
434
+ // {
435
+ // fillId: 'b5467d00-b13e-3fa9-8216-dd66735550fc',
436
+ // price: '0.09771286',
437
+ // quantity: '1.45340410',
438
+ // quoteQuantity: '0.14201627',
439
+ // time: 1598345638994,
440
+ // makerSide: 'buy',
441
+ // sequence: 3853
442
+ // }, ...
443
+ // ]
444
+ const response = await this.publicGetTrades (this.extend (request, params));
445
+ return this.parseTrades (response, market, since, limit);
446
+ }
447
+
448
+ parseTrade (trade, market = undefined) {
449
+ //
450
+ // public trades
451
+ // {
452
+ // "fillId":"a4883704-850b-3c4b-8588-020b5e4c62f1",
453
+ // "price":"0.20377008",
454
+ // "quantity":"47.58448728",
455
+ // "quoteQuantity":"9.69629509",
456
+ // "time":1642091300873,
457
+ // "makerSide":"buy",
458
+ // "type":"hybrid", // one of either: "orderBook", "hybrid", or "pool"
459
+ // "sequence":31876
460
+ // }
461
+ //
462
+ // private trades
463
+ // {
464
+ // "fillId":"83429066-9334-3582-b710-78858b2f0d6b",
465
+ // "price":"0.20717368",
466
+ // "quantity":"15.00000000",
467
+ // "quoteQuantity":"3.10760523",
468
+ // "orderBookQuantity":"0.00000003",
469
+ // "orderBookQuoteQuantity":"0.00000001",
470
+ // "poolQuantity":"14.99999997",
471
+ // "poolQuoteQuantity":"3.10760522",
472
+ // "time":1642083351215,
473
+ // "makerSide":"sell",
474
+ // "sequence":31795,
475
+ // "market":"IDEX-USDC",
476
+ // "orderId":"4fe993f0-747b-11ec-bd08-79d4a0b6e47c",
477
+ // "side":"buy",
478
+ // "fee":"0.03749989",
479
+ // "feeAsset":"IDEX",
480
+ // "gas":"0.40507261",
481
+ // "liquidity":"taker",
482
+ // "type":"hybrid",
483
+ // "txId":"0x69f6d82a762d12e3201efd0b3e9cc1969351e3c6ea3cf07c47c66bf24a459815",
484
+ // "txStatus":"mined"
485
+ // }
486
+ //
487
+ const id = this.safeString (trade, 'fillId');
488
+ const priceString = this.safeString (trade, 'price');
489
+ const amountString = this.safeString (trade, 'quantity');
490
+ const costString = this.safeString (trade, 'quoteQuantity');
491
+ const timestamp = this.safeInteger (trade, 'time');
492
+ const marketId = this.safeString (trade, 'market');
493
+ const symbol = this.safeSymbol (marketId, market, '-');
494
+ // this code handles the duality of public vs private trades
495
+ const makerSide = this.safeString (trade, 'makerSide');
496
+ const oppositeSide = (makerSide === 'buy') ? 'sell' : 'buy';
497
+ const side = this.safeString (trade, 'side', oppositeSide);
498
+ const takerOrMaker = this.safeString (trade, 'liquidity', 'taker');
499
+ const feeCostString = this.safeString (trade, 'fee');
500
+ let fee = undefined;
501
+ if (feeCostString !== undefined) {
502
+ const feeCurrencyId = this.safeString (trade, 'feeAsset');
503
+ fee = {
504
+ 'cost': feeCostString,
505
+ 'currency': this.safeCurrencyCode (feeCurrencyId),
506
+ };
507
+ }
508
+ const orderId = this.safeString (trade, 'orderId');
509
+ return this.safeTrade ({
510
+ 'info': trade,
511
+ 'timestamp': timestamp,
512
+ 'datetime': this.iso8601 (timestamp),
513
+ 'symbol': symbol,
514
+ 'id': id,
515
+ 'order': orderId,
516
+ 'type': 'limit',
517
+ 'side': side,
518
+ 'takerOrMaker': takerOrMaker,
519
+ 'price': priceString,
520
+ 'amount': amountString,
521
+ 'cost': costString,
522
+ 'fee': fee,
523
+ }, market);
524
+ }
525
+
526
+ async fetchTradingFees (params = {}) {
527
+ this.checkRequiredCredentials ();
528
+ await this.loadMarkets ();
529
+ const nonce = this.uuidv1 ();
530
+ const request = {
531
+ 'nonce': nonce,
532
+ };
533
+ let response = undefined;
534
+ response = await this.privateGetUser (this.extend (request, params));
535
+ //
536
+ // {
537
+ // depositEnabled: true,
538
+ // orderEnabled: true,
539
+ // cancelEnabled: true,
540
+ // withdrawEnabled: true,
541
+ // totalPortfolioValueUsd: '0.00',
542
+ // makerFeeRate: '0.0000',
543
+ // takerFeeRate: '0.0025',
544
+ // takerIdexFeeRate: '0.0005',
545
+ // takerLiquidityProviderFeeRate: '0.0020'
546
+ // }
547
+ //
548
+ const maker = this.safeNumber (response, 'makerFeeRate');
549
+ const taker = this.safeNumber (response, 'takerFeeRate');
550
+ const result = {};
551
+ for (let i = 0; i < this.symbols.length; i++) {
552
+ const symbol = this.symbols[i];
553
+ result[symbol] = {
554
+ 'info': response,
555
+ 'symbol': symbol,
556
+ 'maker': maker,
557
+ 'taker': taker,
558
+ 'percentage': true,
559
+ 'tierBased': false,
560
+ };
561
+ }
562
+ return result;
563
+ }
564
+
565
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
566
+ await this.loadMarkets ();
567
+ const market = this.market (symbol);
568
+ const request = {
569
+ 'market': market['id'],
570
+ 'level': 2,
571
+ };
572
+ if (limit !== undefined) {
573
+ request['limit'] = limit;
574
+ }
575
+ // {
576
+ // sequence: 36416753,
577
+ // bids: [
578
+ // [ '0.09672815', '8.22284267', 1 ],
579
+ // [ '0.09672814', '1.83685554', 1 ],
580
+ // [ '0.09672143', '4.10962617', 1 ],
581
+ // [ '0.09658884', '4.03863759', 1 ],
582
+ // [ '0.09653781', '3.35730684', 1 ],
583
+ // [ '0.09624660', '2.54163586', 1 ],
584
+ // [ '0.09617490', '1.93065030', 1 ]
585
+ // ],
586
+ // asks: [
587
+ // [ '0.09910476', '3.22840154', 1 ],
588
+ // [ '0.09940587', '3.39796593', 1 ],
589
+ // [ '0.09948189', '4.25088898', 1 ],
590
+ // [ '0.09958362', '2.42195784', 1 ],
591
+ // [ '0.09974393', '4.25234367', 1 ],
592
+ // [ '0.09995250', '3.40192141', 1 ]
593
+ // ]
594
+ // }
595
+ const response = await this.publicGetOrderbook (this.extend (request, params));
596
+ const nonce = this.safeInteger (response, 'sequence');
597
+ return {
598
+ 'symbol': symbol,
599
+ 'timestamp': undefined,
600
+ 'datetime': undefined,
601
+ 'nonce': nonce,
602
+ 'bids': this.parseSide (response, 'bids'),
603
+ 'asks': this.parseSide (response, 'asks'),
604
+ };
605
+ }
606
+
607
+ parseSide (book, side) {
608
+ const bookSide = this.safeValue (book, side, []);
609
+ const result = [];
610
+ for (let i = 0; i < bookSide.length; i++) {
611
+ const order = bookSide[i];
612
+ const price = this.safeNumber (order, 0);
613
+ const amount = this.safeNumber (order, 1);
614
+ const orderCount = this.safeInteger (order, 2);
615
+ result.push ([ price, amount, orderCount ]);
616
+ }
617
+ const descending = side === 'bids';
618
+ return this.sortBy (result, 0, descending);
619
+ }
620
+
621
+ async fetchCurrencies (params = {}) {
622
+ // [
623
+ // {
624
+ // name: 'Ether',
625
+ // symbol: 'ETH',
626
+ // contractAddress: '0x0000000000000000000000000000000000000000',
627
+ // assetDecimals: 18,
628
+ // exchangeDecimals: 8
629
+ // }, ..
630
+ // ]
631
+ const response = await this.publicGetAssets (params);
632
+ const result = {};
633
+ for (let i = 0; i < response.length; i++) {
634
+ const entry = response[i];
635
+ const name = this.safeString (entry, 'name');
636
+ const currencyId = this.safeString (entry, 'symbol');
637
+ const precisionString = this.safeString (entry, 'exchangeDecimals');
638
+ const code = this.safeCurrencyCode (currencyId);
639
+ const precision = this.parsePrecision (precisionString);
640
+ const lot = this.parseNumber (precision);
641
+ result[code] = {
642
+ 'id': currencyId,
643
+ 'code': code,
644
+ 'info': entry,
645
+ 'type': undefined,
646
+ 'name': name,
647
+ 'active': undefined,
648
+ 'deposit': undefined,
649
+ 'withdraw': undefined,
650
+ 'fee': undefined,
651
+ 'precision': parseInt (precisionString),
652
+ 'limits': {
653
+ 'amount': { 'min': lot, 'max': undefined },
654
+ 'withdraw': { 'min': lot, 'max': undefined },
655
+ },
656
+ };
657
+ }
658
+ return result;
659
+ }
660
+
661
+ parseBalance (response) {
662
+ const result = {
663
+ 'info': response,
664
+ 'timestamp': undefined,
665
+ 'datetime': undefined,
666
+ };
667
+ for (let i = 0; i < response.length; i++) {
668
+ const entry = response[i];
669
+ const currencyId = this.safeString (entry, 'asset');
670
+ const code = this.safeCurrencyCode (currencyId);
671
+ const account = this.account ();
672
+ account['total'] = this.safeString (entry, 'quantity');
673
+ account['free'] = this.safeString (entry, 'availableForTrade');
674
+ account['used'] = this.safeString (entry, 'locked');
675
+ result[code] = account;
676
+ }
677
+ return this.safeBalance (result);
678
+ }
679
+
680
+ async fetchBalance (params = {}) {
681
+ this.checkRequiredCredentials ();
682
+ await this.loadMarkets ();
683
+ const nonce1 = this.uuidv1 ();
684
+ const request = {
685
+ 'nonce': nonce1,
686
+ 'wallet': this.walletAddress,
687
+ };
688
+ // [
689
+ // {
690
+ // asset: 'DIL',
691
+ // quantity: '0.00000000',
692
+ // availableForTrade: '0.00000000',
693
+ // locked: '0.00000000',
694
+ // usdValue: null
695
+ // }, ...
696
+ // ]
697
+ const extendedRequest = this.extend (request, params);
698
+ if (extendedRequest['wallet'] === undefined) {
699
+ throw new BadRequest (this.id + ' fetchBalance() wallet is undefined, set this.walletAddress or "address" in params');
700
+ }
701
+ let response = undefined;
702
+ try {
703
+ response = await this.privateGetBalances (extendedRequest);
704
+ } catch (e) {
705
+ if (e instanceof InvalidAddress) {
706
+ const walletAddress = extendedRequest['wallet'];
707
+ await this.associateWallet (walletAddress);
708
+ response = await this.privateGetBalances (extendedRequest);
709
+ } else {
710
+ throw e;
711
+ }
712
+ }
713
+ return this.parseBalance (response);
714
+ }
715
+
716
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
717
+ this.checkRequiredCredentials ();
718
+ await this.loadMarkets ();
719
+ let market = undefined;
720
+ const request = {
721
+ 'nonce': this.uuidv1 (),
722
+ 'wallet': this.walletAddress,
723
+ };
724
+ if (symbol !== undefined) {
725
+ market = this.market (symbol);
726
+ request['market'] = market['id'];
727
+ }
728
+ if (since !== undefined) {
729
+ request['start'] = since;
730
+ }
731
+ if (limit !== undefined) {
732
+ request['limit'] = limit;
733
+ }
734
+ // [
735
+ // {
736
+ // fillId: '48582d10-b9bb-3c4b-94d3-e67537cf2472',
737
+ // price: '0.09905990',
738
+ // quantity: '0.40000000',
739
+ // quoteQuantity: '0.03962396',
740
+ // time: 1598873478762,
741
+ // makerSide: 'sell',
742
+ // sequence: 5053,
743
+ // market: 'DIL-ETH',
744
+ // orderId: '7cdc8e90-eb7d-11ea-9e60-4118569f6e63',
745
+ // side: 'buy',
746
+ // fee: '0.00080000',
747
+ // feeAsset: 'DIL',
748
+ // gas: '0.00857497',
749
+ // liquidity: 'taker',
750
+ // txId: '0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65',
751
+ // txStatus: 'mined'
752
+ // }
753
+ // ]
754
+ const extendedRequest = this.extend (request, params);
755
+ if (extendedRequest['wallet'] === undefined) {
756
+ throw new BadRequest (this.id + ' fetchMyTrades() walletAddress is undefined, set this.walletAddress or "address" in params');
757
+ }
758
+ let response = undefined;
759
+ try {
760
+ response = await this.privateGetFills (extendedRequest);
761
+ } catch (e) {
762
+ if (e instanceof InvalidAddress) {
763
+ const walletAddress = extendedRequest['wallet'];
764
+ await this.associateWallet (walletAddress);
765
+ response = await this.privateGetFills (extendedRequest);
766
+ } else {
767
+ throw e;
768
+ }
769
+ }
770
+ return this.parseTrades (response, market, since, limit);
771
+ }
772
+
773
+ async fetchOrder (id, symbol = undefined, params = {}) {
774
+ const request = {
775
+ 'orderId': id,
776
+ };
777
+ return await this.fetchOrdersHelper (symbol, undefined, undefined, this.extend (request, params));
778
+ }
779
+
780
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
781
+ const request = {
782
+ 'closed': false,
783
+ };
784
+ return await this.fetchOrdersHelper (symbol, since, limit, this.extend (request, params));
785
+ }
786
+
787
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
788
+ const request = {
789
+ 'closed': true,
790
+ };
791
+ return await this.fetchOrdersHelper (symbol, since, limit, this.extend (request, params));
792
+ }
793
+
794
+ async fetchOrdersHelper (symbol = undefined, since = undefined, limit = undefined, params = {}) {
795
+ await this.loadMarkets ();
796
+ const request = {
797
+ 'nonce': this.uuidv1 (),
798
+ 'wallet': this.walletAddress,
799
+ };
800
+ let market = undefined;
801
+ if (symbol !== undefined) {
802
+ market = this.market (symbol);
803
+ request['market'] = market['id'];
804
+ }
805
+ if (since !== undefined) {
806
+ request['start'] = since;
807
+ }
808
+ if (limit !== undefined) {
809
+ request['limit'] = limit;
810
+ }
811
+ const response = await this.privateGetOrders (this.extend (request, params));
812
+ // fetchClosedOrders / fetchOpenOrders
813
+ // [
814
+ // {
815
+ // "market": "DIL-ETH",
816
+ // "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
817
+ // "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
818
+ // "time": 1598873478650,
819
+ // "status": "filled",
820
+ // "type": "limit",
821
+ // "side": "buy",
822
+ // "originalQuantity": "0.40000000",
823
+ // "executedQuantity": "0.40000000",
824
+ // "cumulativeQuoteQuantity": "0.03962396",
825
+ // "avgExecutionPrice": "0.09905990",
826
+ // "price": "1.00000000",
827
+ // "fills": [
828
+ // {
829
+ // "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
830
+ // "price": "0.09905990",
831
+ // "quantity": "0.40000000",
832
+ // "quoteQuantity": "0.03962396",
833
+ // "time": 1598873478650,
834
+ // "makerSide": "sell",
835
+ // "sequence": 5053,
836
+ // "fee": "0.00080000",
837
+ // "feeAsset": "DIL",
838
+ // "gas": "0.00857497",
839
+ // "liquidity": "taker",
840
+ // "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
841
+ // "txStatus": "mined"
842
+ // }
843
+ // ]
844
+ // }
845
+ // ]
846
+ // fetchOrder
847
+ // { market: 'DIL-ETH',
848
+ // orderId: '7cdc8e90-eb7d-11ea-9e60-4118569f6e63',
849
+ // wallet: '0x0AB991497116f7F5532a4c2f4f7B1784488628e1',
850
+ // time: 1598873478650,
851
+ // status: 'filled',
852
+ // type: 'limit',
853
+ // side: 'buy',
854
+ // originalQuantity: '0.40000000',
855
+ // executedQuantity: '0.40000000',
856
+ // cumulativeQuoteQuantity: '0.03962396',
857
+ // avgExecutionPrice: '0.09905990',
858
+ // price: '1.00000000',
859
+ // fills:
860
+ // [ { fillId: '48582d10-b9bb-3c4b-94d3-e67537cf2472',
861
+ // price: '0.09905990',
862
+ // quantity: '0.40000000',
863
+ // quoteQuantity: '0.03962396',
864
+ // time: 1598873478650,
865
+ // makerSide: 'sell',
866
+ // sequence: 5053,
867
+ // fee: '0.00080000',
868
+ // feeAsset: 'DIL',
869
+ // gas: '0.00857497',
870
+ // liquidity: 'taker',
871
+ // txId: '0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65',
872
+ // txStatus: 'mined' } ] }
873
+ if (Array.isArray (response)) {
874
+ return this.parseOrders (response, market, since, limit);
875
+ } else {
876
+ return this.parseOrder (response, market);
877
+ }
878
+ }
879
+
880
+ parseOrderStatus (status) {
881
+ // https://docs.idex.io/#order-states-amp-lifecycle
882
+ const statuses = {
883
+ 'active': 'open',
884
+ 'partiallyFilled': 'open',
885
+ 'rejected': 'canceled',
886
+ 'filled': 'closed',
887
+ };
888
+ return this.safeString (statuses, status, status);
889
+ }
890
+
891
+ parseOrder (order, market = undefined) {
892
+ //
893
+ // {
894
+ // "market": "DIL-ETH",
895
+ // "orderId": "7cdc8e90-eb7d-11ea-9e60-4118569f6e63",
896
+ // "wallet": "0x0AB991497116f7F5532a4c2f4f7B1784488628e1",
897
+ // "time": 1598873478650,
898
+ // "status": "filled",
899
+ // "type": "limit",
900
+ // "side": "buy",
901
+ // "originalQuantity": "0.40000000",
902
+ // "executedQuantity": "0.40000000",
903
+ // "cumulativeQuoteQuantity": "0.03962396",
904
+ // "avgExecutionPrice": "0.09905990",
905
+ // "price": "1.00000000",
906
+ // "fills": [
907
+ // {
908
+ // "fillId": "48582d10-b9bb-3c4b-94d3-e67537cf2472",
909
+ // "price": "0.09905990",
910
+ // "quantity": "0.40000000",
911
+ // "quoteQuantity": "0.03962396",
912
+ // "time": 1598873478650,
913
+ // "makerSide": "sell",
914
+ // "sequence": 5053,
915
+ // "fee": "0.00080000",
916
+ // "feeAsset": "DIL",
917
+ // "gas": "0.00857497",
918
+ // "liquidity": "taker",
919
+ // "txId": "0xeaa02b112c0b8b61bc02fa1776a2b39d6c614e287c1af90df0a2e591da573e65",
920
+ // "txStatus": "mined"
921
+ // }
922
+ // ]
923
+ // }
924
+ //
925
+ const timestamp = this.safeInteger (order, 'time');
926
+ const fills = this.safeValue (order, 'fills', []);
927
+ const id = this.safeString (order, 'orderId');
928
+ const clientOrderId = this.safeString (order, 'clientOrderId');
929
+ const marketId = this.safeString (order, 'market');
930
+ const side = this.safeString (order, 'side');
931
+ const symbol = this.safeSymbol (marketId, market, '-');
932
+ const type = this.safeString (order, 'type');
933
+ const amount = this.safeString (order, 'originalQuantity');
934
+ const filled = this.safeString (order, 'executedQuantity');
935
+ const average = this.safeString (order, 'avgExecutionPrice');
936
+ const price = this.safeString (order, 'price');
937
+ const rawStatus = this.safeString (order, 'status');
938
+ const timeInForce = this.safeStringUpper (order, 'timeInForce');
939
+ const status = this.parseOrderStatus (rawStatus);
940
+ return this.safeOrder ({
941
+ 'info': order,
942
+ 'id': id,
943
+ 'clientOrderId': clientOrderId,
944
+ 'timestamp': timestamp,
945
+ 'datetime': this.iso8601 (timestamp),
946
+ 'lastTradeTimestamp': undefined,
947
+ 'symbol': symbol,
948
+ 'type': type,
949
+ 'timeInForce': timeInForce,
950
+ 'postOnly': undefined,
951
+ 'side': side,
952
+ 'price': price,
953
+ 'stopPrice': undefined,
954
+ 'amount': amount,
955
+ 'cost': undefined,
956
+ 'average': average,
957
+ 'filled': filled,
958
+ 'remaining': undefined,
959
+ 'status': status,
960
+ 'fee': undefined,
961
+ 'trades': fills,
962
+ }, market);
963
+ }
964
+
965
+ async associateWallet (walletAddress, params = {}) {
966
+ const nonce = this.uuidv1 ();
967
+ const noPrefix = this.remove0xPrefix (walletAddress);
968
+ const byteArray = [
969
+ this.base16ToBinary (nonce),
970
+ this.base16ToBinary (noPrefix),
971
+ ];
972
+ const binary = this.binaryConcatArray (byteArray);
973
+ const hash = this.hash (binary, 'keccak', 'hex');
974
+ const signature = this.signMessageString (hash, this.privateKey);
975
+ // {
976
+ // address: '0x0AB991497116f7F5532a4c2f4f7B1784488628e1',
977
+ // totalPortfolioValueUsd: '0.00',
978
+ // time: 1598468353626
979
+ // }
980
+ const request = {
981
+ 'parameters': {
982
+ 'nonce': nonce,
983
+ 'wallet': walletAddress,
984
+ },
985
+ 'signature': signature,
986
+ };
987
+ const result = await this.privatePostWallets (request);
988
+ return result;
989
+ }
990
+
991
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
992
+ // https://docs.idex.io/#create-order
993
+ this.checkRequiredCredentials ();
994
+ await this.loadMarkets ();
995
+ const market = this.market (symbol);
996
+ const nonce = this.uuidv1 ();
997
+ let typeEnum = undefined;
998
+ const stopLossTypeEnums = {
999
+ 'stopLoss': 3,
1000
+ 'stopLossLimit': 4,
1001
+ 'takeProfit': 5,
1002
+ 'takeProfitLimit': 6,
1003
+ };
1004
+ let stopPriceString = undefined;
1005
+ if ((type === 'stopLossLimit') || (type === 'takeProfitLimit') || ('stopPrice' in params)) {
1006
+ if (!('stopPrice' in params)) {
1007
+ throw new BadRequest (this.id + ' createOrder() stopPrice is a required parameter for ' + type + 'orders');
1008
+ }
1009
+ stopPriceString = this.priceToPrecision (symbol, params['stopPrice']);
1010
+ }
1011
+ const limitTypeEnums = {
1012
+ 'limit': 1,
1013
+ 'limitMaker': 2,
1014
+ };
1015
+ let priceString = undefined;
1016
+ const typeLower = type.toLowerCase ();
1017
+ const limitOrder = typeLower.indexOf ('limit') >= 0;
1018
+ if (type in limitTypeEnums) {
1019
+ typeEnum = limitTypeEnums[type];
1020
+ priceString = this.priceToPrecision (symbol, price);
1021
+ } else if (type in stopLossTypeEnums) {
1022
+ typeEnum = stopLossTypeEnums[type];
1023
+ priceString = this.priceToPrecision (symbol, price);
1024
+ } else if (type === 'market') {
1025
+ typeEnum = 0;
1026
+ } else {
1027
+ throw new BadRequest (this.id + ' ' + type + ' is not a valid order type');
1028
+ }
1029
+ let amountEnum = 0; // base quantity
1030
+ if ('quoteOrderQuantity' in params) {
1031
+ if (type !== 'market') {
1032
+ throw new NotSupported (this.id + ' createOrder() quoteOrderQuantity is not supported for ' + type + ' orders, only supported for market orders');
1033
+ }
1034
+ amountEnum = 1;
1035
+ amount = this.safeNumber (params, 'quoteOrderQuantity');
1036
+ }
1037
+ const sideEnum = (side === 'buy') ? 0 : 1;
1038
+ const walletBytes = this.remove0xPrefix (this.walletAddress);
1039
+ const network = this.safeString (this.options, 'network', 'ETH');
1040
+ const orderVersion = this.getSupportedMapping (network, {
1041
+ 'ETH': 1,
1042
+ 'BSC': 2,
1043
+ 'MATIC': 4,
1044
+ });
1045
+ const amountString = this.amountToPrecision (symbol, amount);
1046
+ // https://docs.idex.io/#time-in-force
1047
+ const timeInForceEnums = {
1048
+ 'gtc': 0,
1049
+ 'ioc': 2,
1050
+ 'fok': 3,
1051
+ };
1052
+ const defaultTimeInForce = this.safeString (this.options, 'defaultTimeInForce', 'gtc');
1053
+ const timeInForce = this.safeString (params, 'timeInForce', defaultTimeInForce);
1054
+ let timeInForceEnum = undefined;
1055
+ if (timeInForce in timeInForceEnums) {
1056
+ timeInForceEnum = timeInForceEnums[timeInForce];
1057
+ } else {
1058
+ const allOptions = Object.keys (timeInForceEnums);
1059
+ const asString = allOptions.join (', ');
1060
+ throw new BadRequest (this.id + ' ' + timeInForce + ' is not a valid timeInForce, please choose one of ' + asString);
1061
+ }
1062
+ // https://docs.idex.io/#self-trade-prevention
1063
+ const selfTradePreventionEnums = {
1064
+ 'dc': 0,
1065
+ 'co': 1,
1066
+ 'cn': 2,
1067
+ 'cb': 3,
1068
+ };
1069
+ const defaultSelfTradePrevention = this.safeString (this.options, 'defaultSelfTradePrevention', 'cn');
1070
+ const selfTradePrevention = this.safeString (params, 'selfTradePrevention', defaultSelfTradePrevention);
1071
+ let selfTradePreventionEnum = undefined;
1072
+ if (selfTradePrevention in selfTradePreventionEnums) {
1073
+ selfTradePreventionEnum = selfTradePreventionEnums[selfTradePrevention];
1074
+ } else {
1075
+ const allOptions = Object.keys (selfTradePreventionEnums);
1076
+ const asString = allOptions.join (', ');
1077
+ throw new BadRequest (this.id + ' ' + selfTradePrevention + ' is not a valid selfTradePrevention, please choose one of ' + asString);
1078
+ }
1079
+ const byteArray = [
1080
+ this.numberToBE (orderVersion, 1),
1081
+ this.base16ToBinary (nonce),
1082
+ this.base16ToBinary (walletBytes),
1083
+ this.stringToBinary (this.encode (market['id'])), // TODO: refactor to remove either encode or stringToBinary
1084
+ this.numberToBE (typeEnum, 1),
1085
+ this.numberToBE (sideEnum, 1),
1086
+ this.stringToBinary (this.encode (amountString)),
1087
+ this.numberToBE (amountEnum, 1),
1088
+ ];
1089
+ if (limitOrder) {
1090
+ const encodedPrice = this.stringToBinary (this.encode (priceString));
1091
+ byteArray.push (encodedPrice);
1092
+ }
1093
+ if (type in stopLossTypeEnums) {
1094
+ const encodedPrice = this.stringToBinary (this.encode (stopPriceString || priceString));
1095
+ byteArray.push (encodedPrice);
1096
+ }
1097
+ const clientOrderId = this.safeString (params, 'clientOrderId');
1098
+ if (clientOrderId !== undefined) {
1099
+ byteArray.push (this.stringToBinary (this.encode (clientOrderId)));
1100
+ }
1101
+ const after = [
1102
+ this.numberToBE (timeInForceEnum, 1),
1103
+ this.numberToBE (selfTradePreventionEnum, 1),
1104
+ this.numberToBE (0, 8), // unused
1105
+ ];
1106
+ const allBytes = this.arrayConcat (byteArray, after);
1107
+ const binary = this.binaryConcatArray (allBytes);
1108
+ const hash = this.hash (binary, 'keccak', 'hex');
1109
+ const signature = this.signMessageString (hash, this.privateKey);
1110
+ const request = {
1111
+ 'parameters': {
1112
+ 'nonce': nonce,
1113
+ 'market': market['id'],
1114
+ 'side': side,
1115
+ 'type': type,
1116
+ 'wallet': this.walletAddress,
1117
+ 'selfTradePrevention': selfTradePrevention,
1118
+ },
1119
+ 'signature': signature,
1120
+ };
1121
+ if (type !== 'market') {
1122
+ request['parameters']['timeInForce'] = timeInForce;
1123
+ }
1124
+ if (limitOrder) {
1125
+ request['parameters']['price'] = priceString;
1126
+ }
1127
+ if (type in stopLossTypeEnums) {
1128
+ request['parameters']['stopPrice'] = stopPriceString || priceString;
1129
+ }
1130
+ if (amountEnum === 0) {
1131
+ request['parameters']['quantity'] = amountString;
1132
+ } else {
1133
+ request['parameters']['quoteOrderQuantity'] = amountString;
1134
+ }
1135
+ if (clientOrderId !== undefined) {
1136
+ request['parameters']['clientOrderId'] = clientOrderId;
1137
+ }
1138
+ // {
1139
+ // market: 'DIL-ETH',
1140
+ // orderId: '7cdc8e90-eb7d-11ea-9e60-4118569f6e63',
1141
+ // wallet: '0x0AB991497116f7F5532a4c2f4f7B1784488628e1',
1142
+ // time: 1598873478650,
1143
+ // status: 'filled',
1144
+ // type: 'limit',
1145
+ // side: 'buy',
1146
+ // originalQuantity: '0.40000000',
1147
+ // executedQuantity: '0.40000000',
1148
+ // cumulativeQuoteQuantity: '0.03962396',
1149
+ // price: '1.00000000',
1150
+ // fills: [
1151
+ // {
1152
+ // fillId: '48582d10-b9bb-3c4b-94d3-e67537cf2472',
1153
+ // price: '0.09905990',
1154
+ // quantity: '0.40000000',
1155
+ // quoteQuantity: '0.03962396',
1156
+ // time: 1598873478650,
1157
+ // makerSide: 'sell',
1158
+ // sequence: 5053,
1159
+ // fee: '0.00080000',
1160
+ // feeAsset: 'DIL',
1161
+ // gas: '0.00857497',
1162
+ // liquidity: 'taker',
1163
+ // txStatus: 'pending'
1164
+ // }
1165
+ // ],
1166
+ // avgExecutionPrice: '0.09905990'
1167
+ // }
1168
+ // we don't use extend here because it is a signed endpoint
1169
+ const response = await this.privatePostOrders (request);
1170
+ return this.parseOrder (response, market);
1171
+ }
1172
+
1173
+ async withdraw (code, amount, address, tag = undefined, params = {}) {
1174
+ [ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
1175
+ this.checkRequiredCredentials ();
1176
+ await this.loadMarkets ();
1177
+ const nonce = this.uuidv1 ();
1178
+ const amountString = this.currencyToPrecision (code, amount);
1179
+ const currency = this.currency (code);
1180
+ const walletBytes = this.remove0xPrefix (this.walletAddress);
1181
+ const byteArray = [
1182
+ this.base16ToBinary (nonce),
1183
+ this.base16ToBinary (walletBytes),
1184
+ this.stringToBinary (this.encode (currency['id'])),
1185
+ this.stringToBinary (this.encode (amountString)),
1186
+ this.numberToBE (1, 1), // bool set to true
1187
+ ];
1188
+ const binary = this.binaryConcatArray (byteArray);
1189
+ const hash = this.hash (binary, 'keccak', 'hex');
1190
+ const signature = this.signMessageString (hash, this.privateKey);
1191
+ const request = {
1192
+ 'parameters': {
1193
+ 'nonce': nonce,
1194
+ 'wallet': address,
1195
+ 'asset': currency['id'],
1196
+ 'quantity': amountString,
1197
+ },
1198
+ 'signature': signature,
1199
+ };
1200
+ const response = await this.privatePostWithdrawals (request);
1201
+ //
1202
+ // {
1203
+ // withdrawalId: 'a61dcff0-ec4d-11ea-8b83-c78a6ecb3180',
1204
+ // asset: 'ETH',
1205
+ // assetContractAddress: '0x0000000000000000000000000000000000000000',
1206
+ // quantity: '0.20000000',
1207
+ // time: 1598962883190,
1208
+ // fee: '0.00024000',
1209
+ // txStatus: 'pending',
1210
+ // txId: null
1211
+ // }
1212
+ //
1213
+ return this.parseTransaction (response, currency);
1214
+ }
1215
+
1216
+ async cancelOrder (id, symbol = undefined, params = {}) {
1217
+ this.checkRequiredCredentials ();
1218
+ await this.loadMarkets ();
1219
+ let market = undefined;
1220
+ if (symbol !== undefined) {
1221
+ market = this.market (symbol);
1222
+ }
1223
+ const nonce = this.uuidv1 ();
1224
+ const walletBytes = this.remove0xPrefix (this.walletAddress);
1225
+ const byteArray = [
1226
+ this.base16ToBinary (nonce),
1227
+ this.base16ToBinary (walletBytes),
1228
+ this.stringToBinary (this.encode (id)),
1229
+ ];
1230
+ const binary = this.binaryConcatArray (byteArray);
1231
+ const hash = this.hash (binary, 'keccak', 'hex');
1232
+ const signature = this.signMessageString (hash, this.privateKey);
1233
+ const request = {
1234
+ 'parameters': {
1235
+ 'nonce': nonce,
1236
+ 'wallet': this.walletAddress,
1237
+ 'orderId': id,
1238
+ },
1239
+ 'signature': signature,
1240
+ };
1241
+ // [ { orderId: '688336f0-ec50-11ea-9842-b332f8a34d0e' } ]
1242
+ const response = await this.privateDeleteOrders (this.extend (request, params));
1243
+ const canceledOrder = this.safeValue (response, 0);
1244
+ return this.parseOrder (canceledOrder, market);
1245
+ }
1246
+
1247
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1248
+ const errorCode = this.safeString (response, 'code');
1249
+ const message = this.safeString (response, 'message');
1250
+ if (errorCode in this.exceptions) {
1251
+ const Exception = this.exceptions[errorCode];
1252
+ throw new Exception (this.id + ' ' + message);
1253
+ }
1254
+ if (errorCode !== undefined) {
1255
+ throw new ExchangeError (this.id + ' ' + message);
1256
+ }
1257
+ }
1258
+
1259
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1260
+ params = this.extend ({
1261
+ 'method': 'privateGetDeposits',
1262
+ }, params);
1263
+ return this.fetchTransactionsHelper (code, since, limit, params);
1264
+ }
1265
+
1266
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1267
+ params = this.extend ({
1268
+ 'method': 'privateGetWithdrawals',
1269
+ }, params);
1270
+ return this.fetchTransactionsHelper (code, since, limit, params);
1271
+ }
1272
+
1273
+ async fetchTransactionsHelper (code = undefined, since = undefined, limit = undefined, params = {}) {
1274
+ await this.loadMarkets ();
1275
+ const nonce = this.uuidv1 ();
1276
+ const request = {
1277
+ 'nonce': nonce,
1278
+ 'wallet': this.walletAddress,
1279
+ };
1280
+ let currency = undefined;
1281
+ if (code !== undefined) {
1282
+ currency = this.currency (code);
1283
+ request['asset'] = currency['id'];
1284
+ }
1285
+ if (since !== undefined) {
1286
+ request['start'] = since;
1287
+ }
1288
+ if (limit !== undefined) {
1289
+ request['limit'] = limit;
1290
+ }
1291
+ // [
1292
+ // {
1293
+ // depositId: 'e9970cc0-eb6b-11ea-9e89-09a5ebc1f98e',
1294
+ // asset: 'ETH',
1295
+ // quantity: '1.00000000',
1296
+ // txId: '0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142',
1297
+ // txTime: 1598865853000,
1298
+ // confirmationTime: 1598865930231
1299
+ // }
1300
+ // ]
1301
+ const method = params['method'];
1302
+ params = this.omit (params, 'method');
1303
+ const response = await this[method] (this.extend (request, params));
1304
+ return this.parseTransactions (response, currency, since, limit);
1305
+ }
1306
+
1307
+ parseTransactionStatus (status) {
1308
+ const statuses = {
1309
+ 'mined': 'ok',
1310
+ };
1311
+ return this.safeString (statuses, status, status);
1312
+ }
1313
+
1314
+ parseTransaction (transaction, currency = undefined) {
1315
+ //
1316
+ // fetchDeposits
1317
+ //
1318
+ // {
1319
+ // depositId: 'e9970cc0-eb6b-11ea-9e89-09a5ebc1f98f',
1320
+ // asset: 'ETH',
1321
+ // quantity: '1.00000000',
1322
+ // txId: '0xcd4aac3171d7131cc9e795568c67938675185ac17641553ef54c8a7c294c8142',
1323
+ // txTime: 1598865853000,
1324
+ // confirmationTime: 1598865930231
1325
+ // }
1326
+ //
1327
+ // fetchWithdrwalas
1328
+ //
1329
+ // {
1330
+ // withdrawalId: 'a62d8760-ec4d-11ea-9fa6-47904c19499b',
1331
+ // asset: 'ETH',
1332
+ // assetContractAddress: '0x0000000000000000000000000000000000000000',
1333
+ // quantity: '0.20000000',
1334
+ // time: 1598962883288,
1335
+ // fee: '0.00024000',
1336
+ // txId: '0x305e9cdbaa85ad029f50578d13d31d777c085de573ed5334d95c19116d8c03ce',
1337
+ // txStatus: 'mined'
1338
+ // }
1339
+ //
1340
+ // withdraw
1341
+ //
1342
+ // {
1343
+ // withdrawalId: 'a61dcff0-ec4d-11ea-8b83-c78a6ecb3180',
1344
+ // asset: 'ETH',
1345
+ // assetContractAddress: '0x0000000000000000000000000000000000000000',
1346
+ // quantity: '0.20000000',
1347
+ // time: 1598962883190,
1348
+ // fee: '0.00024000',
1349
+ // txStatus: 'pending',
1350
+ // txId: null
1351
+ // }
1352
+ //
1353
+ let type = undefined;
1354
+ if ('depositId' in transaction) {
1355
+ type = 'deposit';
1356
+ } else if (('withdrawId' in transaction) || ('withdrawalId' in transaction)) {
1357
+ type = 'withdrawal';
1358
+ }
1359
+ let id = this.safeString2 (transaction, 'depositId', 'withdrawId');
1360
+ id = this.safeString (transaction, 'withdrawalId', id);
1361
+ const code = this.safeCurrencyCode (this.safeString (transaction, 'asset'), currency);
1362
+ const amount = this.safeNumber (transaction, 'quantity');
1363
+ const txid = this.safeString (transaction, 'txId');
1364
+ const timestamp = this.safeInteger (transaction, 'txTime');
1365
+ let fee = undefined;
1366
+ if ('fee' in transaction) {
1367
+ fee = {
1368
+ 'cost': this.safeNumber (transaction, 'fee'),
1369
+ 'currency': 'ETH',
1370
+ };
1371
+ }
1372
+ const rawStatus = this.safeString (transaction, 'txStatus');
1373
+ const status = this.parseTransactionStatus (rawStatus);
1374
+ const updated = this.safeInteger (transaction, 'confirmationTime');
1375
+ return {
1376
+ 'info': transaction,
1377
+ 'id': id,
1378
+ 'txid': txid,
1379
+ 'timestamp': timestamp,
1380
+ 'datetime': this.iso8601 (timestamp),
1381
+ 'network': undefined,
1382
+ 'address': undefined,
1383
+ 'addressTo': undefined,
1384
+ 'addressFrom': undefined,
1385
+ 'tag': undefined,
1386
+ 'tagTo': undefined,
1387
+ 'tagFrom': undefined,
1388
+ 'type': type,
1389
+ 'amount': amount,
1390
+ 'currency': code,
1391
+ 'status': status,
1392
+ 'updated': updated,
1393
+ 'fee': fee,
1394
+ };
1395
+ }
1396
+
1397
+ calculateRateLimiterCost (api, method, path, params, config = {}, context = {}) {
1398
+ const hasApiKey = (this.apiKey !== undefined);
1399
+ const hasSecret = (this.secret !== undefined);
1400
+ const hasWalletAddress = (this.walletAddress !== undefined);
1401
+ const hasPrivateKey = (this.privateKey !== undefined);
1402
+ const defaultCost = this.safeValue (config, 'cost', 1);
1403
+ const authenticated = hasApiKey && hasSecret && hasWalletAddress && hasPrivateKey;
1404
+ return authenticated ? (defaultCost / 2) : defaultCost;
1405
+ }
1406
+
1407
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1408
+ const network = this.safeString (this.options, 'network', 'ETH');
1409
+ const version = this.safeString (this.options, 'version', 'v1');
1410
+ let url = this.urls['api'][network] + '/' + version + '/' + path;
1411
+ const keys = Object.keys (params);
1412
+ const length = keys.length;
1413
+ let query = undefined;
1414
+ if (length > 0) {
1415
+ if (method === 'GET') {
1416
+ query = this.urlencode (params);
1417
+ url = url + '?' + query;
1418
+ } else {
1419
+ body = this.json (params);
1420
+ }
1421
+ }
1422
+ headers = {
1423
+ 'Content-Type': 'application/json',
1424
+ };
1425
+ if (this.apiKey !== undefined) {
1426
+ headers['IDEX-API-Key'] = this.apiKey;
1427
+ }
1428
+ if (api === 'private') {
1429
+ let payload = undefined;
1430
+ if (method === 'GET') {
1431
+ payload = query;
1432
+ } else {
1433
+ payload = body;
1434
+ }
1435
+ headers['IDEX-HMAC-Signature'] = this.hmac (this.encode (payload), this.encode (this.secret), 'sha256', 'hex');
1436
+ }
1437
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1438
+ }
1439
+ };