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
@@ -0,0 +1,1336 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { ExchangeError, ArgumentsRequired, BadRequest, AuthenticationError, DDoSProtection, BadResponse } = require ('./base/errors');
7
+ const Precise = require ('./base/Precise');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class bytetrade extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'bytetrade',
15
+ 'name': 'ByteTrade',
16
+ 'countries': [ 'HK' ],
17
+ // 10 requests per second => ( 1000ms / 10 ) = 100
18
+ 'rateLimit': 100,
19
+ 'requiresWeb3': true,
20
+ 'certified': false,
21
+ // new metainfo interface
22
+ 'has': {
23
+ 'CORS': undefined,
24
+ 'spot': true,
25
+ 'margin': false,
26
+ 'swap': false,
27
+ 'future': false,
28
+ 'option': false,
29
+ 'addMargin': false,
30
+ 'cancelOrder': true,
31
+ 'createOrder': true,
32
+ 'createReduceOnlyOrder': false,
33
+ 'fetchBalance': true,
34
+ 'fetchBidsAsks': true,
35
+ 'fetchBorrowRate': false,
36
+ 'fetchBorrowRateHistories': false,
37
+ 'fetchBorrowRateHistory': false,
38
+ 'fetchBorrowRates': false,
39
+ 'fetchBorrowRatesPerSymbol': false,
40
+ 'fetchClosedOrders': true,
41
+ 'fetchCurrencies': true,
42
+ 'fetchDepositAddress': true,
43
+ 'fetchDeposits': true,
44
+ 'fetchFundingHistory': false,
45
+ 'fetchFundingRate': false,
46
+ 'fetchFundingRateHistory': false,
47
+ 'fetchFundingRates': false,
48
+ 'fetchIndexOHLCV': false,
49
+ 'fetchLeverage': false,
50
+ 'fetchLeverageTiers': false,
51
+ 'fetchMarkets': true,
52
+ 'fetchMarkOHLCV': false,
53
+ 'fetchMyTrades': true,
54
+ 'fetchOHLCV': true,
55
+ 'fetchOpenOrders': true,
56
+ 'fetchOrder': true,
57
+ 'fetchOrderBook': true,
58
+ 'fetchOrders': true,
59
+ 'fetchPosition': false,
60
+ 'fetchPositions': false,
61
+ 'fetchPositionsRisk': false,
62
+ 'fetchPremiumIndexOHLCV': false,
63
+ 'fetchTicker': true,
64
+ 'fetchTickers': true,
65
+ 'fetchTrades': true,
66
+ 'fetchTradingFee': false,
67
+ 'fetchTradingFees': true,
68
+ 'fetchWithdrawals': true,
69
+ 'reduceMargin': false,
70
+ 'setLeverage': false,
71
+ 'setMarginMode': false,
72
+ 'setPositionMode': false,
73
+ 'withdraw': undefined,
74
+ },
75
+ 'timeframes': {
76
+ '1m': '1m',
77
+ '5m': '5m',
78
+ '15m': '15m',
79
+ '30m': '30m',
80
+ '1h': '1h',
81
+ '4h': '4h',
82
+ '1d': '1d',
83
+ '5d': '5d',
84
+ '1w': '1w',
85
+ '1M': '1M',
86
+ },
87
+ 'urls': {
88
+ 'test': {
89
+ 'market': 'https://api-v2-test.byte-trade.com',
90
+ 'public': 'https://api-v2-test.byte-trade.com',
91
+ },
92
+ 'logo': 'https://user-images.githubusercontent.com/1294454/67288762-2f04a600-f4e6-11e9-9fd6-c60641919491.jpg',
93
+ 'api': {
94
+ 'market': 'https://api-v2.bttcdn.com',
95
+ 'public': 'https://api-v2.bttcdn.com',
96
+ },
97
+ 'www': 'https://www.byte-trade.com',
98
+ 'doc': 'https://docs.byte-trade.com/#description',
99
+ },
100
+ 'api': {
101
+ 'market': {
102
+ 'get': {
103
+ 'klines': 1, // Kline of a symbol
104
+ 'depth': 1, // Market Depth of a symbol
105
+ 'trades': 1, // Trade records of a symbol
106
+ 'tickers': 1,
107
+ },
108
+ },
109
+ 'public': {
110
+ 'get': {
111
+ 'symbols': 1, // Reference information of trading instrument, including base currency, quote precision, etc.
112
+ 'currencies': 1, // The list of currencies available
113
+ 'balance': 1, // Get the balance of an account
114
+ 'orders/open': 1, // Get the open orders of an account
115
+ 'orders/closed': 1, // Get the closed orders of an account
116
+ 'orders/all': 1, // Get the open and closed orders of an account
117
+ 'orders': 1, // Get the details of an order of an account
118
+ 'orders/trades': 1, // Get detail match results
119
+ 'depositaddress': 1, // Get deposit address
120
+ 'withdrawals': 1, // Get withdrawals info
121
+ 'deposits': 1, // Get deposit info
122
+ 'transfers': 1, // Get transfer info
123
+ },
124
+ 'post': {
125
+ 'transaction/createorder': 1, // Post create order transaction to blockchain
126
+ 'transaction/cancelorder': 1, // Post cancel order transaction to blockchain
127
+ 'transaction/withdraw': 1, // Post withdraw transaction to blockchain
128
+ 'transaction/transfer': 1, // Post transfer transaction to blockchain
129
+ },
130
+ },
131
+ },
132
+ 'fees': {
133
+ 'trading': {
134
+ 'tierBased': false,
135
+ 'percentage': true,
136
+ 'taker': 0.0008,
137
+ 'maker': 0.0008,
138
+ },
139
+ },
140
+ 'commonCurrencies': {
141
+ '1': 'ByteTrade',
142
+ '44': 'ByteHub',
143
+ '48': 'Blocktonic',
144
+ '133': 'TerraCredit',
145
+ },
146
+ 'exceptions': {
147
+ 'vertify error': AuthenticationError, // typo on the exchange side, 'vertify'
148
+ 'verify error': AuthenticationError, // private key signature is incorrect
149
+ 'transaction already in network': BadRequest, // same transaction submited
150
+ 'invalid argument': BadRequest,
151
+ },
152
+ 'options': {
153
+ 'orderExpiration': 31536000000, // one year
154
+ },
155
+ });
156
+ }
157
+
158
+ async fetchCurrencies (params = {}) {
159
+ const currencies = await this.publicGetCurrencies (params);
160
+ const result = {};
161
+ for (let i = 0; i < currencies.length; i++) {
162
+ const currency = currencies[i];
163
+ const id = this.safeString (currency, 'code');
164
+ let code = undefined;
165
+ if (id in this.commonCurrencies) {
166
+ code = this.commonCurrencies[id];
167
+ } else {
168
+ code = this.safeString (currency, 'name');
169
+ }
170
+ const name = this.safeString (currency, 'fullname');
171
+ // in byte-trade.com DEX, request https://api-v2.byte-trade.com/currencies will return currencies,
172
+ // the api doc is https://github.com/Bytetrade/bytetrade-official-api-docs/wiki/rest-api#get-currencies-get-currencys-supported-in-bytetradecom
173
+ // we can see the coin name is none-unique in the result, the coin which code is 18 is the CyberMiles ERC20, and the coin which code is 35 is the CyberMiles main chain, but their name is same.
174
+ // that is because bytetrade is a DEX, supports people create coin with the same name, but the id(code) of coin is unique, so we should use the id or name and id as the identity of coin.
175
+ // For coin name and symbol is same with CCXT, I use name@id as the key of commonCurrencies dict.
176
+ // [{
177
+ // "name": "CMT", // currency name, non-unique
178
+ // "code": "18", // currency id, unique
179
+ // "type": "crypto",
180
+ // "fullname": "CyberMiles",
181
+ // "active": true,
182
+ // "chainType": "ethereum",
183
+ // "basePrecision": 18,
184
+ // "transferPrecision": 10,
185
+ // "externalPrecision": 18,
186
+ // "chainContractAddress": "0xf85feea2fdd81d51177f6b8f35f0e6734ce45f5f",
187
+ // "limits": {
188
+ // "deposit": {
189
+ // "min": "0",
190
+ // "max": "-1"
191
+ // },
192
+ // "withdraw": {
193
+ // "min": "0",
194
+ // "max": "-1"
195
+ // }
196
+ // }
197
+ // },
198
+ // {
199
+ // "name": "CMT",
200
+ // "code": "35",
201
+ // "type": "crypto",
202
+ // "fullname": "CyberMiles",
203
+ // "active": true,
204
+ // "chainType": "cmt",
205
+ // "basePrecision": 18,
206
+ // "transferPrecision": 10,
207
+ // "externalPrecision": 18,
208
+ // "chainContractAddress": "0x0000000000000000000000000000000000000000",
209
+ // "limits": {
210
+ // "deposit": {
211
+ // "min": "1",
212
+ // "max": "-1"
213
+ // },
214
+ // "withdraw": {
215
+ // "min": "10",
216
+ // "max": "-1"
217
+ // }
218
+ // }
219
+ // }
220
+ // ]
221
+ const active = this.safeValue (currency, 'active');
222
+ const limits = this.safeValue (currency, 'limits');
223
+ const deposit = this.safeValue (limits, 'deposit');
224
+ const amountPrecision = this.safeInteger (currency, 'basePrecision');
225
+ let maxDeposit = this.safeString (deposit, 'max');
226
+ if (Precise.stringEquals (maxDeposit, '-1')) {
227
+ maxDeposit = undefined;
228
+ }
229
+ const withdraw = this.safeValue (limits, 'withdraw');
230
+ let maxWithdraw = this.safeString (withdraw, 'max');
231
+ if (Precise.stringEquals (maxWithdraw, '-1')) {
232
+ maxWithdraw = undefined;
233
+ }
234
+ result[code] = {
235
+ 'id': id,
236
+ 'code': code,
237
+ 'name': name,
238
+ 'active': active,
239
+ 'deposit': undefined,
240
+ 'withdraw': undefined,
241
+ 'precision': amountPrecision,
242
+ 'fee': undefined,
243
+ 'limits': {
244
+ 'amount': { 'min': undefined, 'max': undefined },
245
+ 'deposit': {
246
+ 'min': this.safeNumber (deposit, 'min'),
247
+ 'max': this.parseNumber (maxDeposit),
248
+ },
249
+ 'withdraw': {
250
+ 'min': this.safeNumber (withdraw, 'min'),
251
+ 'max': this.parseNumber (maxWithdraw),
252
+ },
253
+ },
254
+ 'info': currency,
255
+ };
256
+ }
257
+ return result;
258
+ }
259
+
260
+ async fetchMarkets (params = {}) {
261
+ const markets = await this.publicGetSymbols (params);
262
+ //
263
+ // [
264
+ // {
265
+ // "symbol": "122406567911",
266
+ // "name": "BTC/USDT",
267
+ // "base": "32",
268
+ // "quote": "57",
269
+ // "marketStatus": 0,
270
+ // "baseName": "BTC",
271
+ // "quoteName": "USDT",
272
+ // "active": true,
273
+ // "maker": "0.0008",
274
+ // "taker": "0.0008",
275
+ // "precision": {
276
+ // "amount": 6,
277
+ // "price": 2,
278
+ // "minPrice":1
279
+ // },
280
+ // "limits": {
281
+ // "amount": {
282
+ // "min": "0.000001",
283
+ // "max": "-1"
284
+ // },
285
+ // "price": {
286
+ // "min": "0.01",
287
+ // "max": "-1"
288
+ // }
289
+ // }
290
+ // }
291
+ // ]
292
+ //
293
+ const result = [];
294
+ for (let i = 0; i < markets.length; i++) {
295
+ const market = markets[i];
296
+ const id = this.safeString (market, 'symbol');
297
+ let base = this.safeString (market, 'baseName');
298
+ let quote = this.safeString (market, 'quoteName');
299
+ const baseId = this.safeString (market, 'base');
300
+ const quoteId = this.safeString (market, 'quote');
301
+ const normalBase = base.split ('@' + baseId)[0];
302
+ let normalQuote = quote.split ('@' + quoteId)[0];
303
+ if (quoteId === '126') {
304
+ normalQuote = 'ZAR'; // The id 126 coin is a special coin whose name on the chain is actually ZAR, but it is changed to ZCN after creation, so it must be changed to ZAR when placing the transaction in the chain
305
+ }
306
+ const normalSymbol = normalBase + '/' + normalQuote;
307
+ if (baseId in this.commonCurrencies) {
308
+ base = this.commonCurrencies[baseId];
309
+ }
310
+ if (quoteId in this.commonCurrencies) {
311
+ quote = this.commonCurrencies[quoteId];
312
+ }
313
+ const limits = this.safeValue (market, 'limits', {});
314
+ const amount = this.safeValue (limits, 'amount', {});
315
+ const price = this.safeValue (limits, 'price', {});
316
+ const precision = this.safeValue (market, 'precision', {});
317
+ let maxAmount = this.safeString (amount, 'max');
318
+ if (Precise.stringEquals (maxAmount, '-1')) {
319
+ maxAmount = undefined;
320
+ }
321
+ let maxPrice = this.safeString (price, 'max');
322
+ if (Precise.stringEquals (maxPrice, '-1')) {
323
+ maxPrice = undefined;
324
+ }
325
+ const entry = {
326
+ 'id': id,
327
+ 'symbol': base + '/' + quote,
328
+ 'normalSymbol': normalSymbol,
329
+ 'base': base,
330
+ 'quote': quote,
331
+ 'settle': undefined,
332
+ 'baseId': baseId,
333
+ 'quoteId': quoteId,
334
+ 'settleId': undefined,
335
+ 'type': 'spot',
336
+ 'spot': true,
337
+ 'margin': false,
338
+ 'swap': false,
339
+ 'future': false,
340
+ 'option': false,
341
+ 'active': this.safeString (market, 'active'),
342
+ 'contract': false,
343
+ 'linear': undefined,
344
+ 'inverse': undefined,
345
+ 'taker': this.safeNumber (market, 'taker'),
346
+ 'maker': this.safeNumber (market, 'maker'),
347
+ 'contractSize': undefined,
348
+ 'expiry': undefined,
349
+ 'expiryDatetime': undefined,
350
+ 'strike': undefined,
351
+ 'optionType': undefined,
352
+ 'precision': {
353
+ 'amount': this.safeInteger (precision, 'amount'),
354
+ 'price': this.safeInteger (precision, 'price'),
355
+ },
356
+ 'limits': {
357
+ 'leverage': {
358
+ 'min': undefined,
359
+ 'max': undefined,
360
+ },
361
+ 'amount': {
362
+ 'min': this.safeNumber (amount, 'min'),
363
+ 'max': this.parseNumber (maxAmount),
364
+ },
365
+ 'price': {
366
+ 'min': this.safeNumber (price, 'min'),
367
+ 'max': this.parseNumber (maxPrice),
368
+ },
369
+ 'cost': {
370
+ 'min': undefined,
371
+ 'max': undefined,
372
+ },
373
+ },
374
+ 'info': market,
375
+ };
376
+ result.push (entry);
377
+ }
378
+ return result;
379
+ }
380
+
381
+ parseBalance (response) {
382
+ const result = { 'info': response };
383
+ for (let i = 0; i < response.length; i++) {
384
+ const balance = response[i];
385
+ const currencyId = this.safeString (balance, 'code');
386
+ const code = this.safeCurrencyCode (currencyId, undefined);
387
+ const account = this.account ();
388
+ account['free'] = this.safeString (balance, 'free');
389
+ account['used'] = this.safeString (balance, 'used');
390
+ result[code] = account;
391
+ }
392
+ return this.safeBalance (result);
393
+ }
394
+
395
+ async fetchBalance (params = {}) {
396
+ if (!('userid' in params) && (this.apiKey === undefined)) {
397
+ throw new ArgumentsRequired (this.id + ' fetchDeposits() requires this.apiKey or userid argument');
398
+ }
399
+ await this.loadMarkets ();
400
+ const request = {
401
+ 'userid': this.apiKey,
402
+ };
403
+ const response = await this.publicGetBalance (this.extend (request, params));
404
+ return this.parseBalance (response);
405
+ }
406
+
407
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
408
+ await this.loadMarkets ();
409
+ const market = this.market (symbol);
410
+ const request = {
411
+ 'symbol': market['id'],
412
+ };
413
+ if (limit !== undefined) {
414
+ request['limit'] = limit; // default = maximum = 100
415
+ }
416
+ const response = await this.marketGetDepth (this.extend (request, params));
417
+ const timestamp = this.safeValue (response, 'timestamp');
418
+ const orderbook = this.parseOrderBook (response, symbol, timestamp);
419
+ return orderbook;
420
+ }
421
+
422
+ parseTicker (ticker, market = undefined) {
423
+ const timestamp = this.safeInteger (ticker, 'timestamp');
424
+ //
425
+ // [
426
+ // {
427
+ // "symbol":"68719476706",
428
+ // "name":"ETH/BTC",
429
+ // "base":"2",
430
+ // "quote":"32",
431
+ // "timestamp":1575905991933,
432
+ // "datetime":"2019-12-09T15:39:51.933Z",
433
+ // "high":"0",
434
+ // "low":"0",
435
+ // "open":"0",
436
+ // "close":"0",
437
+ // "last":"0",
438
+ // "change":"0",
439
+ // "percentage":"0",
440
+ // "baseVolume":"0",
441
+ // "quoteVolume":"0"
442
+ // }
443
+ // ]
444
+ //
445
+ const marketId = this.safeString (ticker, 'symbol');
446
+ market = this.safeMarket (marketId, market);
447
+ const symbol = market['symbol'];
448
+ return this.safeTicker ({
449
+ 'symbol': symbol,
450
+ 'timestamp': timestamp,
451
+ 'datetime': this.iso8601 (timestamp),
452
+ 'high': this.safeString (ticker, 'high'),
453
+ 'low': this.safeString (ticker, 'low'),
454
+ 'bid': undefined,
455
+ 'bidVolume': undefined,
456
+ 'ask': undefined,
457
+ 'askVolume': undefined,
458
+ 'vwap': this.safeString (ticker, 'weightedAvgPrice'),
459
+ 'open': this.safeString (ticker, 'open'),
460
+ 'close': this.safeString (ticker, 'close'),
461
+ 'last': this.safeString (ticker, 'last'),
462
+ 'previousClose': undefined, // previous day close
463
+ 'change': this.safeString (ticker, 'change'),
464
+ 'percentage': this.safeString (ticker, 'percentage'),
465
+ 'average': undefined,
466
+ 'baseVolume': this.safeString (ticker, 'baseVolume'),
467
+ 'quoteVolume': this.safeString (ticker, 'quoteVolume'),
468
+ 'info': ticker,
469
+ }, market, false);
470
+ }
471
+
472
+ async fetchTicker (symbol, params = {}) {
473
+ await this.loadMarkets ();
474
+ const market = this.market (symbol);
475
+ const request = {
476
+ 'symbol': market['id'],
477
+ };
478
+ const response = await this.marketGetTickers (this.extend (request, params));
479
+ //
480
+ // [
481
+ // {
482
+ // "symbol":"68719476706",
483
+ // "name":"ETH/BTC",
484
+ // "base":"2",
485
+ // "quote":"32",
486
+ // "timestamp":1575905991933,
487
+ // "datetime":"2019-12-09T15:39:51.933Z",
488
+ // "high":"0",
489
+ // "low":"0",
490
+ // "open":"0",
491
+ // "close":"0",
492
+ // "last":"0",
493
+ // "change":"0",
494
+ // "percentage":"0",
495
+ // "baseVolume":"0",
496
+ // "quoteVolume":"0"
497
+ // }
498
+ // ]
499
+ //
500
+ if (Array.isArray (response)) {
501
+ const ticker = this.safeValue (response, 0);
502
+ if (ticker === undefined) {
503
+ throw new BadResponse (this.id + ' fetchTicker() returned an empty response');
504
+ }
505
+ return this.parseTicker (ticker, market);
506
+ }
507
+ return this.parseTicker (response, market);
508
+ }
509
+
510
+ async fetchBidsAsks (symbols = undefined, params = {}) {
511
+ await this.loadMarkets ();
512
+ const response = await this.marketGetDepth (params);
513
+ return this.parseTickers (response, symbols);
514
+ }
515
+
516
+ async fetchTickers (symbols = undefined, params = {}) {
517
+ await this.loadMarkets ();
518
+ const response = await this.marketGetTickers (params);
519
+ return this.parseTickers (response, symbols);
520
+ }
521
+
522
+ parseOHLCV (ohlcv, market = undefined) {
523
+ //
524
+ // [
525
+ // 1591505760000,
526
+ // "242.7",
527
+ // "242.76",
528
+ // "242.69",
529
+ // "242.76",
530
+ // "0.1892"
531
+ // ]
532
+ //
533
+ return [
534
+ this.safeInteger (ohlcv, 0),
535
+ this.safeNumber (ohlcv, 1),
536
+ this.safeNumber (ohlcv, 2),
537
+ this.safeNumber (ohlcv, 3),
538
+ this.safeNumber (ohlcv, 4),
539
+ this.safeNumber (ohlcv, 5),
540
+ ];
541
+ }
542
+
543
+ async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
544
+ await this.loadMarkets ();
545
+ const market = this.market (symbol);
546
+ const request = {
547
+ 'symbol': market['id'],
548
+ 'timeframe': this.timeframes[timeframe],
549
+ };
550
+ if (since !== undefined) {
551
+ request['since'] = since;
552
+ }
553
+ if (limit !== undefined) {
554
+ request['limit'] = limit;
555
+ }
556
+ const response = await this.marketGetKlines (this.extend (request, params));
557
+ //
558
+ // [
559
+ // [1591505760000,"242.7","242.76","242.69","242.76","0.1892"],
560
+ // [1591505820000,"242.77","242.83","242.7","242.72","0.6378"],
561
+ // [1591505880000,"242.72","242.73","242.61","242.72","0.4141"],
562
+ // ]
563
+ //
564
+ return this.parseOHLCVs (response, market, timeframe, since, limit);
565
+ }
566
+
567
+ parseTrade (trade, market = undefined) {
568
+ //
569
+ // public trades
570
+ // {
571
+ // "id":"d38a5bc4b651106f9d6abf9ced671961909be215",
572
+ // "timestamp":1642522255864,
573
+ // "symbol":"122406567940",
574
+ // "side":"sell",
575
+ // "price":"0.12",
576
+ // "amount":"0.5747"
577
+ // }
578
+ //
579
+ // private trades
580
+ // {
581
+ // "id":"905b6ff62b6c90eb5b8c0f7ad0f6bccf018d15e4",
582
+ // "timestamp":1642525375299,
583
+ // "datetime":"2022-01-18T17:02:55.299Z",
584
+ // "symbol":"122406567940",
585
+ // "userid":"slimmjimm@gmail.com",
586
+ // "otherUserid":"nakamoto@gmail.com",
587
+ // "takerOrMaker":"maker",
588
+ // "side":"sell",
589
+ // "txid":"036a89648352732f26a2b6680331dd7887a5c800",
590
+ // "type":"market",
591
+ // "order":"84749f1ca91541d97e400f628d5bb7b1e418a738",
592
+ // "fee": {
593
+ // "cost":"0.000611176192",
594
+ // "rate":"0.0008",
595
+ // "code":57,"name":"USDT"
596
+ // },
597
+ // "cost":"0.76397024",
598
+ // "price":"0.01216",
599
+ // "amount":"62.8265",
600
+ // "average":"0.01216",
601
+ // "name":"DOGE/USDT"
602
+ // }
603
+ //
604
+ const timestamp = this.safeInteger (trade, 'timestamp');
605
+ const priceString = this.safeString (trade, 'price');
606
+ const amountString = this.safeString (trade, 'amount');
607
+ const costString = this.safeString (trade, 'cost');
608
+ const id = this.safeString (trade, 'id');
609
+ const type = this.safeString (trade, 'type');
610
+ const takerOrMaker = this.safeString (trade, 'takerOrMaker');
611
+ const side = this.safeString (trade, 'side');
612
+ const datetime = this.iso8601 (timestamp); // this.safeString (trade, 'datetime');
613
+ const order = this.safeString (trade, 'order');
614
+ const marketId = this.safeString (trade, 'symbol');
615
+ market = this.safeMarket (marketId, market);
616
+ const feeData = this.safeValue (trade, 'fee');
617
+ const feeCostString = this.safeString (feeData, 'cost');
618
+ const feeRateString = this.safeString (feeData, 'rate');
619
+ const feeCode = this.safeString (feeData, 'code');
620
+ const feeCurrency = this.safeCurrencyCode (feeCode);
621
+ const fee = {
622
+ 'currency': feeCurrency,
623
+ 'cost': feeCostString,
624
+ 'rate': feeRateString,
625
+ };
626
+ return this.safeTrade ({
627
+ 'info': trade,
628
+ 'timestamp': timestamp,
629
+ 'datetime': datetime,
630
+ 'symbol': market['symbol'],
631
+ 'id': id,
632
+ 'order': order,
633
+ 'type': type,
634
+ 'takerOrMaker': takerOrMaker,
635
+ 'side': side,
636
+ 'price': priceString,
637
+ 'amount': amountString,
638
+ 'cost': costString,
639
+ 'fee': fee,
640
+ }, market);
641
+ }
642
+
643
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
644
+ await this.loadMarkets ();
645
+ const market = this.market (symbol);
646
+ const request = {
647
+ 'symbol': market['id'],
648
+ };
649
+ if (since !== undefined) {
650
+ request['since'] = since;
651
+ }
652
+ if (limit !== undefined) {
653
+ request['limit'] = limit; // default = 100, maximum = 500
654
+ }
655
+ const response = await this.marketGetTrades (this.extend (request, params));
656
+ return this.parseTrades (response, market, since, limit);
657
+ }
658
+
659
+ async fetchTradingFees (params = {}) {
660
+ await this.loadMarkets ();
661
+ const response = await this.publicGetSymbols (params);
662
+ //
663
+ // [
664
+ // {
665
+ // "symbol": "122406567911",
666
+ // "name": "BTC/USDT",
667
+ // "base": "32",
668
+ // "quote": "57",
669
+ // "marketStatus": 0,
670
+ // "baseName": "BTC",
671
+ // "quoteName": "USDT",
672
+ // "active": true,
673
+ // "maker": "0.0008",
674
+ // "taker": "0.0008",
675
+ // "precision": {
676
+ // "amount": 6,
677
+ // "price": 2,
678
+ // "minPrice":1
679
+ // },
680
+ // "limits": {
681
+ // "amount": {
682
+ // "min": "0.000001",
683
+ // "max": "-1"
684
+ // },
685
+ // "price": {
686
+ // "min": "0.01",
687
+ // "max": "-1"
688
+ // }
689
+ // }
690
+ // }
691
+ // ...
692
+ // ]
693
+ //
694
+ const result = {};
695
+ for (let i = 0; i < response.length; i++) {
696
+ const symbolInfo = response[i];
697
+ const marketId = this.safeString (symbolInfo, 'name');
698
+ const symbol = this.safeSymbol (marketId);
699
+ result[symbol] = {
700
+ 'info': symbolInfo,
701
+ 'symbol': symbol,
702
+ 'maker': this.safeNumber (symbolInfo, 'maker'),
703
+ 'taker': this.safeNumber (symbolInfo, 'taker'),
704
+ 'percentage': true,
705
+ };
706
+ }
707
+ return result;
708
+ }
709
+
710
+ parseOrder (order, market = undefined) {
711
+ const status = this.safeString (order, 'status');
712
+ let symbol = undefined;
713
+ const marketId = this.safeString (order, 'symbol');
714
+ if (marketId in this.markets_by_id) {
715
+ market = this.markets_by_id[marketId];
716
+ } else {
717
+ const baseId = this.safeString (order, 'base');
718
+ const quoteId = this.safeString (order, 'quote');
719
+ if ((baseId !== undefined) && (quoteId !== undefined)) {
720
+ const base = this.safeCurrencyCode (baseId);
721
+ const quote = this.safeCurrencyCode (quoteId);
722
+ symbol = base + '/' + quote;
723
+ }
724
+ }
725
+ if ((symbol === undefined) && (market !== undefined)) {
726
+ symbol = market['symbol'];
727
+ }
728
+ const timestamp = this.safeInteger (order, 'timestamp');
729
+ const datetime = this.safeString (order, 'datetime');
730
+ const lastTradeTimestamp = this.safeInteger (order, 'lastTradeTimestamp');
731
+ const price = this.safeString (order, 'price');
732
+ const amount = this.safeString (order, 'amount');
733
+ const filled = this.safeString (order, 'filled');
734
+ const remaining = this.safeString (order, 'remaining');
735
+ const cost = this.safeString (order, 'cost');
736
+ const average = this.safeString (order, 'average');
737
+ const id = this.safeString (order, 'id');
738
+ const type = this.safeString (order, 'type');
739
+ const side = this.safeString (order, 'side');
740
+ const feeData = this.safeValue (order, 'fee');
741
+ const feeCost = this.safeNumber (feeData, 'cost');
742
+ const feeRate = this.safeNumber (feeData, 'rate');
743
+ const feeCode = this.safeString (feeData, 'code');
744
+ const feeCurrency = this.safeCurrencyCode (feeCode);
745
+ const fee = {
746
+ 'currency': feeCurrency,
747
+ 'cost': feeCost,
748
+ 'rate': feeRate,
749
+ };
750
+ return this.safeOrder ({
751
+ 'info': order,
752
+ 'id': id,
753
+ 'clientOrderId': undefined,
754
+ 'timestamp': timestamp,
755
+ 'datetime': datetime,
756
+ 'lastTradeTimestamp': lastTradeTimestamp,
757
+ 'symbol': symbol,
758
+ 'type': type,
759
+ 'timeInForce': undefined,
760
+ 'postOnly': undefined,
761
+ 'side': side,
762
+ 'price': price,
763
+ 'stopPrice': undefined,
764
+ 'amount': amount,
765
+ 'cost': cost,
766
+ 'average': average,
767
+ 'filled': filled,
768
+ 'remaining': remaining,
769
+ 'status': status,
770
+ 'fee': fee,
771
+ 'trades': undefined,
772
+ }, market);
773
+ }
774
+
775
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
776
+ this.checkRequiredDependencies ();
777
+ if (this.apiKey === undefined) {
778
+ throw new ArgumentsRequired ('createOrder() requires this.apiKey or userid in params');
779
+ }
780
+ await this.loadMarkets ();
781
+ const market = this.market (symbol);
782
+ let sideNum = undefined;
783
+ let typeNum = undefined;
784
+ if (side === 'sell') {
785
+ sideNum = 1;
786
+ } else {
787
+ sideNum = 2;
788
+ }
789
+ if (type === 'limit') {
790
+ typeNum = 1;
791
+ } else {
792
+ typeNum = 2;
793
+ price = 0;
794
+ }
795
+ const normalSymbol = market['normalSymbol'];
796
+ const baseId = market['baseId'];
797
+ const baseCurrency = this.currency (market['base']);
798
+ const amountTruncated = this.amountToPrecision (symbol, amount);
799
+ const amountTruncatedPrecise = new Precise (amountTruncated);
800
+ amountTruncatedPrecise.reduce ();
801
+ amountTruncatedPrecise.decimals -= baseCurrency['precision'];
802
+ const amountChain = amountTruncatedPrecise.toString ();
803
+ const amountChainString = this.numberToString (amountChain);
804
+ const quoteId = market['quoteId'];
805
+ const quoteCurrency = this.currency (market['quote']);
806
+ const priceRounded = this.priceToPrecision (symbol, price);
807
+ const priceRoundedPrecise = new Precise (priceRounded);
808
+ priceRoundedPrecise.reduce ();
809
+ priceRoundedPrecise.decimals -= quoteCurrency['precision'];
810
+ const priceChain = priceRoundedPrecise.toString ();
811
+ const priceChainString = this.numberToString (priceChain);
812
+ const now = this.milliseconds ();
813
+ const expiryDelta = this.safeInteger (this.options, 'orderExpiration', 31536000000);
814
+ const expiration = this.milliseconds () + expiryDelta;
815
+ let datetime = this.iso8601 (now);
816
+ datetime = datetime.split ('.')[0];
817
+ let expirationDatetime = this.iso8601 (expiration);
818
+ expirationDatetime = expirationDatetime.split ('.')[0];
819
+ const defaultDappId = 'Sagittarius';
820
+ const dappId = this.safeString (params, 'dappId', defaultDappId);
821
+ const defaultFee = this.safeString (this.options, 'fee', '300000000000000');
822
+ const totalFeeRate = this.safeString (params, 'totalFeeRate', 8);
823
+ const chainFeeRate = this.safeString (params, 'chainFeeRate', 1);
824
+ const fee = this.safeString (params, 'fee', defaultFee);
825
+ const eightBytes = '18446744073709551616'; // 2 ** 64
826
+ const allByteStringArray = [
827
+ this.numberToBE (1, 32),
828
+ this.numberToLE (Math.floor (now / 1000), 4),
829
+ this.numberToLE (1, 1),
830
+ this.numberToLE (Math.floor (expiration / 1000), 4),
831
+ this.numberToLE (1, 1),
832
+ this.numberToLE (32, 1),
833
+ this.numberToLE (0, 8),
834
+ this.numberToLE (fee, 8), // string for 32 bit php
835
+ this.numberToLE (this.apiKey.length, 1),
836
+ this.stringToBinary (this.encode (this.apiKey)),
837
+ this.numberToLE (sideNum, 1),
838
+ this.numberToLE (typeNum, 1),
839
+ this.numberToLE (normalSymbol.length, 1),
840
+ this.stringToBinary (this.encode (normalSymbol)),
841
+ this.numberToLE (Precise.stringDiv (amountChainString, eightBytes, 0), 8),
842
+ this.numberToLE (Precise.stringMod (amountChainString, eightBytes), 8),
843
+ this.numberToLE (Precise.stringDiv (priceChainString, eightBytes, 0), 8),
844
+ this.numberToLE (Precise.stringMod (priceChainString, eightBytes), 8),
845
+ this.numberToLE (0, 2),
846
+ this.numberToLE (Math.floor (now / 1000), 4),
847
+ this.numberToLE (Math.floor (expiration / 1000), 4),
848
+ this.numberToLE (1, 1),
849
+ this.numberToLE (parseInt (chainFeeRate), 2),
850
+ this.numberToLE (1, 1),
851
+ this.numberToLE (parseInt (totalFeeRate), 2),
852
+ this.numberToLE (parseInt (quoteId), 4),
853
+ this.numberToLE (parseInt (baseId), 4),
854
+ this.numberToLE (0, 1),
855
+ this.numberToLE (1, 1),
856
+ this.numberToLE (dappId.length, 1),
857
+ this.stringToBinary (this.encode (dappId)),
858
+ this.numberToLE (0, 1),
859
+ ];
860
+ const txByteStringArray = [
861
+ this.numberToLE (Math.floor (now / 1000), 4),
862
+ this.numberToLE (1, 1),
863
+ this.numberToLE (Math.floor (expiration / 1000), 4),
864
+ this.numberToLE (1, 1),
865
+ this.numberToLE (32, 1),
866
+ this.numberToLE (0, 8),
867
+ this.numberToLE (fee, 8), // string for 32 bit php
868
+ this.numberToLE (this.apiKey.length, 1),
869
+ this.stringToBinary (this.encode (this.apiKey)),
870
+ this.numberToLE (sideNum, 1),
871
+ this.numberToLE (typeNum, 1),
872
+ this.numberToLE (normalSymbol.length, 1),
873
+ this.stringToBinary (this.encode (normalSymbol)),
874
+ this.numberToLE (Precise.stringDiv (amountChainString, eightBytes, 0), 8),
875
+ this.numberToLE (Precise.stringMod (amountChainString, eightBytes), 8),
876
+ this.numberToLE (Precise.stringDiv (priceChainString, eightBytes, 0), 8),
877
+ this.numberToLE (Precise.stringMod (priceChainString, eightBytes), 8),
878
+ this.numberToLE (0, 2),
879
+ this.numberToLE (Math.floor (now / 1000), 4),
880
+ this.numberToLE (Math.floor (expiration / 1000), 4),
881
+ this.numberToLE (1, 1),
882
+ this.numberToLE (parseInt (chainFeeRate), 2),
883
+ this.numberToLE (1, 1),
884
+ this.numberToLE (parseInt (totalFeeRate), 2),
885
+ this.numberToLE (parseInt (quoteId), 4),
886
+ this.numberToLE (parseInt (baseId), 4),
887
+ this.numberToLE (0, 1),
888
+ this.numberToLE (1, 1),
889
+ this.numberToLE (dappId.length, 1),
890
+ this.stringToBinary (this.encode (dappId)),
891
+ this.numberToLE (0, 1),
892
+ ];
893
+ const txbytestring = this.binaryConcatArray (txByteStringArray);
894
+ const txidhash = this.hash (txbytestring, 'sha256', 'hex');
895
+ const txid = txidhash.slice (0, 40);
896
+ const orderidByteStringArray = [
897
+ this.numberToLE (txid.length, 1),
898
+ this.stringToBinary (this.encode (txid)),
899
+ this.numberToBE (0, 4),
900
+ ];
901
+ const orderidbytestring = this.binaryConcatArray (orderidByteStringArray);
902
+ const orderidhash = this.hash (orderidbytestring, 'sha256', 'hex');
903
+ const orderid = orderidhash.slice (0, 40);
904
+ const bytestring = this.binaryConcatArray (allByteStringArray);
905
+ const hash = this.hash (bytestring, 'sha256', 'hex');
906
+ const signature = this.ecdsa (hash, this.secret, 'secp256k1', undefined, true);
907
+ const recoveryParam = this.binaryToBase16 (this.numberToLE (this.sum (signature['v'], 31), 1));
908
+ const mySignature = recoveryParam + signature['r'] + signature['s'];
909
+ const operation = {
910
+ 'now': datetime,
911
+ 'expiration': expirationDatetime,
912
+ 'fee': fee,
913
+ 'creator': this.apiKey,
914
+ 'side': sideNum,
915
+ 'order_type': typeNum,
916
+ 'market_name': normalSymbol,
917
+ 'amount': amountChain,
918
+ 'price': priceChain,
919
+ 'use_btt_as_fee': false,
920
+ 'money_id': parseInt (quoteId),
921
+ 'stock_id': parseInt (baseId),
922
+ 'custom_no_btt_fee_rate': parseInt (totalFeeRate),
923
+ 'custom_btt_fee_rate': parseInt (chainFeeRate),
924
+ };
925
+ const fatty = {
926
+ 'timestamp': datetime,
927
+ 'expiration': expirationDatetime,
928
+ 'operations': [
929
+ [
930
+ 32,
931
+ operation,
932
+ ],
933
+ ],
934
+ 'validate_type': 0,
935
+ 'dapp': dappId,
936
+ 'signatures': [
937
+ mySignature,
938
+ ],
939
+ };
940
+ const request = {
941
+ 'trObj': this.json (fatty),
942
+ };
943
+ const response = await this.publicPostTransactionCreateorder (request);
944
+ const timestamp = this.milliseconds ();
945
+ const statusCode = this.safeString (response, 'code');
946
+ const status = (statusCode === '0') ? 'open' : 'failed';
947
+ return {
948
+ 'info': response,
949
+ 'id': orderid,
950
+ 'timestamp': timestamp,
951
+ 'datetime': this.iso8601 (timestamp),
952
+ 'lastTradeTimestamp': undefined,
953
+ 'status': status,
954
+ 'symbol': undefined,
955
+ 'type': undefined,
956
+ 'side': undefined,
957
+ 'price': undefined,
958
+ 'amount': undefined,
959
+ 'filled': undefined,
960
+ 'remaining': undefined,
961
+ 'cost': undefined,
962
+ 'trades': undefined,
963
+ 'fee': undefined,
964
+ 'clientOrderId': undefined,
965
+ 'average': undefined,
966
+ };
967
+ }
968
+
969
+ async fetchOrder (id, symbol = undefined, params = {}) {
970
+ if (!('userid' in params) && (this.apiKey === undefined)) {
971
+ throw new ArgumentsRequired ('fetchOrder() requires this.apiKey or userid argument');
972
+ }
973
+ await this.loadMarkets ();
974
+ const request = {
975
+ 'userid': this.apiKey,
976
+ };
977
+ let market = undefined;
978
+ if (symbol !== undefined) {
979
+ market = this.markets[symbol];
980
+ request['symbol'] = market['id'];
981
+ }
982
+ request['id'] = id;
983
+ const response = await this.publicGetOrders (this.extend (request, params));
984
+ return this.parseOrder (response, market);
985
+ }
986
+
987
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
988
+ if (!('userid' in params) && (this.apiKey === undefined)) {
989
+ throw new ArgumentsRequired ('fetchOpenOrders() requires this.apiKey or userid argument');
990
+ }
991
+ await this.loadMarkets ();
992
+ const request = {
993
+ 'userid': this.apiKey,
994
+ };
995
+ let market = undefined;
996
+ if (symbol !== undefined) {
997
+ market = this.market (symbol);
998
+ request['symbol'] = market['id'];
999
+ }
1000
+ if (limit !== undefined) {
1001
+ request['limit'] = limit;
1002
+ }
1003
+ if (since !== undefined) {
1004
+ request['since'] = since;
1005
+ }
1006
+ const response = await this.publicGetOrdersOpen (this.extend (request, params));
1007
+ return this.parseOrders (response, market, since, limit);
1008
+ }
1009
+
1010
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1011
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1012
+ throw new ArgumentsRequired ('fetchClosedOrders() requires this.apiKey or userid argument');
1013
+ }
1014
+ await this.loadMarkets ();
1015
+ let market = undefined;
1016
+ const request = {
1017
+ 'userid': this.apiKey,
1018
+ };
1019
+ if (symbol !== undefined) {
1020
+ market = this.market (symbol);
1021
+ request['symbol'] = market['id'];
1022
+ }
1023
+ if (limit !== undefined) {
1024
+ request['limit'] = limit;
1025
+ }
1026
+ if (since !== undefined) {
1027
+ request['since'] = since;
1028
+ }
1029
+ const response = await this.publicGetOrdersClosed (this.extend (request, params));
1030
+ return this.parseOrders (response, market, since, limit);
1031
+ }
1032
+
1033
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1034
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1035
+ throw new ArgumentsRequired ('fetchOrders() requires this.apiKey or userid argument');
1036
+ }
1037
+ await this.loadMarkets ();
1038
+ let market = undefined;
1039
+ const request = {
1040
+ 'userid': this.apiKey,
1041
+ };
1042
+ if (symbol !== undefined) {
1043
+ market = this.market (symbol);
1044
+ request['symbol'] = market['id'];
1045
+ }
1046
+ if (limit !== undefined) {
1047
+ request['limit'] = limit;
1048
+ }
1049
+ if (since !== undefined) {
1050
+ request['since'] = since;
1051
+ }
1052
+ const response = await this.publicGetOrdersAll (this.extend (request, params));
1053
+ return this.parseOrders (response, market, since, limit);
1054
+ }
1055
+
1056
+ async cancelOrder (id, symbol = undefined, params = {}) {
1057
+ if (this.apiKey === undefined) {
1058
+ throw new ArgumentsRequired ('cancelOrder() requires hasAlreadyAuthenticatedSuccessfully');
1059
+ }
1060
+ if (symbol === undefined) {
1061
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
1062
+ }
1063
+ await this.loadMarkets ();
1064
+ const market = this.market (symbol);
1065
+ const baseId = market['baseId'];
1066
+ const quoteId = market['quoteId'];
1067
+ const normalSymbol = market['normalSymbol'];
1068
+ const feeAmount = '300000000000000';
1069
+ const now = this.milliseconds ();
1070
+ const expiration = 0;
1071
+ let datetime = this.iso8601 (now);
1072
+ datetime = datetime.split ('.')[0];
1073
+ let expirationDatetime = this.iso8601 (expiration);
1074
+ expirationDatetime = expirationDatetime.split ('.')[0];
1075
+ const defaultDappId = 'Sagittarius';
1076
+ const dappId = this.safeString (params, 'dappId', defaultDappId);
1077
+ const byteStringArray = [
1078
+ this.numberToBE (1, 32),
1079
+ this.numberToLE (Math.floor (now / 1000), 4),
1080
+ this.numberToLE (1, 1),
1081
+ this.numberToLE (expiration, 4),
1082
+ this.numberToLE (1, 1),
1083
+ this.numberToLE (33, 1),
1084
+ this.numberToLE (0, 8),
1085
+ this.numberToLE (feeAmount, 8), // string for 32 bit php
1086
+ this.numberToLE (this.apiKey.length, 1),
1087
+ this.stringToBinary (this.encode (this.apiKey)),
1088
+ this.numberToLE (normalSymbol.length, 1),
1089
+ this.stringToBinary (this.encode (normalSymbol)),
1090
+ this.base16ToBinary (id),
1091
+ this.numberToLE (parseInt (quoteId), 4),
1092
+ this.numberToLE (parseInt (baseId), 4),
1093
+ this.numberToLE (0, 1),
1094
+ this.numberToLE (1, 1),
1095
+ this.numberToLE (dappId.length, 1),
1096
+ this.stringToBinary (this.encode (dappId)),
1097
+ this.numberToLE (0, 1),
1098
+ ];
1099
+ const bytestring = this.binaryConcatArray (byteStringArray);
1100
+ const hash = this.hash (bytestring, 'sha256', 'hex');
1101
+ const signature = this.ecdsa (hash, this.secret, 'secp256k1', undefined, true);
1102
+ const recoveryParam = this.binaryToBase16 (this.numberToLE (this.sum (signature['v'], 31), 1));
1103
+ const mySignature = recoveryParam + signature['r'] + signature['s'];
1104
+ const operation = {
1105
+ 'fee': feeAmount,
1106
+ 'creator': this.apiKey,
1107
+ 'order_id': id,
1108
+ 'market_name': normalSymbol,
1109
+ 'money_id': parseInt (quoteId),
1110
+ 'stock_id': parseInt (baseId),
1111
+ };
1112
+ const fatty = {
1113
+ 'timestamp': datetime,
1114
+ 'expiration': expirationDatetime,
1115
+ 'operations': [
1116
+ [
1117
+ 33,
1118
+ operation,
1119
+ ],
1120
+ ],
1121
+ 'validate_type': 0,
1122
+ 'dapp': dappId,
1123
+ 'signatures': [
1124
+ mySignature,
1125
+ ],
1126
+ };
1127
+ const request = {
1128
+ 'trObj': this.json (fatty),
1129
+ };
1130
+ const response = await this.publicPostTransactionCancelorder (request);
1131
+ const timestamp = this.milliseconds ();
1132
+ const statusCode = this.safeString (response, 'code');
1133
+ const status = (statusCode === '0') ? 'canceled' : 'failed';
1134
+ return {
1135
+ 'info': response,
1136
+ 'id': undefined,
1137
+ 'timestamp': timestamp,
1138
+ 'datetime': this.iso8601 (timestamp),
1139
+ 'lastTradeTimestamp': undefined,
1140
+ 'status': status,
1141
+ 'symbol': undefined,
1142
+ 'type': undefined,
1143
+ 'side': undefined,
1144
+ 'price': undefined,
1145
+ 'amount': undefined,
1146
+ 'filled': undefined,
1147
+ 'remaining': undefined,
1148
+ 'cost': undefined,
1149
+ 'trades': undefined,
1150
+ 'fee': undefined,
1151
+ 'clientOrderId': undefined,
1152
+ 'average': undefined,
1153
+ };
1154
+ }
1155
+
1156
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
1157
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1158
+ throw new ArgumentsRequired ('fetchMyTrades() requires this.apiKey or userid argument');
1159
+ }
1160
+ await this.loadMarkets ();
1161
+ const market = this.market (symbol);
1162
+ const request = {
1163
+ 'userid': this.apiKey,
1164
+ };
1165
+ if (symbol !== undefined) {
1166
+ request['symbol'] = market['id'];
1167
+ }
1168
+ if (limit !== undefined) {
1169
+ request['limit'] = limit;
1170
+ }
1171
+ if (since !== undefined) {
1172
+ request['since'] = since;
1173
+ }
1174
+ const response = await this.publicGetOrdersTrades (this.extend (request, params));
1175
+ return this.parseTrades (response, market, since, limit);
1176
+ }
1177
+
1178
+ async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
1179
+ await this.loadMarkets ();
1180
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1181
+ throw new ArgumentsRequired ('fetchDeposits() requires this.apiKey or userid argument');
1182
+ }
1183
+ let currency = undefined;
1184
+ const request = {
1185
+ 'userid': this.apiKey,
1186
+ };
1187
+ if (code !== undefined) {
1188
+ currency = this.currency (code);
1189
+ request['currency'] = currency['id'];
1190
+ }
1191
+ if (since !== undefined) {
1192
+ request['since'] = since;
1193
+ }
1194
+ if (limit !== undefined) {
1195
+ request['limit'] = limit;
1196
+ }
1197
+ const response = await this.publicGetDeposits (this.extend (request, params));
1198
+ return this.parseTransactions (response, currency, since, limit);
1199
+ }
1200
+
1201
+ async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
1202
+ await this.loadMarkets ();
1203
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1204
+ throw new ArgumentsRequired ('fetchWithdrawals() requires this.apiKey or userid argument');
1205
+ }
1206
+ let currency = undefined;
1207
+ const request = {
1208
+ 'userid': this.apiKey,
1209
+ };
1210
+ if (code !== undefined) {
1211
+ currency = this.currency (code);
1212
+ request['currency'] = currency['id'];
1213
+ }
1214
+ if (since !== undefined) {
1215
+ request['since'] = since;
1216
+ }
1217
+ if (limit !== undefined) {
1218
+ request['limit'] = limit;
1219
+ }
1220
+ const response = await this.publicGetWithdrawals (this.extend (request, params));
1221
+ return this.parseTransactions (response, currency, since, limit);
1222
+ }
1223
+
1224
+ parseTransactionStatus (status) {
1225
+ const statuses = {
1226
+ 'DEPOSIT_FAILED': 'failed',
1227
+ 'FEE_SEND_FAILED': 'failed',
1228
+ 'FEE_FAILED': 'failed',
1229
+ 'PAY_SEND_FAILED': 'failed',
1230
+ 'PAY_FAILED': 'failed',
1231
+ 'BTT_FAILED': 'failed',
1232
+ 'WITHDDRAW_FAILED': 'failed',
1233
+ 'USER_FAILED': 'failed',
1234
+ 'FEE_EXECUED': 'pending',
1235
+ 'PAY_EXECUED': 'pending',
1236
+ 'WITHDDRAW_EXECUTED': 'pending',
1237
+ 'USER_EXECUED': 'pending',
1238
+ 'BTT_SUCCED': 'ok',
1239
+ };
1240
+ return this.safeString (statuses, status, status);
1241
+ }
1242
+
1243
+ parseTransaction (transaction, currency = undefined) {
1244
+ const id = this.safeString (transaction, 'id');
1245
+ const address = this.safeString (transaction, 'address');
1246
+ let tag = this.safeString (transaction, 'tag');
1247
+ if (tag !== undefined) {
1248
+ if (tag.length < 1) {
1249
+ tag = undefined;
1250
+ }
1251
+ }
1252
+ const txid = this.safeValue (transaction, 'txid');
1253
+ const currencyId = this.safeString (transaction, 'code');
1254
+ const code = this.safeCurrencyCode (currencyId, currency);
1255
+ const timestamp = this.safeInteger (transaction, 'timestamp');
1256
+ const datetime = this.safeString (transaction, 'datetime');
1257
+ const type = this.safeString (transaction, 'type');
1258
+ const status = this.parseTransactionStatus (this.safeString (transaction, 'status'));
1259
+ const amount = this.safeNumber (transaction, 'amount');
1260
+ const feeInfo = this.safeValue (transaction, 'fee');
1261
+ const feeCost = this.safeNumber (feeInfo, 'cost');
1262
+ const feeCurrencyId = this.safeString (feeInfo, 'code');
1263
+ const feeCode = this.safeCurrencyCode (feeCurrencyId, currency);
1264
+ const fee = {
1265
+ 'cost': feeCost,
1266
+ 'currency': feeCode,
1267
+ };
1268
+ return {
1269
+ 'info': transaction,
1270
+ 'id': id,
1271
+ 'txid': txid,
1272
+ 'timestamp': timestamp,
1273
+ 'datetime': datetime,
1274
+ 'address': address,
1275
+ 'tag': tag,
1276
+ 'type': type,
1277
+ 'amount': amount,
1278
+ 'currency': code,
1279
+ 'status': status,
1280
+ 'updated': undefined,
1281
+ 'fee': fee,
1282
+ };
1283
+ }
1284
+
1285
+ async fetchDepositAddress (code, params = {}) {
1286
+ await this.loadMarkets ();
1287
+ if (!('userid' in params) && (this.apiKey === undefined)) {
1288
+ throw new ArgumentsRequired ('fetchDepositAddress() requires this.apiKey or userid argument');
1289
+ }
1290
+ const currency = this.currency (code);
1291
+ const request = {
1292
+ 'userid': this.apiKey,
1293
+ 'code': currency['id'],
1294
+ };
1295
+ const response = await this.publicGetDepositaddress (request);
1296
+ const firstAddress = this.safeValue (response, 0);
1297
+ const address = this.safeString (firstAddress, 'address');
1298
+ const tag = this.safeString (firstAddress, 'tag');
1299
+ const chainType = this.safeStringUpper (firstAddress, 'chainType');
1300
+ this.checkAddress (address);
1301
+ return {
1302
+ 'currency': code,
1303
+ 'address': address,
1304
+ 'tag': tag,
1305
+ 'network': chainType,
1306
+ 'info': response,
1307
+ };
1308
+ }
1309
+
1310
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1311
+ let url = this.urls['api'][api];
1312
+ url += '/' + path;
1313
+ if (Object.keys (params).length) {
1314
+ url += '?' + this.urlencode (params);
1315
+ }
1316
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1317
+ }
1318
+
1319
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1320
+ if (code === 503) {
1321
+ throw new DDoSProtection (this.id + ' ' + code.toString () + ' ' + reason + ' ' + body);
1322
+ }
1323
+ if (response === undefined) {
1324
+ return; // fallback to default error handler
1325
+ }
1326
+ if ('code' in response) {
1327
+ const status = this.safeString (response, 'code');
1328
+ if (status === '1') {
1329
+ const message = this.safeString (response, 'msg');
1330
+ const feedback = this.id + ' ' + body;
1331
+ this.throwExactlyMatchedException (this.exceptions, message, feedback);
1332
+ throw new ExchangeError (feedback);
1333
+ }
1334
+ }
1335
+ }
1336
+ };