ccxt 4.2.10 → 4.2.12

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 (383) hide show
  1. package/README.md +5 -5
  2. package/build.sh +4 -4
  3. package/dist/ccxt.browser.js +695 -282
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/_virtual/agent.js +7 -0
  6. package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
  7. package/dist/cjs/_virtual/promisify.js +7 -0
  8. package/dist/cjs/ccxt.js +1 -1
  9. package/dist/cjs/js/ccxt.js +474 -0
  10. package/dist/cjs/js/src/abstract/ace.js +9 -0
  11. package/dist/cjs/js/src/abstract/alpaca.js +9 -0
  12. package/dist/cjs/js/src/abstract/ascendex.js +9 -0
  13. package/dist/cjs/js/src/abstract/bigone.js +9 -0
  14. package/dist/cjs/js/src/abstract/binance.js +9 -0
  15. package/dist/cjs/js/src/abstract/bingx.js +9 -0
  16. package/dist/cjs/js/src/abstract/bit2c.js +9 -0
  17. package/dist/cjs/js/src/abstract/bitbank.js +9 -0
  18. package/dist/cjs/js/src/abstract/bitbns.js +9 -0
  19. package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
  20. package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
  21. package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
  22. package/dist/cjs/js/src/abstract/bitforex.js +9 -0
  23. package/dist/cjs/js/src/abstract/bitget.js +9 -0
  24. package/dist/cjs/js/src/abstract/bithumb.js +9 -0
  25. package/dist/cjs/js/src/abstract/bitmart.js +9 -0
  26. package/dist/cjs/js/src/abstract/bitmex.js +9 -0
  27. package/dist/cjs/js/src/abstract/bitopro.js +9 -0
  28. package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
  29. package/dist/cjs/js/src/abstract/bitrue.js +9 -0
  30. package/dist/cjs/js/src/abstract/bitso.js +9 -0
  31. package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
  32. package/dist/cjs/js/src/abstract/bitteam.js +9 -0
  33. package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
  34. package/dist/cjs/js/src/abstract/bl3p.js +9 -0
  35. package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
  36. package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
  37. package/dist/cjs/js/src/abstract/btcbox.js +9 -0
  38. package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
  39. package/dist/cjs/js/src/abstract/btcturk.js +9 -0
  40. package/dist/cjs/js/src/abstract/bybit.js +9 -0
  41. package/dist/cjs/js/src/abstract/cex.js +9 -0
  42. package/dist/cjs/js/src/abstract/coinbase.js +9 -0
  43. package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
  44. package/dist/cjs/js/src/abstract/coincheck.js +9 -0
  45. package/dist/cjs/js/src/abstract/coinex.js +9 -0
  46. package/dist/cjs/js/src/abstract/coinlist.js +9 -0
  47. package/dist/cjs/js/src/abstract/coinmate.js +9 -0
  48. package/dist/cjs/js/src/abstract/coinone.js +9 -0
  49. package/dist/cjs/js/src/abstract/coinsph.js +9 -0
  50. package/dist/cjs/js/src/abstract/coinspot.js +9 -0
  51. package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
  52. package/dist/cjs/js/src/abstract/currencycom.js +9 -0
  53. package/dist/cjs/js/src/abstract/delta.js +9 -0
  54. package/dist/cjs/js/src/abstract/deribit.js +9 -0
  55. package/dist/cjs/js/src/abstract/digifinex.js +9 -0
  56. package/dist/cjs/js/src/abstract/exmo.js +9 -0
  57. package/dist/cjs/js/src/abstract/gate.js +9 -0
  58. package/dist/cjs/js/src/abstract/gemini.js +9 -0
  59. package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
  60. package/dist/cjs/js/src/abstract/hollaex.js +9 -0
  61. package/dist/cjs/js/src/abstract/htx.js +9 -0
  62. package/dist/cjs/js/src/abstract/huobijp.js +9 -0
  63. package/dist/cjs/js/src/abstract/idex.js +9 -0
  64. package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
  65. package/dist/cjs/js/src/abstract/indodax.js +9 -0
  66. package/dist/cjs/js/src/abstract/kraken.js +9 -0
  67. package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
  68. package/dist/cjs/js/src/abstract/kucoin.js +9 -0
  69. package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
  70. package/dist/cjs/js/src/abstract/kuna.js +9 -0
  71. package/dist/cjs/js/src/abstract/latoken.js +9 -0
  72. package/dist/cjs/js/src/abstract/lbank.js +9 -0
  73. package/dist/cjs/js/src/abstract/luno.js +9 -0
  74. package/dist/cjs/js/src/abstract/lykke.js +9 -0
  75. package/dist/cjs/js/src/abstract/mercado.js +9 -0
  76. package/dist/cjs/js/src/abstract/mexc.js +9 -0
  77. package/dist/cjs/js/src/abstract/ndax.js +9 -0
  78. package/dist/cjs/js/src/abstract/novadax.js +9 -0
  79. package/dist/cjs/js/src/abstract/oceanex.js +9 -0
  80. package/dist/cjs/js/src/abstract/okcoin.js +9 -0
  81. package/dist/cjs/js/src/abstract/okx.js +9 -0
  82. package/dist/cjs/js/src/abstract/p2b.js +9 -0
  83. package/dist/cjs/js/src/abstract/paymium.js +9 -0
  84. package/dist/cjs/js/src/abstract/phemex.js +9 -0
  85. package/dist/cjs/js/src/abstract/poloniex.js +9 -0
  86. package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
  87. package/dist/cjs/js/src/abstract/probit.js +9 -0
  88. package/dist/cjs/js/src/abstract/timex.js +9 -0
  89. package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
  90. package/dist/cjs/js/src/abstract/upbit.js +9 -0
  91. package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
  92. package/dist/cjs/js/src/abstract/wazirx.js +9 -0
  93. package/dist/cjs/js/src/abstract/whitebit.js +9 -0
  94. package/dist/cjs/js/src/abstract/woo.js +9 -0
  95. package/dist/cjs/js/src/abstract/yobit.js +9 -0
  96. package/dist/cjs/js/src/abstract/zaif.js +9 -0
  97. package/dist/cjs/js/src/abstract/zonda.js +9 -0
  98. package/dist/cjs/js/src/ace.js +1058 -0
  99. package/dist/cjs/js/src/alpaca.js +1125 -0
  100. package/dist/cjs/js/src/ascendex.js +3360 -0
  101. package/dist/cjs/js/src/base/Exchange.js +5110 -0
  102. package/dist/cjs/js/src/base/Precise.js +263 -0
  103. package/dist/cjs/js/src/base/errors.js +299 -0
  104. package/dist/cjs/js/src/base/functions/crypto.js +78 -0
  105. package/dist/cjs/js/src/base/functions/encode.js +44 -0
  106. package/dist/cjs/js/src/base/functions/generic.js +193 -0
  107. package/dist/cjs/js/src/base/functions/misc.js +96 -0
  108. package/dist/cjs/js/src/base/functions/number.js +297 -0
  109. package/dist/cjs/js/src/base/functions/platform.js +28 -0
  110. package/dist/cjs/js/src/base/functions/rsa.js +34 -0
  111. package/dist/cjs/js/src/base/functions/string.js +48 -0
  112. package/dist/cjs/js/src/base/functions/throttle.js +66 -0
  113. package/dist/cjs/js/src/base/functions/time.js +187 -0
  114. package/dist/cjs/js/src/base/functions/totp.js +24 -0
  115. package/dist/cjs/js/src/base/functions/type.js +162 -0
  116. package/dist/cjs/js/src/base/functions.js +157 -0
  117. package/dist/cjs/js/src/base/ws/Cache.js +254 -0
  118. package/dist/cjs/js/src/base/ws/Client.js +299 -0
  119. package/dist/cjs/js/src/base/ws/Future.js +34 -0
  120. package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
  121. package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
  122. package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
  123. package/dist/cjs/js/src/bequant.js +33 -0
  124. package/dist/cjs/js/src/bigone.js +2142 -0
  125. package/dist/cjs/js/src/binance.js +9729 -0
  126. package/dist/cjs/js/src/binancecoinm.js +45 -0
  127. package/dist/cjs/js/src/binanceus.js +84 -0
  128. package/dist/cjs/js/src/binanceusdm.js +58 -0
  129. package/dist/cjs/js/src/bingx.js +3737 -0
  130. package/dist/cjs/js/src/bit2c.js +916 -0
  131. package/dist/cjs/js/src/bitbank.js +1000 -0
  132. package/dist/cjs/js/src/bitbay.js +17 -0
  133. package/dist/cjs/js/src/bitbns.js +1220 -0
  134. package/dist/cjs/js/src/bitcoincom.js +17 -0
  135. package/dist/cjs/js/src/bitfinex.js +1670 -0
  136. package/dist/cjs/js/src/bitfinex2.js +2990 -0
  137. package/dist/cjs/js/src/bitflyer.js +1045 -0
  138. package/dist/cjs/js/src/bitforex.js +852 -0
  139. package/dist/cjs/js/src/bitget.js +8284 -0
  140. package/dist/cjs/js/src/bithumb.js +1090 -0
  141. package/dist/cjs/js/src/bitmart.js +4454 -0
  142. package/dist/cjs/js/src/bitmex.js +2884 -0
  143. package/dist/cjs/js/src/bitopro.js +1724 -0
  144. package/dist/cjs/js/src/bitpanda.js +2002 -0
  145. package/dist/cjs/js/src/bitrue.js +3253 -0
  146. package/dist/cjs/js/src/bitso.js +1753 -0
  147. package/dist/cjs/js/src/bitstamp.js +2188 -0
  148. package/dist/cjs/js/src/bitteam.js +2309 -0
  149. package/dist/cjs/js/src/bitvavo.js +1968 -0
  150. package/dist/cjs/js/src/bl3p.js +447 -0
  151. package/dist/cjs/js/src/blockchaincom.js +1160 -0
  152. package/dist/cjs/js/src/btcalpha.js +929 -0
  153. package/dist/cjs/js/src/btcbox.js +565 -0
  154. package/dist/cjs/js/src/btcmarkets.js +1237 -0
  155. package/dist/cjs/js/src/btcturk.js +929 -0
  156. package/dist/cjs/js/src/bybit.js +7646 -0
  157. package/dist/cjs/js/src/cex.js +1693 -0
  158. package/dist/cjs/js/src/coinbase.js +3274 -0
  159. package/dist/cjs/js/src/coinbasepro.js +1866 -0
  160. package/dist/cjs/js/src/coincheck.js +843 -0
  161. package/dist/cjs/js/src/coinex.js +5414 -0
  162. package/dist/cjs/js/src/coinlist.js +2329 -0
  163. package/dist/cjs/js/src/coinmate.js +989 -0
  164. package/dist/cjs/js/src/coinone.js +1185 -0
  165. package/dist/cjs/js/src/coinsph.js +1933 -0
  166. package/dist/cjs/js/src/coinspot.js +548 -0
  167. package/dist/cjs/js/src/cryptocom.js +3007 -0
  168. package/dist/cjs/js/src/currencycom.js +2015 -0
  169. package/dist/cjs/js/src/delta.js +3256 -0
  170. package/dist/cjs/js/src/deribit.js +3306 -0
  171. package/dist/cjs/js/src/digifinex.js +4307 -0
  172. package/dist/cjs/js/src/exmo.js +2645 -0
  173. package/dist/cjs/js/src/fmfwio.js +34 -0
  174. package/dist/cjs/js/src/gate.js +7054 -0
  175. package/dist/cjs/js/src/gateio.js +16 -0
  176. package/dist/cjs/js/src/gemini.js +1801 -0
  177. package/dist/cjs/js/src/hitbtc.js +3660 -0
  178. package/dist/cjs/js/src/hitbtc3.js +19 -0
  179. package/dist/cjs/js/src/hollaex.js +1882 -0
  180. package/dist/cjs/js/src/htx.js +9024 -0
  181. package/dist/cjs/js/src/huobi.js +16 -0
  182. package/dist/cjs/js/src/huobijp.js +1918 -0
  183. package/dist/cjs/js/src/idex.js +1770 -0
  184. package/dist/cjs/js/src/independentreserve.js +759 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2861 -0
  187. package/dist/cjs/js/src/krakenfutures.js +2407 -0
  188. package/dist/cjs/js/src/kucoin.js +4489 -0
  189. package/dist/cjs/js/src/kucoinfutures.js +2475 -0
  190. package/dist/cjs/js/src/kuna.js +1949 -0
  191. package/dist/cjs/js/src/latoken.js +1729 -0
  192. package/dist/cjs/js/src/lbank.js +2825 -0
  193. package/dist/cjs/js/src/luno.js +1044 -0
  194. package/dist/cjs/js/src/lykke.js +1303 -0
  195. package/dist/cjs/js/src/mercado.js +897 -0
  196. package/dist/cjs/js/src/mexc.js +5407 -0
  197. package/dist/cjs/js/src/ndax.js +2450 -0
  198. package/dist/cjs/js/src/novadax.js +1556 -0
  199. package/dist/cjs/js/src/oceanex.js +964 -0
  200. package/dist/cjs/js/src/okcoin.js +3115 -0
  201. package/dist/cjs/js/src/okx.js +7329 -0
  202. package/dist/cjs/js/src/p2b.js +1243 -0
  203. package/dist/cjs/js/src/paymium.js +597 -0
  204. package/dist/cjs/js/src/phemex.js +4715 -0
  205. package/dist/cjs/js/src/poloniex.js +2356 -0
  206. package/dist/cjs/js/src/poloniexfutures.js +1794 -0
  207. package/dist/cjs/js/src/pro/alpaca.js +714 -0
  208. package/dist/cjs/js/src/pro/ascendex.js +957 -0
  209. package/dist/cjs/js/src/pro/bequant.js +33 -0
  210. package/dist/cjs/js/src/pro/binance.js +2796 -0
  211. package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
  212. package/dist/cjs/js/src/pro/binanceus.js +51 -0
  213. package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
  214. package/dist/cjs/js/src/pro/bingx.js +944 -0
  215. package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
  216. package/dist/cjs/js/src/pro/bitfinex.js +672 -0
  217. package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
  218. package/dist/cjs/js/src/pro/bitget.js +1733 -0
  219. package/dist/cjs/js/src/pro/bitmart.js +1486 -0
  220. package/dist/cjs/js/src/pro/bitmex.js +1576 -0
  221. package/dist/cjs/js/src/pro/bitopro.js +327 -0
  222. package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
  223. package/dist/cjs/js/src/pro/bitrue.js +462 -0
  224. package/dist/cjs/js/src/pro/bitstamp.js +547 -0
  225. package/dist/cjs/js/src/pro/bitvavo.js +704 -0
  226. package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
  227. package/dist/cjs/js/src/pro/bybit.js +1843 -0
  228. package/dist/cjs/js/src/pro/cex.js +1510 -0
  229. package/dist/cjs/js/src/pro/coinbase.js +561 -0
  230. package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
  231. package/dist/cjs/js/src/pro/coinex.js +1095 -0
  232. package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
  233. package/dist/cjs/js/src/pro/currencycom.js +563 -0
  234. package/dist/cjs/js/src/pro/deribit.js +825 -0
  235. package/dist/cjs/js/src/pro/exmo.js +658 -0
  236. package/dist/cjs/js/src/pro/gate.js +1316 -0
  237. package/dist/cjs/js/src/pro/gateio.js +16 -0
  238. package/dist/cjs/js/src/pro/gemini.js +649 -0
  239. package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
  240. package/dist/cjs/js/src/pro/hollaex.js +597 -0
  241. package/dist/cjs/js/src/pro/htx.js +2383 -0
  242. package/dist/cjs/js/src/pro/huobi.js +16 -0
  243. package/dist/cjs/js/src/pro/huobijp.js +606 -0
  244. package/dist/cjs/js/src/pro/idex.js +714 -0
  245. package/dist/cjs/js/src/pro/independentreserve.js +280 -0
  246. package/dist/cjs/js/src/pro/kraken.js +1364 -0
  247. package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
  248. package/dist/cjs/js/src/pro/kucoin.js +1052 -0
  249. package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
  250. package/dist/cjs/js/src/pro/luno.js +322 -0
  251. package/dist/cjs/js/src/pro/mexc.js +1170 -0
  252. package/dist/cjs/js/src/pro/ndax.js +545 -0
  253. package/dist/cjs/js/src/pro/okcoin.js +760 -0
  254. package/dist/cjs/js/src/pro/okx.js +1558 -0
  255. package/dist/cjs/js/src/pro/phemex.js +1511 -0
  256. package/dist/cjs/js/src/pro/poloniex.js +1253 -0
  257. package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
  258. package/dist/cjs/js/src/pro/probit.js +586 -0
  259. package/dist/cjs/js/src/pro/upbit.js +234 -0
  260. package/dist/cjs/js/src/pro/wazirx.js +776 -0
  261. package/dist/cjs/js/src/pro/whitebit.js +927 -0
  262. package/dist/cjs/js/src/pro/woo.js +769 -0
  263. package/dist/cjs/js/src/probit.js +1865 -0
  264. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
  265. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
  266. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
  267. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
  268. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
  269. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
  270. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
  271. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
  272. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
  273. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
  274. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
  275. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
  276. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
  277. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
  278. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
  279. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
  280. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
  281. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
  282. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
  283. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
  284. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
  285. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
  286. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
  287. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
  288. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
  289. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
  290. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
  291. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
  292. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
  293. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
  294. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
  295. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
  296. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
  297. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
  298. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
  299. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
  300. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
  301. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
  302. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
  303. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
  304. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
  305. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
  306. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
  307. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
  308. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
  309. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
  310. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
  311. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
  312. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
  313. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
  314. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
  315. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
  316. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
  317. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
  318. package/dist/cjs/js/src/timex.js +1562 -0
  319. package/dist/cjs/js/src/tokocrypto.js +2542 -0
  320. package/dist/cjs/js/src/upbit.js +1844 -0
  321. package/dist/cjs/js/src/wavesexchange.js +2607 -0
  322. package/dist/cjs/js/src/wazirx.js +953 -0
  323. package/dist/cjs/js/src/whitebit.js +2309 -0
  324. package/dist/cjs/js/src/woo.js +2715 -0
  325. package/dist/cjs/js/src/yobit.js +1314 -0
  326. package/dist/cjs/js/src/zaif.js +736 -0
  327. package/dist/cjs/js/src/zonda.js +1883 -0
  328. package/dist/cjs/src/base/Exchange.js +11 -0
  329. package/dist/cjs/src/bingx.js +0 -10
  330. package/dist/cjs/src/bitget.js +14 -5
  331. package/dist/cjs/src/bybit.js +1 -1
  332. package/dist/cjs/src/kucoin.js +29 -5
  333. package/js/ccxt.d.ts +1 -1
  334. package/js/ccxt.js +1 -1
  335. package/js/src/abstract/bigone.d.ts +18 -0
  336. package/js/src/abstract/binance.d.ts +2 -0
  337. package/js/src/abstract/binancecoinm.d.ts +2 -0
  338. package/js/src/abstract/binanceus.d.ts +2 -0
  339. package/js/src/abstract/binanceusdm.d.ts +2 -0
  340. package/js/src/abstract/bybit.d.ts +1 -0
  341. package/js/src/abstract/gate.d.ts +11 -0
  342. package/js/src/abstract/gateio.d.ts +11 -0
  343. package/js/src/alpaca.js +18 -18
  344. package/js/src/base/Exchange.d.ts +6 -1
  345. package/js/src/base/Exchange.js +112 -12
  346. package/js/src/bigone.d.ts +1 -2
  347. package/js/src/bigone.js +340 -145
  348. package/js/src/binance.js +15 -8
  349. package/js/src/bingx.d.ts +0 -1
  350. package/js/src/bingx.js +9 -12
  351. package/js/src/bitfinex.d.ts +2 -2
  352. package/js/src/bitfinex.js +2 -3
  353. package/js/src/bitget.js +35 -13
  354. package/js/src/bitmart.d.ts +2 -2
  355. package/js/src/bitmart.js +3 -3
  356. package/js/src/bitmex.js +1 -0
  357. package/js/src/bybit.js +3 -1
  358. package/js/src/coinlist.js +2 -3
  359. package/js/src/coinsph.js +2 -3
  360. package/js/src/deribit.js +1 -0
  361. package/js/src/gate.d.ts +4 -4
  362. package/js/src/gate.js +22 -3
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.js +4 -7
  366. package/js/src/huobijp.js +2 -3
  367. package/js/src/kraken.js +1 -0
  368. package/js/src/kucoin.js +29 -5
  369. package/js/src/mexc.js +2 -1
  370. package/js/src/okx.js +13 -3
  371. package/js/src/pro/binance.d.ts +2 -23
  372. package/js/src/pro/binance.js +58 -22
  373. package/js/src/pro/coinbase.d.ts +2 -2
  374. package/js/src/pro/coinbase.js +4 -1
  375. package/js/src/pro/coinbasepro.d.ts +2 -2
  376. package/js/src/pro/hitbtc.d.ts +2 -2
  377. package/js/src/pro/poloniex.d.ts +2 -2
  378. package/js/src/upbit.d.ts +3 -101
  379. package/js/src/upbit.js +12 -12
  380. package/js/src/woo.js +2 -0
  381. package/package.json +11 -11
  382. package/skip-tests.json +5 -0
  383. package/tests-manager.sh +2 -2
@@ -0,0 +1,3253 @@
1
+ 'use strict';
2
+
3
+ var bitrue$1 = require('./abstract/bitrue.js');
4
+ var errors = require('./base/errors.js');
5
+ var Precise = require('./base/Precise.js');
6
+ var number = require('./base/functions/number.js');
7
+ var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * @class bitrue
13
+ * @augments Exchange
14
+ */
15
+ class bitrue extends bitrue$1 {
16
+ describe() {
17
+ return this.deepExtend(super.describe(), {
18
+ 'id': 'bitrue',
19
+ 'name': 'Bitrue',
20
+ 'countries': ['SG'],
21
+ 'rateLimit': 1000,
22
+ 'certified': false,
23
+ 'version': 'v1',
24
+ 'pro': true,
25
+ // new metainfo interface
26
+ 'has': {
27
+ 'CORS': undefined,
28
+ 'spot': true,
29
+ 'margin': false,
30
+ 'swap': true,
31
+ 'future': false,
32
+ 'option': false,
33
+ 'cancelAllOrders': true,
34
+ 'cancelOrder': true,
35
+ 'createMarketBuyOrderWithCost': true,
36
+ 'createMarketOrderWithCost': false,
37
+ 'createMarketSellOrderWithCost': false,
38
+ 'createOrder': true,
39
+ 'createStopLimitOrder': true,
40
+ 'createStopMarketOrder': true,
41
+ 'createStopOrder': true,
42
+ 'fetchBalance': true,
43
+ 'fetchBidsAsks': true,
44
+ 'fetchBorrowRateHistories': false,
45
+ 'fetchBorrowRateHistory': false,
46
+ 'fetchClosedOrders': true,
47
+ 'fetchCrossBorrowRate': false,
48
+ 'fetchCrossBorrowRates': false,
49
+ 'fetchCurrencies': true,
50
+ 'fetchDepositAddress': false,
51
+ 'fetchDeposits': true,
52
+ 'fetchDepositsWithdrawals': false,
53
+ 'fetchDepositWithdrawFee': 'emulated',
54
+ 'fetchDepositWithdrawFees': true,
55
+ 'fetchIsolatedBorrowRate': false,
56
+ 'fetchIsolatedBorrowRates': false,
57
+ 'fetchMarginMode': false,
58
+ 'fetchMarkets': true,
59
+ 'fetchMyTrades': true,
60
+ 'fetchOHLCV': true,
61
+ 'fetchOpenOrders': true,
62
+ 'fetchOrder': true,
63
+ 'fetchOrderBook': true,
64
+ 'fetchOrders': false,
65
+ 'fetchPositionMode': false,
66
+ 'fetchStatus': true,
67
+ 'fetchTicker': true,
68
+ 'fetchTickers': true,
69
+ 'fetchTime': true,
70
+ 'fetchTrades': true,
71
+ 'fetchTradingFee': false,
72
+ 'fetchTradingFees': false,
73
+ 'fetchTransactionFees': false,
74
+ 'fetchTransactions': false,
75
+ 'fetchTransfers': true,
76
+ 'fetchWithdrawals': true,
77
+ 'setLeverage': true,
78
+ 'setMargin': true,
79
+ 'transfer': true,
80
+ 'withdraw': true,
81
+ },
82
+ 'timeframes': {
83
+ '1m': '1m',
84
+ '5m': '5m',
85
+ '15m': '15m',
86
+ '30m': '30m',
87
+ '1h': '1H',
88
+ '2h': '2H',
89
+ '4h': '4H',
90
+ '1d': '1D',
91
+ '1w': '1W',
92
+ },
93
+ 'urls': {
94
+ 'logo': 'https://user-images.githubusercontent.com/1294454/139516488-243a830d-05dd-446b-91c6-c1f18fe30c63.jpg',
95
+ 'api': {
96
+ 'spot': 'https://www.bitrue.com/api',
97
+ 'fapi': 'https://fapi.bitrue.com/fapi',
98
+ 'dapi': 'https://fapi.bitrue.com/dapi',
99
+ 'kline': 'https://www.bitrue.com/kline-api',
100
+ },
101
+ 'www': 'https://www.bitrue.com',
102
+ 'referral': 'https://www.bitrue.com/affiliate/landing?cn=600000&inviteCode=EZWETQE',
103
+ 'doc': [
104
+ 'https://github.com/Bitrue-exchange/bitrue-official-api-docs',
105
+ 'https://www.bitrue.com/api-docs',
106
+ ],
107
+ 'fees': 'https://bitrue.zendesk.com/hc/en-001/articles/4405479952537',
108
+ },
109
+ 'api': {
110
+ 'spot': {
111
+ 'kline': {
112
+ 'public': {
113
+ 'get': {
114
+ 'public.json': 1,
115
+ 'public{currency}.json': 1,
116
+ },
117
+ },
118
+ },
119
+ 'v1': {
120
+ 'public': {
121
+ 'get': {
122
+ 'ping': 1,
123
+ 'time': 1,
124
+ 'exchangeInfo': 1,
125
+ 'depth': { 'cost': 1, 'byLimit': [[100, 1], [500, 5], [1000, 10]] },
126
+ 'trades': 1,
127
+ 'historicalTrades': 5,
128
+ 'aggTrades': 1,
129
+ 'ticker/24hr': { 'cost': 1, 'noSymbol': 40 },
130
+ 'ticker/price': { 'cost': 1, 'noSymbol': 2 },
131
+ 'ticker/bookTicker': { 'cost': 1, 'noSymbol': 2 },
132
+ 'market/kline': 1,
133
+ },
134
+ },
135
+ 'private': {
136
+ 'get': {
137
+ 'order': 1,
138
+ 'openOrders': 1,
139
+ 'allOrders': 5,
140
+ 'account': 5,
141
+ 'myTrades': { 'cost': 5, 'noSymbol': 40 },
142
+ 'etf/net-value/{symbol}': 1,
143
+ 'withdraw/history': 1,
144
+ 'deposit/history': 1,
145
+ },
146
+ 'post': {
147
+ 'order': 4,
148
+ 'withdraw/commit': 1,
149
+ },
150
+ 'delete': {
151
+ 'order': 1,
152
+ },
153
+ },
154
+ },
155
+ 'v2': {
156
+ 'private': {
157
+ 'get': {
158
+ 'myTrades': 5,
159
+ },
160
+ },
161
+ },
162
+ },
163
+ 'fapi': {
164
+ 'v1': {
165
+ 'public': {
166
+ 'get': {
167
+ 'ping': 1,
168
+ 'time': 1,
169
+ 'contracts': 1,
170
+ 'depth': 1,
171
+ 'ticker': 1,
172
+ 'klines': 1,
173
+ },
174
+ },
175
+ },
176
+ 'v2': {
177
+ 'private': {
178
+ 'get': {
179
+ 'myTrades': 1,
180
+ 'openOrders': 1,
181
+ 'order': 1,
182
+ 'account': 1,
183
+ 'leverageBracket': 1,
184
+ 'commissionRate': 1,
185
+ 'futures_transfer_history': 1,
186
+ 'forceOrdersHistory': 1,
187
+ },
188
+ 'post': {
189
+ 'positionMargin': 1,
190
+ 'level_edit': 1,
191
+ 'cancel': 1,
192
+ 'order': 1,
193
+ 'allOpenOrders': 1,
194
+ 'futures_transfer': 1,
195
+ },
196
+ },
197
+ },
198
+ },
199
+ 'dapi': {
200
+ 'v1': {
201
+ 'public': {
202
+ 'get': {
203
+ 'ping': 1,
204
+ 'time': 1,
205
+ 'contracts': 1,
206
+ 'depth': 1,
207
+ 'ticker': 1,
208
+ 'klines': 1,
209
+ },
210
+ },
211
+ },
212
+ 'v2': {
213
+ 'private': {
214
+ 'get': {
215
+ 'myTrades': 1,
216
+ 'openOrders': 1,
217
+ 'order': 1,
218
+ 'account': 1,
219
+ 'leverageBracket': 1,
220
+ 'commissionRate': 1,
221
+ 'futures_transfer_history': 1,
222
+ 'forceOrdersHistory': 1,
223
+ },
224
+ 'post': {
225
+ 'positionMargin': 1,
226
+ 'level_edit': 1,
227
+ 'cancel': 1,
228
+ 'order': 1,
229
+ 'allOpenOrders': 1,
230
+ 'futures_transfer': 1,
231
+ },
232
+ },
233
+ },
234
+ },
235
+ },
236
+ 'fees': {
237
+ 'trading': {
238
+ 'feeSide': 'get',
239
+ 'tierBased': false,
240
+ 'percentage': true,
241
+ 'taker': this.parseNumber('0.00098'),
242
+ 'maker': this.parseNumber('0.00098'),
243
+ },
244
+ 'future': {
245
+ 'trading': {
246
+ 'feeSide': 'quote',
247
+ 'tierBased': true,
248
+ 'percentage': true,
249
+ 'taker': this.parseNumber('0.000400'),
250
+ 'maker': this.parseNumber('0.000200'),
251
+ 'tiers': {
252
+ 'taker': [
253
+ [this.parseNumber('0'), this.parseNumber('0.000400')],
254
+ [this.parseNumber('250'), this.parseNumber('0.000400')],
255
+ [this.parseNumber('2500'), this.parseNumber('0.000350')],
256
+ [this.parseNumber('7500'), this.parseNumber('0.000320')],
257
+ [this.parseNumber('22500'), this.parseNumber('0.000300')],
258
+ [this.parseNumber('50000'), this.parseNumber('0.000270')],
259
+ [this.parseNumber('100000'), this.parseNumber('0.000250')],
260
+ [this.parseNumber('200000'), this.parseNumber('0.000220')],
261
+ [this.parseNumber('400000'), this.parseNumber('0.000200')],
262
+ [this.parseNumber('750000'), this.parseNumber('0.000170')],
263
+ ],
264
+ 'maker': [
265
+ [this.parseNumber('0'), this.parseNumber('0.000200')],
266
+ [this.parseNumber('250'), this.parseNumber('0.000160')],
267
+ [this.parseNumber('2500'), this.parseNumber('0.000140')],
268
+ [this.parseNumber('7500'), this.parseNumber('0.000120')],
269
+ [this.parseNumber('22500'), this.parseNumber('0.000100')],
270
+ [this.parseNumber('50000'), this.parseNumber('0.000080')],
271
+ [this.parseNumber('100000'), this.parseNumber('0.000060')],
272
+ [this.parseNumber('200000'), this.parseNumber('0.000040')],
273
+ [this.parseNumber('400000'), this.parseNumber('0.000020')],
274
+ [this.parseNumber('750000'), this.parseNumber('0')],
275
+ ],
276
+ },
277
+ },
278
+ },
279
+ 'delivery': {
280
+ 'trading': {
281
+ 'feeSide': 'base',
282
+ 'tierBased': true,
283
+ 'percentage': true,
284
+ 'taker': this.parseNumber('0.000500'),
285
+ 'maker': this.parseNumber('0.000100'),
286
+ 'tiers': {
287
+ 'taker': [
288
+ [this.parseNumber('0'), this.parseNumber('0.000500')],
289
+ [this.parseNumber('250'), this.parseNumber('0.000450')],
290
+ [this.parseNumber('2500'), this.parseNumber('0.000400')],
291
+ [this.parseNumber('7500'), this.parseNumber('0.000300')],
292
+ [this.parseNumber('22500'), this.parseNumber('0.000250')],
293
+ [this.parseNumber('50000'), this.parseNumber('0.000240')],
294
+ [this.parseNumber('100000'), this.parseNumber('0.000240')],
295
+ [this.parseNumber('200000'), this.parseNumber('0.000240')],
296
+ [this.parseNumber('400000'), this.parseNumber('0.000240')],
297
+ [this.parseNumber('750000'), this.parseNumber('0.000240')],
298
+ ],
299
+ 'maker': [
300
+ [this.parseNumber('0'), this.parseNumber('0.000100')],
301
+ [this.parseNumber('250'), this.parseNumber('0.000080')],
302
+ [this.parseNumber('2500'), this.parseNumber('0.000050')],
303
+ [this.parseNumber('7500'), this.parseNumber('0.0000030')],
304
+ [this.parseNumber('22500'), this.parseNumber('0')],
305
+ [this.parseNumber('50000'), this.parseNumber('-0.000050')],
306
+ [this.parseNumber('100000'), this.parseNumber('-0.000060')],
307
+ [this.parseNumber('200000'), this.parseNumber('-0.000070')],
308
+ [this.parseNumber('400000'), this.parseNumber('-0.000080')],
309
+ [this.parseNumber('750000'), this.parseNumber('-0.000090')],
310
+ ],
311
+ },
312
+ },
313
+ },
314
+ },
315
+ // exchange-specific options
316
+ 'options': {
317
+ 'createMarketBuyOrderRequiresPrice': true,
318
+ 'fetchMarkets': [
319
+ 'spot',
320
+ 'linear',
321
+ 'inverse',
322
+ ],
323
+ // 'fetchTradesMethod': 'publicGetAggTrades', // publicGetTrades, publicGetHistoricalTrades
324
+ 'fetchMyTradesMethod': 'v2PrivateGetMyTrades',
325
+ 'hasAlreadyAuthenticatedSuccessfully': false,
326
+ 'recvWindow': 5 * 1000,
327
+ 'timeDifference': 0,
328
+ 'adjustForTimeDifference': false,
329
+ 'parseOrderToPrecision': false,
330
+ 'newOrderRespType': {
331
+ 'market': 'FULL',
332
+ 'limit': 'FULL', // we change it from 'ACK' by default to 'FULL' (returns immediately if limit is not hit)
333
+ },
334
+ 'networks': {
335
+ 'ERC20': 'ETH',
336
+ 'TRC20': 'TRX',
337
+ },
338
+ 'defaultType': 'spot',
339
+ 'timeframes': {
340
+ 'spot': {
341
+ '1m': '1m',
342
+ '5m': '5m',
343
+ '15m': '15m',
344
+ '30m': '30m',
345
+ '1h': '1H',
346
+ '2h': '2H',
347
+ '4h': '4H',
348
+ '12h': '12H',
349
+ '1d': '1D',
350
+ '1w': '1W',
351
+ },
352
+ 'future': {
353
+ '1m': '1min',
354
+ '5m': '5min',
355
+ '15m': '15min',
356
+ '30m': '30min',
357
+ '1h': '1h',
358
+ '1d': '1day',
359
+ '1w': '1week',
360
+ '1M': '1month',
361
+ },
362
+ },
363
+ 'accountsByType': {
364
+ 'spot': 'wallet',
365
+ 'future': 'contract',
366
+ 'swap': 'contract',
367
+ 'funding': 'wallet',
368
+ 'fund': 'wallet',
369
+ 'contract': 'contract',
370
+ },
371
+ },
372
+ 'commonCurrencies': {
373
+ 'MIM': 'MIM Swarm',
374
+ },
375
+ 'precisionMode': number.TICK_SIZE,
376
+ // https://binance-docs.github.io/apidocs/spot/en/#error-codes-2
377
+ 'exceptions': {
378
+ 'exact': {
379
+ 'System is under maintenance.': errors.OnMaintenance,
380
+ 'System abnormality': errors.ExchangeError,
381
+ 'You are not authorized to execute this request.': errors.PermissionDenied,
382
+ 'API key does not exist': errors.AuthenticationError,
383
+ 'Order would trigger immediately.': errors.OrderImmediatelyFillable,
384
+ 'Stop price would trigger immediately.': errors.OrderImmediatelyFillable,
385
+ 'Order would immediately match and take.': errors.OrderImmediatelyFillable,
386
+ 'Account has insufficient balance for requested action.': errors.InsufficientFunds,
387
+ 'Rest API trading is not enabled.': errors.ExchangeNotAvailable,
388
+ "You don't have permission.": errors.PermissionDenied,
389
+ 'Market is closed.': errors.ExchangeNotAvailable,
390
+ 'Too many requests. Please try again later.': errors.DDoSProtection,
391
+ '-1000': errors.ExchangeNotAvailable,
392
+ '-1001': errors.ExchangeNotAvailable,
393
+ '-1002': errors.AuthenticationError,
394
+ '-1003': errors.RateLimitExceeded,
395
+ '-1013': errors.InvalidOrder,
396
+ '-1015': errors.RateLimitExceeded,
397
+ '-1016': errors.ExchangeNotAvailable,
398
+ '-1020': errors.BadRequest,
399
+ '-1021': errors.InvalidNonce,
400
+ '-1022': errors.AuthenticationError,
401
+ '-1100': errors.BadRequest,
402
+ '-1101': errors.BadRequest,
403
+ '-1102': errors.BadRequest,
404
+ '-1103': errors.BadRequest,
405
+ '-1104': errors.BadRequest,
406
+ '-1105': errors.BadRequest,
407
+ '-1106': errors.BadRequest,
408
+ '-1111': errors.BadRequest,
409
+ '-1112': errors.InvalidOrder,
410
+ '-1114': errors.BadRequest,
411
+ '-1115': errors.BadRequest,
412
+ '-1116': errors.BadRequest,
413
+ '-1117': errors.BadRequest,
414
+ '-1166': errors.InvalidOrder,
415
+ '-1118': errors.BadRequest,
416
+ '-1119': errors.BadRequest,
417
+ '-1120': errors.BadRequest,
418
+ '-1121': errors.BadSymbol,
419
+ '-1125': errors.AuthenticationError,
420
+ '-1127': errors.BadRequest,
421
+ '-1128': errors.BadRequest,
422
+ '-1130': errors.BadRequest,
423
+ '-1131': errors.BadRequest,
424
+ '-1160': errors.InvalidOrder,
425
+ '-1156': errors.InvalidOrder,
426
+ '-2008': errors.AuthenticationError,
427
+ '-2010': errors.ExchangeError,
428
+ '-2011': errors.OrderNotFound,
429
+ '-2013': errors.OrderNotFound,
430
+ '-2014': errors.AuthenticationError,
431
+ '-2015': errors.AuthenticationError,
432
+ '-2017': errors.InsufficientFunds,
433
+ '-2019': errors.InsufficientFunds,
434
+ '-3005': errors.InsufficientFunds,
435
+ '-3006': errors.InsufficientFunds,
436
+ '-3008': errors.InsufficientFunds,
437
+ '-3010': errors.ExchangeError,
438
+ '-3015': errors.ExchangeError,
439
+ '-3022': errors.AccountSuspended,
440
+ '-4028': errors.BadRequest,
441
+ '-3020': errors.InsufficientFunds,
442
+ '-3041': errors.InsufficientFunds,
443
+ '-5013': errors.InsufficientFunds,
444
+ '-11008': errors.InsufficientFunds,
445
+ '-4051': errors.InsufficientFunds, // {"code":-4051,"msg":"Isolated balance insufficient."}
446
+ },
447
+ 'broad': {
448
+ 'has no operation privilege': errors.PermissionDenied,
449
+ 'MAX_POSITION': errors.InvalidOrder, // {"code":-2010,"msg":"Filter failure: MAX_POSITION"}
450
+ },
451
+ },
452
+ });
453
+ }
454
+ currencyToPrecision(code, fee, networkCode = undefined) {
455
+ // info is available in currencies only if the user has configured his api keys
456
+ if (this.safeValue(this.currencies[code], 'precision') !== undefined) {
457
+ return this.decimalToPrecision(fee, number.TRUNCATE, this.currencies[code]['precision'], this.precisionMode, this.paddingMode);
458
+ }
459
+ else {
460
+ return this.numberToString(fee);
461
+ }
462
+ }
463
+ nonce() {
464
+ return this.milliseconds() - this.options['timeDifference'];
465
+ }
466
+ async fetchStatus(params = {}) {
467
+ /**
468
+ * @method
469
+ * @name bitrue#fetchStatus
470
+ * @description the latest known information on the availability of the exchange API
471
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#test-connectivity
472
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
473
+ * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
474
+ */
475
+ const response = await this.spotV1PublicGetPing(params);
476
+ //
477
+ // empty means working status.
478
+ //
479
+ // {}
480
+ //
481
+ const keys = Object.keys(response);
482
+ const keysLength = keys.length;
483
+ const formattedStatus = keysLength ? 'maintenance' : 'ok';
484
+ return {
485
+ 'status': formattedStatus,
486
+ 'updated': undefined,
487
+ 'eta': undefined,
488
+ 'url': undefined,
489
+ 'info': response,
490
+ };
491
+ }
492
+ async fetchTime(params = {}) {
493
+ /**
494
+ * @method
495
+ * @name bitrue#fetchTime
496
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
497
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#check-server-time
498
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
499
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
500
+ */
501
+ const response = await this.spotV1PublicGetTime(params);
502
+ //
503
+ // {
504
+ // "serverTime":1635467280514
505
+ // }
506
+ //
507
+ return this.safeInteger(response, 'serverTime');
508
+ }
509
+ safeNetwork(networkId) {
510
+ const uppercaseNetworkId = networkId.toUpperCase();
511
+ const networksById = {
512
+ 'Aeternity': 'Aeternity',
513
+ 'AION': 'AION',
514
+ 'Algorand': 'Algorand',
515
+ 'ASK': 'ASK',
516
+ 'ATOM': 'ATOM',
517
+ 'AVAX C-Chain': 'AVAX C-Chain',
518
+ 'bch': 'bch',
519
+ 'BCH': 'BCH',
520
+ 'BEP2': 'BEP2',
521
+ 'BEP20': 'BEP20',
522
+ 'Bitcoin': 'Bitcoin',
523
+ 'BRP20': 'BRP20',
524
+ 'Cardano': 'ADA',
525
+ 'CasinoCoin': 'CasinoCoin',
526
+ 'CasinoCoin XRPL': 'CasinoCoin XRPL',
527
+ 'Contentos': 'Contentos',
528
+ 'Dash': 'Dash',
529
+ 'Decoin': 'Decoin',
530
+ 'DeFiChain': 'DeFiChain',
531
+ 'DGB': 'DGB',
532
+ 'Divi': 'Divi',
533
+ 'dogecoin': 'DOGE',
534
+ 'EOS': 'EOS',
535
+ 'ERC20': 'ERC20',
536
+ 'ETC': 'ETC',
537
+ 'Filecoin': 'Filecoin',
538
+ 'FREETON': 'FREETON',
539
+ 'HBAR': 'HBAR',
540
+ 'Hedera Hashgraph': 'Hedera Hashgraph',
541
+ 'HRC20': 'HRC20',
542
+ 'ICON': 'ICON',
543
+ 'ICP': 'ICP',
544
+ 'Ignis': 'Ignis',
545
+ 'Internet Computer': 'Internet Computer',
546
+ 'IOTA': 'IOTA',
547
+ 'KAVA': 'KAVA',
548
+ 'KSM': 'KSM',
549
+ 'LiteCoin': 'LiteCoin',
550
+ 'Luna': 'Luna',
551
+ 'MATIC': 'MATIC',
552
+ 'Mobile Coin': 'Mobile Coin',
553
+ 'MonaCoin': 'MonaCoin',
554
+ 'Monero': 'Monero',
555
+ 'NEM': 'NEM',
556
+ 'NEP5': 'NEP5',
557
+ 'OMNI': 'OMNI',
558
+ 'PAC': 'PAC',
559
+ 'Polkadot': 'Polkadot',
560
+ 'Ravencoin': 'Ravencoin',
561
+ 'Safex': 'Safex',
562
+ 'SOLANA': 'SOL',
563
+ 'Songbird': 'Songbird',
564
+ 'Stellar Lumens': 'Stellar Lumens',
565
+ 'Symbol': 'Symbol',
566
+ 'Tezos': 'XTZ',
567
+ 'theta': 'theta',
568
+ 'THETA': 'THETA',
569
+ 'TRC20': 'TRC20',
570
+ 'VeChain': 'VeChain',
571
+ 'VECHAIN': 'VECHAIN',
572
+ 'Wanchain': 'Wanchain',
573
+ 'XinFin Network': 'XinFin Network',
574
+ 'XRP': 'XRP',
575
+ 'XRPL': 'XRPL',
576
+ 'ZIL': 'ZIL',
577
+ };
578
+ return this.safeString2(networksById, networkId, uppercaseNetworkId, networkId);
579
+ }
580
+ async fetchCurrencies(params = {}) {
581
+ /**
582
+ * @method
583
+ * @name bitrue#fetchCurrencies
584
+ * @description fetches all available currencies on an exchange
585
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
586
+ * @returns {object} an associative dictionary of currencies
587
+ */
588
+ const response = await this.spotV1PublicGetExchangeInfo(params);
589
+ //
590
+ // {
591
+ // "timezone":"CTT",
592
+ // "serverTime":1635464889117,
593
+ // "rateLimits":[
594
+ // {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
595
+ // {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
596
+ // {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
597
+ // ],
598
+ // "exchangeFilters":[],
599
+ // "symbols":[
600
+ // {
601
+ // "symbol":"SHABTC",
602
+ // "status":"TRADING",
603
+ // "baseAsset":"sha",
604
+ // "baseAssetPrecision":0,
605
+ // "quoteAsset":"btc",
606
+ // "quotePrecision":10,
607
+ // "orderTypes":["MARKET","LIMIT"],
608
+ // "icebergAllowed":false,
609
+ // "filters":[
610
+ // {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
611
+ // {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
612
+ // ],
613
+ // "defaultPrice":"0.0000006100",
614
+ // },
615
+ // ],
616
+ // "coins":[
617
+ // {
618
+ // "coin": "near",
619
+ // "coinFulName": "NEAR Protocol",
620
+ // "chains": [ "BEP20", ],
621
+ // "chainDetail": [
622
+ // {
623
+ // "chain": "BEP20",
624
+ // "enableWithdraw": true,
625
+ // "enableDeposit": true,
626
+ // "withdrawFee": "0.2000",
627
+ // "minWithdraw": "5.0000",
628
+ // "maxWithdraw": "1000000000000000.0000",
629
+ // },
630
+ // ],
631
+ // },
632
+ // ],
633
+ // }
634
+ //
635
+ const result = {};
636
+ const coins = this.safeValue(response, 'coins', []);
637
+ for (let i = 0; i < coins.length; i++) {
638
+ const currency = coins[i];
639
+ const id = this.safeString(currency, 'coin');
640
+ const name = this.safeString(currency, 'coinFulName');
641
+ const code = this.safeCurrencyCode(id);
642
+ let deposit = undefined;
643
+ let withdraw = undefined;
644
+ let minWithdrawString = undefined;
645
+ let maxWithdrawString = undefined;
646
+ let minWithdrawFeeString = undefined;
647
+ const networkDetails = this.safeValue(currency, 'chainDetail', []);
648
+ const networks = {};
649
+ for (let j = 0; j < networkDetails.length; j++) {
650
+ const entry = networkDetails[j];
651
+ const networkId = this.safeString(entry, 'chain');
652
+ const network = this.networkIdToCode(networkId, code);
653
+ const enableDeposit = this.safeValue(entry, 'enableDeposit');
654
+ deposit = (enableDeposit) ? enableDeposit : deposit;
655
+ const enableWithdraw = this.safeValue(entry, 'enableWithdraw');
656
+ withdraw = (enableWithdraw) ? enableWithdraw : withdraw;
657
+ const networkWithdrawFeeString = this.safeString(entry, 'withdrawFee');
658
+ if (networkWithdrawFeeString !== undefined) {
659
+ minWithdrawFeeString = (minWithdrawFeeString === undefined) ? networkWithdrawFeeString : Precise["default"].stringMin(networkWithdrawFeeString, minWithdrawFeeString);
660
+ }
661
+ const networkMinWithdrawString = this.safeString(entry, 'minWithdraw');
662
+ if (networkMinWithdrawString !== undefined) {
663
+ minWithdrawString = (minWithdrawString === undefined) ? networkMinWithdrawString : Precise["default"].stringMin(networkMinWithdrawString, minWithdrawString);
664
+ }
665
+ const networkMaxWithdrawString = this.safeString(entry, 'maxWithdraw');
666
+ if (networkMaxWithdrawString !== undefined) {
667
+ maxWithdrawString = (maxWithdrawString === undefined) ? networkMaxWithdrawString : Precise["default"].stringMax(networkMaxWithdrawString, maxWithdrawString);
668
+ }
669
+ networks[network] = {
670
+ 'info': entry,
671
+ 'id': networkId,
672
+ 'network': network,
673
+ 'deposit': enableDeposit,
674
+ 'withdraw': enableWithdraw,
675
+ 'active': enableDeposit && enableWithdraw,
676
+ 'fee': this.parseNumber(networkWithdrawFeeString),
677
+ 'precision': undefined,
678
+ 'limits': {
679
+ 'withdraw': {
680
+ 'min': this.parseNumber(networkMinWithdrawString),
681
+ 'max': this.parseNumber(networkMaxWithdrawString),
682
+ },
683
+ },
684
+ };
685
+ }
686
+ result[code] = {
687
+ 'id': id,
688
+ 'name': name,
689
+ 'code': code,
690
+ 'precision': undefined,
691
+ 'info': currency,
692
+ 'active': deposit && withdraw,
693
+ 'deposit': deposit,
694
+ 'withdraw': withdraw,
695
+ 'networks': networks,
696
+ 'fee': this.parseNumber(minWithdrawFeeString),
697
+ // 'fees': fees,
698
+ 'limits': {
699
+ 'withdraw': {
700
+ 'min': this.parseNumber(minWithdrawString),
701
+ 'max': this.parseNumber(maxWithdrawString),
702
+ },
703
+ },
704
+ };
705
+ }
706
+ return result;
707
+ }
708
+ async fetchMarkets(params = {}) {
709
+ /**
710
+ * @method
711
+ * @name bitrue#fetchMarkets
712
+ * @description retrieves data on all markets for bitrue
713
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
714
+ * @see https://www.bitrue.com/api-docs#current-open-contract
715
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-open-contract
716
+ * @param {object} [params] extra parameters specific to the exchange api endpoint
717
+ * @returns {object[]} an array of objects representing market data
718
+ */
719
+ const promisesRaw = [];
720
+ const fetchMarkets = this.safeValue(this.options, 'fetchMarkets', ['spot', 'linear', 'inverse']);
721
+ for (let i = 0; i < fetchMarkets.length; i++) {
722
+ const marketType = fetchMarkets[i];
723
+ if (marketType === 'spot') {
724
+ promisesRaw.push(this.spotV1PublicGetExchangeInfo(params));
725
+ }
726
+ else if (marketType === 'linear') {
727
+ promisesRaw.push(this.fapiV1PublicGetContracts(params));
728
+ }
729
+ else if (marketType === 'inverse') {
730
+ promisesRaw.push(this.dapiV1PublicGetContracts(params));
731
+ }
732
+ else {
733
+ throw new errors.ExchangeError(this.id + ' fetchMarkets() this.options fetchMarkets "' + marketType + '" is not a supported market type');
734
+ }
735
+ }
736
+ const promises = await Promise.all(promisesRaw);
737
+ const spotMarkets = this.safeValue(this.safeValue(promises, 0), 'symbols', []);
738
+ const futureMarkets = this.safeValue(promises, 1);
739
+ const deliveryMarkets = this.safeValue(promises, 2);
740
+ let markets = spotMarkets;
741
+ markets = this.arrayConcat(markets, futureMarkets);
742
+ markets = this.arrayConcat(markets, deliveryMarkets);
743
+ //
744
+ // spot
745
+ //
746
+ // {
747
+ // "timezone":"CTT",
748
+ // "serverTime":1635464889117,
749
+ // "rateLimits":[
750
+ // {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000},
751
+ // {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150},
752
+ // {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000},
753
+ // ],
754
+ // "exchangeFilters":[],
755
+ // "symbols":[
756
+ // {
757
+ // "symbol":"SHABTC",
758
+ // "status":"TRADING",
759
+ // "baseAsset":"sha",
760
+ // "baseAssetPrecision":0,
761
+ // "quoteAsset":"btc",
762
+ // "quotePrecision":10,
763
+ // "orderTypes":["MARKET","LIMIT"],
764
+ // "icebergAllowed":false,
765
+ // "filters":[
766
+ // {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10},
767
+ // {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0},
768
+ // ],
769
+ // "defaultPrice":"0.0000006100",
770
+ // },
771
+ // ],
772
+ // "coins":[
773
+ // {
774
+ // "coin":"sbr",
775
+ // "coinFulName":"Saber",
776
+ // "enableWithdraw":true,
777
+ // "enableDeposit":true,
778
+ // "chains":["SOLANA"],
779
+ // "withdrawFee":"2.0",
780
+ // "minWithdraw":"5.0",
781
+ // "maxWithdraw":"1000000000000000",
782
+ // },
783
+ // ],
784
+ // }
785
+ //
786
+ // swap / delivery
787
+ //
788
+ // [
789
+ // {
790
+ // "symbol": "H-HT-USDT",
791
+ // "pricePrecision": 8,
792
+ // "side": 1,
793
+ // "maxMarketVolume": 100000,
794
+ // "multiplier": 6,
795
+ // "minOrderVolume": 1,
796
+ // "maxMarketMoney": 10000000,
797
+ // "type": "H", // E: perpetual contract, S: test contract, others are mixed contract
798
+ // "maxLimitVolume": 1000000,
799
+ // "maxValidOrder": 20,
800
+ // "multiplierCoin": "HT",
801
+ // "minOrderMoney": 0.001,
802
+ // "maxLimitMoney": 1000000,
803
+ // "status": 1
804
+ // }
805
+ // ]
806
+ //
807
+ if (this.options['adjustForTimeDifference']) {
808
+ await this.loadTimeDifference();
809
+ }
810
+ return this.parseMarkets(markets);
811
+ }
812
+ parseMarket(market) {
813
+ const id = this.safeString(market, 'symbol');
814
+ const lowercaseId = this.safeStringLower(market, 'symbol');
815
+ const side = this.safeInteger(market, 'side'); // 1 linear, 0 inverse, undefined spot
816
+ let type = undefined;
817
+ let isLinear = undefined;
818
+ let isInverse = undefined;
819
+ if (side === undefined) {
820
+ type = 'spot';
821
+ }
822
+ else {
823
+ type = 'swap';
824
+ isLinear = (side === 1);
825
+ isInverse = (side === 0);
826
+ }
827
+ const isContract = (type !== 'spot');
828
+ let baseId = this.safeString(market, 'baseAsset');
829
+ let quoteId = this.safeString(market, 'quoteAsset');
830
+ let settleId = undefined;
831
+ let settle = undefined;
832
+ if (isContract) {
833
+ const symbolSplit = id.split('-');
834
+ baseId = this.safeString(symbolSplit, 1);
835
+ quoteId = this.safeString(symbolSplit, 2);
836
+ if (isLinear) {
837
+ settleId = quoteId;
838
+ }
839
+ else {
840
+ settleId = baseId;
841
+ }
842
+ settle = this.safeCurrencyCode(settleId);
843
+ }
844
+ const base = this.safeCurrencyCode(baseId);
845
+ const quote = this.safeCurrencyCode(quoteId);
846
+ let symbol = base + '/' + quote;
847
+ if (settle !== undefined) {
848
+ symbol += ':' + settle;
849
+ }
850
+ const filters = this.safeValue(market, 'filters', []);
851
+ const filtersByType = this.indexBy(filters, 'filterType');
852
+ const status = this.safeString(market, 'status');
853
+ const priceFilter = this.safeValue(filtersByType, 'PRICE_FILTER', {});
854
+ const amountFilter = this.safeValue(filtersByType, 'LOT_SIZE', {});
855
+ const defaultPricePrecision = this.safeString(market, 'pricePrecision');
856
+ const defaultAmountPrecision = this.safeString(market, 'quantityPrecision');
857
+ const pricePrecision = this.safeString(priceFilter, 'priceScale', defaultPricePrecision);
858
+ const amountPrecision = this.safeString(amountFilter, 'volumeScale', defaultAmountPrecision);
859
+ const multiplier = this.safeString(market, 'multiplier');
860
+ let maxQuantity = this.safeNumber(amountFilter, 'maxQty');
861
+ if (maxQuantity === undefined) {
862
+ maxQuantity = this.safeNumber(market, 'maxValidOrder');
863
+ }
864
+ let minCost = this.safeNumber(amountFilter, 'minVal');
865
+ if (minCost === undefined) {
866
+ minCost = this.safeNumber(market, 'minOrderMoney');
867
+ }
868
+ return {
869
+ 'id': id,
870
+ 'lowercaseId': lowercaseId,
871
+ 'symbol': symbol,
872
+ 'base': base,
873
+ 'quote': quote,
874
+ 'settle': settle,
875
+ 'baseId': baseId,
876
+ 'quoteId': quoteId,
877
+ 'settleId': settleId,
878
+ 'type': type,
879
+ 'spot': (type === 'spot'),
880
+ 'margin': false,
881
+ 'swap': isContract,
882
+ 'future': false,
883
+ 'option': false,
884
+ 'active': (status === 'TRADING'),
885
+ 'contract': isContract,
886
+ 'linear': isLinear,
887
+ 'inverse': isInverse,
888
+ 'contractSize': this.parseNumber(Precise["default"].stringAbs(multiplier)),
889
+ 'expiry': undefined,
890
+ 'expiryDatetime': undefined,
891
+ 'strike': undefined,
892
+ 'optionType': undefined,
893
+ 'precision': {
894
+ 'amount': this.parseNumber(this.parsePrecision(amountPrecision)),
895
+ 'price': this.parseNumber(this.parsePrecision(pricePrecision)),
896
+ },
897
+ 'limits': {
898
+ 'leverage': {
899
+ 'min': undefined,
900
+ 'max': undefined,
901
+ },
902
+ 'amount': {
903
+ 'min': this.safeNumber(amountFilter, 'minQty'),
904
+ 'max': maxQuantity,
905
+ },
906
+ 'price': {
907
+ 'min': this.safeNumber(priceFilter, 'minPrice'),
908
+ 'max': this.safeNumber(priceFilter, 'maxPrice'),
909
+ },
910
+ 'cost': {
911
+ 'min': minCost,
912
+ 'max': undefined,
913
+ },
914
+ },
915
+ 'created': undefined,
916
+ 'info': market,
917
+ };
918
+ }
919
+ parseBalance(response) {
920
+ //
921
+ // spot
922
+ //
923
+ // {
924
+ // "makerCommission":0,
925
+ // "takerCommission":0,
926
+ // "buyerCommission":0,
927
+ // "sellerCommission":0,
928
+ // "updateTime":null,
929
+ // "balances":[
930
+ // {"asset":"sbr","free":"0","locked":"0"},
931
+ // {"asset":"ksm","free":"0","locked":"0"},
932
+ // {"asset":"neo3s","free":"0","locked":"0"},
933
+ // ],
934
+ // "canTrade":false,
935
+ // "canWithdraw":false,
936
+ // "canDeposit":false
937
+ // }
938
+ //
939
+ // swap
940
+ //
941
+ // {
942
+ // "account":[
943
+ // {
944
+ // "marginCoin":"USDT",
945
+ // "coinPrecious":4,
946
+ // "accountNormal":1010.4043400372839856,
947
+ // "accountLock":2.9827889600000006,
948
+ // "partPositionNormal":0,
949
+ // "totalPositionNormal":0,
950
+ // "achievedAmount":0,
951
+ // "unrealizedAmount":0,
952
+ // "totalMarginRate":0,
953
+ // "totalEquity":1010.4043400372839856,
954
+ // "partEquity":0,
955
+ // "totalCost":0,
956
+ // "sumMarginRate":0,
957
+ // "sumOpenRealizedAmount":0,
958
+ // "canUseTrialFund":0,
959
+ // "sumMaintenanceMargin":null,
960
+ // "futureModel":null,
961
+ // "positionVos":[]
962
+ // }
963
+ // ]
964
+ // }
965
+ //
966
+ const result = {
967
+ 'info': response,
968
+ };
969
+ const timestamp = this.safeInteger(response, 'updateTime');
970
+ const balances = this.safeValue2(response, 'balances', 'account', []);
971
+ for (let i = 0; i < balances.length; i++) {
972
+ const balance = balances[i];
973
+ const currencyId = this.safeString2(balance, 'asset', 'marginCoin');
974
+ const code = this.safeCurrencyCode(currencyId);
975
+ const account = this.account();
976
+ account['free'] = this.safeString2(balance, 'free', 'accountNormal');
977
+ account['used'] = this.safeString2(balance, 'locked', 'accountLock');
978
+ result[code] = account;
979
+ }
980
+ result['timestamp'] = timestamp;
981
+ result['datetime'] = this.iso8601(timestamp);
982
+ return this.safeBalance(result);
983
+ }
984
+ async fetchBalance(params = {}) {
985
+ /**
986
+ * @method
987
+ * @name bitrue#fetchBalance
988
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
989
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-information-user_data
990
+ * @see https://www.bitrue.com/api-docs#account-information-v2-user_data-hmac-sha256
991
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-information-v2-user_data-hmac-sha256
992
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
993
+ * @param {string} [params.type] 'future', 'delivery', 'spot', 'swap'
994
+ * @param {string} [params.subType] 'linear', 'inverse'
995
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
996
+ */
997
+ await this.loadMarkets();
998
+ let type = undefined;
999
+ [type, params] = this.handleMarketTypeAndParams('fetchBalance', undefined, params);
1000
+ let subType = undefined;
1001
+ [subType, params] = this.handleSubTypeAndParams('fetchBalance', undefined, params);
1002
+ let response = undefined;
1003
+ let result = undefined;
1004
+ if (type === 'swap') {
1005
+ if (subType !== undefined && subType === 'inverse') {
1006
+ response = await this.dapiV2PrivateGetAccount(params);
1007
+ result = this.safeValue(response, 'data', {});
1008
+ //
1009
+ // {
1010
+ // "code":"0",
1011
+ // "msg":"Success",
1012
+ // "data":{
1013
+ // "account":[
1014
+ // {
1015
+ // "marginCoin":"USD",
1016
+ // "coinPrecious":4,
1017
+ // "accountNormal":1010.4043400372839856,
1018
+ // "accountLock":2.9827889600000006,
1019
+ // "partPositionNormal":0,
1020
+ // "totalPositionNormal":0,
1021
+ // "achievedAmount":0,
1022
+ // "unrealizedAmount":0,
1023
+ // "totalMarginRate":0,
1024
+ // "totalEquity":1010.4043400372839856,
1025
+ // "partEquity":0,
1026
+ // "totalCost":0,
1027
+ // "sumMarginRate":0,
1028
+ // "sumOpenRealizedAmount":0,
1029
+ // "canUseTrialFund":0,
1030
+ // "sumMaintenanceMargin":null,
1031
+ // "futureModel":null,
1032
+ // "positionVos":[]
1033
+ // }
1034
+ // ]
1035
+ // }
1036
+ // }
1037
+ //
1038
+ }
1039
+ else {
1040
+ response = await this.fapiV2PrivateGetAccount(params);
1041
+ result = this.safeValue(response, 'data', {});
1042
+ //
1043
+ // {
1044
+ // "code":"0",
1045
+ // "msg":"Success",
1046
+ // "data":{
1047
+ // "account":[
1048
+ // {
1049
+ // "marginCoin":"USDT",
1050
+ // "coinPrecious":4,
1051
+ // "accountNormal":1010.4043400372839856,
1052
+ // "accountLock":2.9827889600000006,
1053
+ // "partPositionNormal":0,
1054
+ // "totalPositionNormal":0,
1055
+ // "achievedAmount":0,
1056
+ // "unrealizedAmount":0,
1057
+ // "totalMarginRate":0,
1058
+ // "totalEquity":1010.4043400372839856,
1059
+ // "partEquity":0,
1060
+ // "totalCost":0,
1061
+ // "sumMarginRate":0,
1062
+ // "sumOpenRealizedAmount":0,
1063
+ // "canUseTrialFund":0,
1064
+ // "sumMaintenanceMargin":null,
1065
+ // "futureModel":null,
1066
+ // "positionVos":[]
1067
+ // }
1068
+ // ]
1069
+ // }
1070
+ // }
1071
+ //
1072
+ }
1073
+ }
1074
+ else {
1075
+ response = await this.spotV1PrivateGetAccount(params);
1076
+ result = response;
1077
+ //
1078
+ // {
1079
+ // "makerCommission":0,
1080
+ // "takerCommission":0,
1081
+ // "buyerCommission":0,
1082
+ // "sellerCommission":0,
1083
+ // "updateTime":null,
1084
+ // "balances":[
1085
+ // {"asset":"sbr","free":"0","locked":"0"},
1086
+ // {"asset":"ksm","free":"0","locked":"0"},
1087
+ // {"asset":"neo3s","free":"0","locked":"0"},
1088
+ // ],
1089
+ // "canTrade":false,
1090
+ // "canWithdraw":false,
1091
+ // "canDeposit":false
1092
+ // }
1093
+ //
1094
+ }
1095
+ return this.parseBalance(result);
1096
+ }
1097
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
1098
+ /**
1099
+ * @method
1100
+ * @name bitrue#fetchOrderBook
1101
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
1102
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#order-book
1103
+ * @see https://www.bitrue.com/api-docs#order-book
1104
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#order-book
1105
+ * @param {string} symbol unified symbol of the market to fetch the order book for
1106
+ * @param {int} [limit] the maximum amount of order book entries to return
1107
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1108
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
1109
+ */
1110
+ await this.loadMarkets();
1111
+ const market = this.market(symbol);
1112
+ let response = undefined;
1113
+ if (market['swap']) {
1114
+ const request = {
1115
+ 'contractName': market['id'],
1116
+ };
1117
+ if (limit !== undefined) {
1118
+ if (limit > 100) {
1119
+ limit = 100;
1120
+ }
1121
+ request['limit'] = limit; // default 100, max 100, see https://www.bitrue.com/api-docs#order-book
1122
+ }
1123
+ if (market['linear']) {
1124
+ response = await this.fapiV1PublicGetDepth(this.extend(request, params));
1125
+ }
1126
+ else if (market['inverse']) {
1127
+ response = await this.dapiV1PublicGetDepth(this.extend(request, params));
1128
+ }
1129
+ }
1130
+ else if (market['spot']) {
1131
+ const request = {
1132
+ 'symbol': market['id'],
1133
+ };
1134
+ if (limit !== undefined) {
1135
+ if (limit > 1000) {
1136
+ limit = 1000;
1137
+ }
1138
+ request['limit'] = limit; // default 100, max 1000, see https://github.com/Bitrue-exchange/bitrue-official-api-docs#order-book
1139
+ }
1140
+ response = await this.spotV1PublicGetDepth(this.extend(request, params));
1141
+ }
1142
+ else {
1143
+ throw new errors.NotSupported(this.id + ' fetchOrderBook only support spot & swap markets');
1144
+ }
1145
+ //
1146
+ // spot
1147
+ //
1148
+ // {
1149
+ // "lastUpdateId":1635474910177,
1150
+ // "bids":[
1151
+ // ["61436.84","0.05",[]],
1152
+ // ["61435.77","0.0124",[]],
1153
+ // ["61434.88","0.012",[]],
1154
+ // ],
1155
+ // "asks":[
1156
+ // ["61452.46","0.0001",[]],
1157
+ // ["61452.47","0.0597",[]],
1158
+ // ["61452.76","0.0713",[]],
1159
+ // ]
1160
+ // }
1161
+ //
1162
+ // swap
1163
+ //
1164
+ // {
1165
+ // "asks": [[34916.5, 2582], [34916.6, 2193], [34916.7, 2629], [34916.8, 3478], [34916.9, 2718]],
1166
+ // "bids": [[34916.4, 92065], [34916.3, 25703], [34916.2, 37259], [34916.1, 26446], [34916, 44456]],
1167
+ // "time": 1699338305000
1168
+ // }
1169
+ //
1170
+ const timestamp = this.safeInteger(response, 'time');
1171
+ const orderbook = this.parseOrderBook(response, symbol, timestamp);
1172
+ orderbook['nonce'] = this.safeInteger(response, 'lastUpdateId');
1173
+ return orderbook;
1174
+ }
1175
+ parseTicker(ticker, market = undefined) {
1176
+ //
1177
+ // fetchBidsAsks
1178
+ //
1179
+ // {
1180
+ // "symbol": "LTCBTC",
1181
+ // "bidPrice": "4.00000000",
1182
+ // "bidQty": "431.00000000",
1183
+ // "askPrice": "4.00000200",
1184
+ // "askQty": "9.00000000"
1185
+ // }
1186
+ //
1187
+ // fetchTicker
1188
+ //
1189
+ // {
1190
+ // "symbol": "BNBBTC",
1191
+ // "priceChange": "0.000248",
1192
+ // "priceChangePercent": "3.5500",
1193
+ // "weightedAvgPrice": null,
1194
+ // "prevClosePrice": null,
1195
+ // "lastPrice": "0.007226",
1196
+ // "lastQty": null,
1197
+ // "bidPrice": "0.007208",
1198
+ // "askPrice": "0.007240",
1199
+ // "openPrice": "0.006978",
1200
+ // "highPrice": "0.007295",
1201
+ // "lowPrice": "0.006935",
1202
+ // "volume": "11749.86",
1203
+ // "quoteVolume": "84.1066211",
1204
+ // "openTime": 0,
1205
+ // "closeTime": 0,
1206
+ // "firstId": 0,
1207
+ // "lastId": 0,
1208
+ // "count": 0
1209
+ // }
1210
+ //
1211
+ const symbol = this.safeSymbol(undefined, market);
1212
+ const last = this.safeString2(ticker, 'lastPrice', 'last');
1213
+ const timestamp = this.safeInteger(ticker, 'time');
1214
+ let percentage = undefined;
1215
+ if (market['swap']) {
1216
+ percentage = Precise["default"].stringMul(this.safeString(ticker, 'rose'), '100');
1217
+ }
1218
+ else {
1219
+ percentage = this.safeString(ticker, 'priceChangePercent');
1220
+ }
1221
+ return this.safeTicker({
1222
+ 'symbol': symbol,
1223
+ 'timestamp': timestamp,
1224
+ 'datetime': this.iso8601(timestamp),
1225
+ 'high': this.safeString2(ticker, 'highPrice', 'high'),
1226
+ 'low': this.safeString2(ticker, 'lowPrice', 'low'),
1227
+ 'bid': this.safeString2(ticker, 'bidPrice', 'buy'),
1228
+ 'bidVolume': this.safeString(ticker, 'bidQty'),
1229
+ 'ask': this.safeString2(ticker, 'askPrice', 'sell'),
1230
+ 'askVolume': this.safeString(ticker, 'askQty'),
1231
+ 'vwap': this.safeString(ticker, 'weightedAvgPrice'),
1232
+ 'open': this.safeString(ticker, 'openPrice'),
1233
+ 'close': last,
1234
+ 'last': last,
1235
+ 'previousClose': undefined,
1236
+ 'change': this.safeString(ticker, 'priceChange'),
1237
+ 'percentage': percentage,
1238
+ 'average': undefined,
1239
+ 'baseVolume': this.safeString2(ticker, 'volume', 'vol'),
1240
+ 'quoteVolume': this.safeString(ticker, 'quoteVolume'),
1241
+ 'info': ticker,
1242
+ }, market);
1243
+ }
1244
+ async fetchTicker(symbol, params = {}) {
1245
+ /**
1246
+ * @method
1247
+ * @name bitrue#fetchTicker
1248
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1249
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
1250
+ * @see https://www.bitrue.com/api-docs#ticker
1251
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
1252
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1253
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1254
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1255
+ */
1256
+ await this.loadMarkets();
1257
+ const market = this.market(symbol);
1258
+ let response = undefined;
1259
+ let data = undefined;
1260
+ if (market['swap']) {
1261
+ const request = {
1262
+ 'contractName': market['id'],
1263
+ };
1264
+ if (market['linear']) {
1265
+ response = await this.fapiV1PublicGetTicker(this.extend(request, params));
1266
+ }
1267
+ else if (market['inverse']) {
1268
+ response = await this.dapiV1PublicGetTicker(this.extend(request, params));
1269
+ }
1270
+ data = response;
1271
+ }
1272
+ else if (market['spot']) {
1273
+ const request = {
1274
+ 'symbol': market['id'],
1275
+ };
1276
+ response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
1277
+ data = this.safeValue(response, 0, {});
1278
+ }
1279
+ else {
1280
+ throw new errors.NotSupported(this.id + ' fetchTicker only support spot & swap markets');
1281
+ }
1282
+ //
1283
+ // spot
1284
+ //
1285
+ // [{
1286
+ // symbol: 'BTCUSDT',
1287
+ // priceChange: '105.20',
1288
+ // priceChangePercent: '0.3000',
1289
+ // weightedAvgPrice: null,
1290
+ // prevClosePrice: null,
1291
+ // lastPrice: '34905.21',
1292
+ // lastQty: null,
1293
+ // bidPrice: '34905.21',
1294
+ // askPrice: '34905.22',
1295
+ // openPrice: '34800.01',
1296
+ // highPrice: '35276.33',
1297
+ // lowPrice: '34787.51',
1298
+ // volume: '12549.6481',
1299
+ // quoteVolume: '439390492.917',
1300
+ // openTime: '0',
1301
+ // closeTime: '0',
1302
+ // firstId: '0',
1303
+ // lastId: '0',
1304
+ // count: '0'
1305
+ // }]
1306
+ //
1307
+ // swap
1308
+ //
1309
+ // {
1310
+ // "high": "35296",
1311
+ // "vol": "779308354",
1312
+ // "last": "34884.1",
1313
+ // "low": "34806.7",
1314
+ // "buy": 34883.9,
1315
+ // "sell": 34884,
1316
+ // "rose": "-0.0027957315",
1317
+ // "time": 1699348013000
1318
+ // }
1319
+ //
1320
+ return this.parseTicker(data, market);
1321
+ }
1322
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
1323
+ /**
1324
+ * @method
1325
+ * @name bitrue#fetchOHLCV
1326
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1327
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#kline-data
1328
+ * @see https://www.bitrue.com/api-docs#kline-candlestick-data
1329
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#kline-candlestick-data
1330
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
1331
+ * @param {string} timeframe the length of time each candle represents
1332
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
1333
+ * @param {int} [limit] the maximum amount of candles to fetch
1334
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1335
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
1336
+ */
1337
+ await this.loadMarkets();
1338
+ const market = this.market(symbol);
1339
+ const timeframes = this.safeValue(this.options, 'timeframes', {});
1340
+ let response = undefined;
1341
+ let data = undefined;
1342
+ if (market['swap']) {
1343
+ const timeframesFuture = this.safeValue(timeframes, 'future', {});
1344
+ const request = {
1345
+ 'contractName': market['id'],
1346
+ // 1min / 5min / 15min / 30min / 1h / 1day / 1week / 1month
1347
+ 'interval': this.safeString(timeframesFuture, timeframe, '1min'),
1348
+ };
1349
+ if (limit !== undefined) {
1350
+ if (limit > 300) {
1351
+ limit = 300;
1352
+ }
1353
+ request['limit'] = limit;
1354
+ }
1355
+ if (market['linear']) {
1356
+ response = await this.fapiV1PublicGetKlines(this.extend(request, params));
1357
+ }
1358
+ else if (market['inverse']) {
1359
+ response = await this.dapiV1PublicGetKlines(this.extend(request, params));
1360
+ }
1361
+ data = response;
1362
+ }
1363
+ else if (market['spot']) {
1364
+ const timeframesSpot = this.safeValue(timeframes, 'spot', {});
1365
+ const request = {
1366
+ 'symbol': market['id'],
1367
+ // 1m / 5m / 15m / 30m / 1H / 2H / 4H / 12H / 1D / 1W
1368
+ 'scale': this.safeString(timeframesSpot, timeframe, '1m'),
1369
+ };
1370
+ if (limit !== undefined) {
1371
+ if (limit > 1440) {
1372
+ limit = 1440;
1373
+ }
1374
+ request['limit'] = limit;
1375
+ }
1376
+ if (since !== undefined) {
1377
+ request['fromIdx'] = since;
1378
+ }
1379
+ response = await this.spotV1PublicGetMarketKline(this.extend(request, params));
1380
+ data = this.safeValue(response, 'data', []);
1381
+ }
1382
+ else {
1383
+ throw new errors.NotSupported(this.id + ' fetchOHLCV only support spot & swap markets');
1384
+ }
1385
+ //
1386
+ // spot
1387
+ //
1388
+ // {
1389
+ // "symbol":"BTCUSDT",
1390
+ // "scale":"KLINE_1MIN",
1391
+ // "data":[
1392
+ // {
1393
+ // "i":"1660825020",
1394
+ // "a":"93458.778",
1395
+ // "v":"3.9774",
1396
+ // "c":"23494.99",
1397
+ // "h":"23509.63",
1398
+ // "l":"23491.93",
1399
+ // "o":"23508.34"
1400
+ // }
1401
+ // ]
1402
+ // }
1403
+ //
1404
+ // swap
1405
+ //
1406
+ // [
1407
+ // {
1408
+ // "high": "35360.7",
1409
+ // "vol": "110288",
1410
+ // "low": "35347.9",
1411
+ // "idx": 1699411680000,
1412
+ // "close": "35347.9",
1413
+ // "open": "35349.4"
1414
+ // }
1415
+ // ]
1416
+ //
1417
+ return this.parseOHLCVs(data, market, timeframe, since, limit);
1418
+ }
1419
+ parseOHLCV(ohlcv, market = undefined) {
1420
+ //
1421
+ // spot
1422
+ //
1423
+ // {
1424
+ // "i":"1660825020",
1425
+ // "a":"93458.778",
1426
+ // "v":"3.9774",
1427
+ // "c":"23494.99",
1428
+ // "h":"23509.63",
1429
+ // "l":"23491.93",
1430
+ // "o":"23508.34"
1431
+ // }
1432
+ //
1433
+ // swap
1434
+ //
1435
+ // {
1436
+ // "high": "35360.7",
1437
+ // "vol": "110288",
1438
+ // "low": "35347.9",
1439
+ // "idx": 1699411680000,
1440
+ // "close": "35347.9",
1441
+ // "open": "35349.4"
1442
+ // }
1443
+ //
1444
+ let timestamp = this.safeTimestamp(ohlcv, 'i');
1445
+ if (timestamp === undefined) {
1446
+ timestamp = this.safeInteger(ohlcv, 'idx');
1447
+ }
1448
+ return [
1449
+ timestamp,
1450
+ this.safeNumber2(ohlcv, 'o', 'open'),
1451
+ this.safeNumber2(ohlcv, 'h', 'high'),
1452
+ this.safeNumber2(ohlcv, 'l', 'low'),
1453
+ this.safeNumber2(ohlcv, 'c', 'close'),
1454
+ this.safeNumber2(ohlcv, 'v', 'vol'),
1455
+ ];
1456
+ }
1457
+ async fetchBidsAsks(symbols = undefined, params = {}) {
1458
+ /**
1459
+ * @method
1460
+ * @name bitrue#fetchBidsAsks
1461
+ * @description fetches the bid and ask price and volume for multiple markets
1462
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#symbol-order-book-ticker
1463
+ * @see https://www.bitrue.com/api-docs#ticker
1464
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
1465
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
1466
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1467
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1468
+ */
1469
+ await this.loadMarkets();
1470
+ symbols = this.marketSymbols(symbols, undefined, false);
1471
+ const first = this.safeString(symbols, 0);
1472
+ const market = this.market(first);
1473
+ let response = undefined;
1474
+ if (market['swap']) {
1475
+ const request = {
1476
+ 'contractName': market['id'],
1477
+ };
1478
+ if (market['linear']) {
1479
+ response = await this.fapiV1PublicGetTicker(this.extend(request, params));
1480
+ }
1481
+ else if (market['inverse']) {
1482
+ response = await this.dapiV1PublicGetTicker(this.extend(request, params));
1483
+ }
1484
+ }
1485
+ else if (market['spot']) {
1486
+ const request = {
1487
+ 'symbol': market['id'],
1488
+ };
1489
+ response = await this.spotV1PublicGetTickerBookTicker(this.extend(request, params));
1490
+ }
1491
+ else {
1492
+ throw new errors.NotSupported(this.id + ' fetchBidsAsks only support spot & swap markets');
1493
+ }
1494
+ //
1495
+ // spot
1496
+ //
1497
+ // {
1498
+ // "symbol": "LTCBTC",
1499
+ // "bidPrice": "4.00000000",
1500
+ // "bidQty": "431.00000000",
1501
+ // "askPrice": "4.00000200",
1502
+ // "askQty": "9.00000000"
1503
+ // }
1504
+ //
1505
+ // swap
1506
+ //
1507
+ // {
1508
+ // "high": "35296",
1509
+ // "vol": "779308354",
1510
+ // "last": "34884.1",
1511
+ // "low": "34806.7",
1512
+ // "buy": 34883.9,
1513
+ // "sell": 34884,
1514
+ // "rose": "-0.0027957315",
1515
+ // "time": 1699348013000
1516
+ // }
1517
+ //
1518
+ const data = {};
1519
+ data[market['id']] = response;
1520
+ return this.parseTickers(data, symbols);
1521
+ }
1522
+ async fetchTickers(symbols = undefined, params = {}) {
1523
+ /**
1524
+ * @method
1525
+ * @name bitrue#fetchTickers
1526
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1527
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics
1528
+ * @see https://www.bitrue.com/api-docs#ticker
1529
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker
1530
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1531
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1532
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1533
+ */
1534
+ await this.loadMarkets();
1535
+ symbols = this.marketSymbols(symbols);
1536
+ let response = undefined;
1537
+ let data = undefined;
1538
+ const request = {};
1539
+ let type = undefined;
1540
+ if (symbols !== undefined) {
1541
+ const first = this.safeString(symbols, 0);
1542
+ const market = this.market(first);
1543
+ if (market['swap']) {
1544
+ throw new errors.NotSupported(this.id + ' fetchTickers does not support swap markets, please use fetchTicker instead');
1545
+ }
1546
+ else if (market['spot']) {
1547
+ response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
1548
+ data = response;
1549
+ }
1550
+ else {
1551
+ throw new errors.NotSupported(this.id + ' fetchTickers only support spot & swap markets');
1552
+ }
1553
+ }
1554
+ else {
1555
+ [type, params] = this.handleMarketTypeAndParams('fetchTickers', undefined, params);
1556
+ if (type !== 'spot') {
1557
+ throw new errors.NotSupported(this.id + ' fetchTickers only support spot when symbols are not proved');
1558
+ }
1559
+ response = await this.spotV1PublicGetTicker24hr(this.extend(request, params));
1560
+ data = response;
1561
+ }
1562
+ //
1563
+ // spot
1564
+ //
1565
+ // [{
1566
+ // symbol: 'BTCUSDT',
1567
+ // priceChange: '105.20',
1568
+ // priceChangePercent: '0.3000',
1569
+ // weightedAvgPrice: null,
1570
+ // prevClosePrice: null,
1571
+ // lastPrice: '34905.21',
1572
+ // lastQty: null,
1573
+ // bidPrice: '34905.21',
1574
+ // askPrice: '34905.22',
1575
+ // openPrice: '34800.01',
1576
+ // highPrice: '35276.33',
1577
+ // lowPrice: '34787.51',
1578
+ // volume: '12549.6481',
1579
+ // quoteVolume: '439390492.917',
1580
+ // openTime: '0',
1581
+ // closeTime: '0',
1582
+ // firstId: '0',
1583
+ // lastId: '0',
1584
+ // count: '0'
1585
+ // }]
1586
+ //
1587
+ // swap
1588
+ //
1589
+ // {
1590
+ // "high": "35296",
1591
+ // "vol": "779308354",
1592
+ // "last": "34884.1",
1593
+ // "low": "34806.7",
1594
+ // "buy": 34883.9,
1595
+ // "sell": 34884,
1596
+ // "rose": "-0.0027957315",
1597
+ // "time": 1699348013000
1598
+ // }
1599
+ //
1600
+ // the exchange returns market ids with an underscore from the tickers endpoint
1601
+ // the market ids do not have an underscore, so it has to be removed
1602
+ // https://github.com/ccxt/ccxt/issues/13856
1603
+ const tickers = {};
1604
+ for (let i = 0; i < data.length; i++) {
1605
+ const ticker = this.safeValue(data, i, {});
1606
+ const market = this.market(this.safeValue(ticker, 'symbol'));
1607
+ tickers[market['id']] = ticker;
1608
+ }
1609
+ return this.parseTickers(tickers, symbols);
1610
+ }
1611
+ parseTrade(trade, market = undefined) {
1612
+ //
1613
+ // fetchTrades
1614
+ //
1615
+ // {
1616
+ // "id": 28457,
1617
+ // "price": "4.00000100",
1618
+ // "qty": "12.00000000",
1619
+ // "time": 1499865549590, // Actual timestamp of trade
1620
+ // "isBuyerMaker": true,
1621
+ // "isBestMatch": true
1622
+ // }
1623
+ //
1624
+ // fetchTrades - spot
1625
+ //
1626
+ // {
1627
+ // "symbol":"USDCUSDT",
1628
+ // "id":20725156,
1629
+ // "orderId":2880918576,
1630
+ // "origClientOrderId":null,
1631
+ // "price":"0.9996000000000000",
1632
+ // "qty":"100.0000000000000000",
1633
+ // "commission":null,
1634
+ // "commissionAssert":null,
1635
+ // "time":1635558511000,
1636
+ // "isBuyer":false,
1637
+ // "isMaker":false,
1638
+ // "isBestMatch":true
1639
+ // }
1640
+ //
1641
+ // fetchTrades - future
1642
+ //
1643
+ // {
1644
+ // "tradeId":12,
1645
+ // "price":0.9,
1646
+ // "qty":1,
1647
+ // "amount":9,
1648
+ // "contractName":"E-SAND-USDT",
1649
+ // "side":"BUY",
1650
+ // "fee":"0.0018",
1651
+ // "bidId":1558124009467904992,
1652
+ // "askId":1558124043827644908,
1653
+ // "bidUserId":10294,
1654
+ // "askUserId":10467,
1655
+ // "isBuyer":true,
1656
+ // "isMaker":true,
1657
+ // "ctime":1678426306000
1658
+ // }
1659
+ //
1660
+ const timestamp = this.safeInteger2(trade, 'ctime', 'time');
1661
+ const priceString = this.safeString(trade, 'price');
1662
+ const amountString = this.safeString(trade, 'qty');
1663
+ const marketId = this.safeString2(trade, 'symbol', 'contractName');
1664
+ const symbol = this.safeSymbol(marketId, market);
1665
+ const orderId = this.safeString(trade, 'orderId');
1666
+ const id = this.safeString2(trade, 'id', 'tradeId');
1667
+ let side = undefined;
1668
+ const buyerMaker = this.safeValue(trade, 'isBuyerMaker'); // ignore "m" until Bitrue fixes api
1669
+ const isBuyer = this.safeValue(trade, 'isBuyer');
1670
+ if (buyerMaker !== undefined) {
1671
+ side = buyerMaker ? 'sell' : 'buy';
1672
+ }
1673
+ if (isBuyer !== undefined) {
1674
+ side = isBuyer ? 'buy' : 'sell'; // this is a true side
1675
+ }
1676
+ let fee = undefined;
1677
+ if ('commission' in trade) {
1678
+ fee = {
1679
+ 'cost': this.safeString2(trade, 'commission', 'fee'),
1680
+ 'currency': this.safeCurrencyCode(this.safeString(trade, 'commissionAssert')),
1681
+ };
1682
+ }
1683
+ let takerOrMaker = undefined;
1684
+ const isMaker = this.safeValue(trade, 'isMaker');
1685
+ if (isMaker !== undefined) {
1686
+ takerOrMaker = isMaker ? 'maker' : 'taker';
1687
+ }
1688
+ return this.safeTrade({
1689
+ 'info': trade,
1690
+ 'timestamp': timestamp,
1691
+ 'datetime': this.iso8601(timestamp),
1692
+ 'symbol': symbol,
1693
+ 'id': id,
1694
+ 'order': orderId,
1695
+ 'type': undefined,
1696
+ 'side': side,
1697
+ 'takerOrMaker': takerOrMaker,
1698
+ 'price': priceString,
1699
+ 'amount': amountString,
1700
+ 'cost': undefined,
1701
+ 'fee': fee,
1702
+ }, market);
1703
+ }
1704
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1705
+ /**
1706
+ * @method
1707
+ * @name bitrue#fetchTrades
1708
+ * @description get the list of most recent trades for a particular symbol
1709
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list
1710
+ * @param {string} symbol unified symbol of the market to fetch trades for
1711
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1712
+ * @param {int} [limit] the maximum amount of trades to fetch
1713
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1714
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1715
+ */
1716
+ await this.loadMarkets();
1717
+ const market = this.market(symbol);
1718
+ let response = undefined;
1719
+ if (market['spot']) {
1720
+ const request = {
1721
+ 'symbol': market['id'],
1722
+ // 'limit': 100, // default 100, max = 1000
1723
+ };
1724
+ if (limit !== undefined) {
1725
+ request['limit'] = limit; // default 100, max 1000
1726
+ }
1727
+ response = await this.spotV1PublicGetTrades(this.extend(request, params));
1728
+ }
1729
+ else {
1730
+ throw new errors.NotSupported(this.id + ' fetchTrades only support spot markets');
1731
+ }
1732
+ //
1733
+ // spot
1734
+ //
1735
+ // [
1736
+ // {
1737
+ // "id": 28457,
1738
+ // "price": "4.00000100",
1739
+ // "qty": "12.00000000",
1740
+ // "time": 1499865549590,
1741
+ // "isBuyerMaker": true,
1742
+ // "isBestMatch": true
1743
+ // }
1744
+ // ]
1745
+ //
1746
+ return this.parseTrades(response, market, since, limit);
1747
+ }
1748
+ parseOrderStatus(status) {
1749
+ const statuses = {
1750
+ 'INIT': 'open',
1751
+ 'PENDING_CREATE': 'open',
1752
+ 'NEW': 'open',
1753
+ 'PARTIALLY_FILLED': 'open',
1754
+ 'FILLED': 'closed',
1755
+ 'CANCELED': 'canceled',
1756
+ 'PENDING_CANCEL': 'canceling',
1757
+ 'REJECTED': 'rejected',
1758
+ 'EXPIRED': 'expired',
1759
+ };
1760
+ return this.safeString(statuses, status, status);
1761
+ }
1762
+ parseOrder(order, market = undefined) {
1763
+ //
1764
+ // createOrder - spot
1765
+ //
1766
+ // {
1767
+ // "symbol":"USDCUSDT",
1768
+ // "orderId":2878854881,
1769
+ // "clientOrderId":"",
1770
+ // "transactTime":1635551031276
1771
+ // }
1772
+ //
1773
+ // createOrder - future
1774
+ //
1775
+ // {
1776
+ // "orderId":1690615676032452985,
1777
+ // }
1778
+ //
1779
+ // fetchOrders - spot
1780
+ //
1781
+ // {
1782
+ // "symbol":"USDCUSDT",
1783
+ // "orderId":"2878854881",
1784
+ // "clientOrderId":"",
1785
+ // "price":"1.1000000000000000",
1786
+ // "origQty":"100.0000000000000000",
1787
+ // "executedQty":"0.0000000000000000",
1788
+ // "cummulativeQuoteQty":"0.0000000000000000",
1789
+ // "status":"NEW",
1790
+ // "timeInForce":"",
1791
+ // "type":"LIMIT",
1792
+ // "side":"SELL",
1793
+ // "stopPrice":"",
1794
+ // "icebergQty":"",
1795
+ // "time":1635551031000,
1796
+ // "updateTime":1635551031000,
1797
+ // "isWorking":false
1798
+ // }
1799
+ //
1800
+ // fetchOrders - future
1801
+ //
1802
+ // {
1803
+ // "orderId":1917641,
1804
+ // "price":100,
1805
+ // "origQty":10,
1806
+ // "origAmount":10,
1807
+ // "executedQty":1,
1808
+ // "avgPrice":10000,
1809
+ // "status":"INIT",
1810
+ // "type":"LIMIT",
1811
+ // "side":"BUY",
1812
+ // "action":"OPEN",
1813
+ // "transactTime":1686716571425
1814
+ // "clientOrderId":4949299210
1815
+ // }
1816
+ //
1817
+ const status = this.parseOrderStatus(this.safeString2(order, 'status', 'orderStatus'));
1818
+ const marketId = this.safeString(order, 'symbol');
1819
+ const symbol = this.safeSymbol(marketId, market);
1820
+ const filled = this.safeString(order, 'executedQty');
1821
+ let timestamp = undefined;
1822
+ let lastTradeTimestamp = undefined;
1823
+ if ('time' in order) {
1824
+ timestamp = this.safeInteger(order, 'time');
1825
+ }
1826
+ else if ('transactTime' in order) {
1827
+ timestamp = this.safeInteger(order, 'transactTime');
1828
+ }
1829
+ else if ('updateTime' in order) {
1830
+ if (status === 'open') {
1831
+ if (Precise["default"].stringGt(filled, '0')) {
1832
+ lastTradeTimestamp = this.safeInteger(order, 'updateTime');
1833
+ }
1834
+ else {
1835
+ timestamp = this.safeInteger(order, 'updateTime');
1836
+ }
1837
+ }
1838
+ }
1839
+ const average = this.safeString(order, 'avgPrice');
1840
+ const price = this.safeString(order, 'price');
1841
+ const amount = this.safeString(order, 'origQty');
1842
+ // - Spot/Margin market: cummulativeQuoteQty
1843
+ // - Futures market: cumQuote.
1844
+ // Note this is not the actual cost, since Binance futures uses leverage to calculate margins.
1845
+ const cost = this.safeString2(order, 'cummulativeQuoteQty', 'cumQuote');
1846
+ const id = this.safeString(order, 'orderId');
1847
+ let type = this.safeStringLower(order, 'type');
1848
+ const side = this.safeStringLower(order, 'side');
1849
+ const fills = this.safeValue(order, 'fills', []);
1850
+ const clientOrderId = this.safeString(order, 'clientOrderId');
1851
+ const timeInForce = this.safeString(order, 'timeInForce');
1852
+ const postOnly = (type === 'limit_maker') || (timeInForce === 'GTX') || (type === 'post_only');
1853
+ if (type === 'limit_maker') {
1854
+ type = 'limit';
1855
+ }
1856
+ const stopPriceString = this.safeString(order, 'stopPrice');
1857
+ const stopPrice = this.parseNumber(this.omitZero(stopPriceString));
1858
+ return this.safeOrder({
1859
+ 'info': order,
1860
+ 'id': id,
1861
+ 'clientOrderId': clientOrderId,
1862
+ 'timestamp': timestamp,
1863
+ 'datetime': this.iso8601(timestamp),
1864
+ 'lastTradeTimestamp': lastTradeTimestamp,
1865
+ 'symbol': symbol,
1866
+ 'type': type,
1867
+ 'timeInForce': timeInForce,
1868
+ 'postOnly': postOnly,
1869
+ 'side': side,
1870
+ 'price': price,
1871
+ 'stopPrice': stopPrice,
1872
+ 'triggerPrice': stopPrice,
1873
+ 'amount': amount,
1874
+ 'cost': cost,
1875
+ 'average': average,
1876
+ 'filled': filled,
1877
+ 'remaining': undefined,
1878
+ 'status': status,
1879
+ 'fee': undefined,
1880
+ 'trades': fills,
1881
+ }, market);
1882
+ }
1883
+ async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
1884
+ /**
1885
+ * @method
1886
+ * @name bitrue#createMarketBuyOrderWithCost
1887
+ * @description create a market buy order by providing the symbol and cost
1888
+ * @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256
1889
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256
1890
+ * @param {string} symbol unified symbol of the market to create an order in
1891
+ * @param {float} cost how much you want to trade in units of the quote currency
1892
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1893
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1894
+ */
1895
+ await this.loadMarkets();
1896
+ const market = this.market(symbol);
1897
+ if (!market['swap']) {
1898
+ throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports swap orders only');
1899
+ }
1900
+ params['createMarketBuyOrderRequiresPrice'] = false;
1901
+ return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
1902
+ }
1903
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1904
+ /**
1905
+ * @method
1906
+ * @name bitrue#createOrder
1907
+ * @description create a trade order
1908
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list
1909
+ * @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256
1910
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256
1911
+ * @param {string} symbol unified symbol of the market to create an order in
1912
+ * @param {string} type 'market' or 'limit'
1913
+ * @param {string} side 'buy' or 'sell'
1914
+ * @param {float} amount how much of currency you want to trade in units of base currency
1915
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1916
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1917
+ * @param {float} [params.triggerPrice] *spot only* the price at which a trigger order is triggered at
1918
+ * @param {string} [params.clientOrderId] a unique id for the order, automatically generated if not sent
1919
+ * @param {decimal} [params.leverage] in future order, the leverage value of the order should consistent with the user contract configuration, default is 1
1920
+ * @param {string} [params.timeInForce] 'fok', 'ioc' or 'po'
1921
+ * @param {bool} [params.postOnly] default false
1922
+ * @param {bool} [params.reduceOnly] default false
1923
+ * EXCHANGE SPECIFIC PARAMETERS
1924
+ * @param {decimal} [params.icebergQty]
1925
+ * @param {long} [params.recvWindow]
1926
+ * @param {float} [params.cost] *swap market buy only* the quote quantity that can be used as an alternative for the amount
1927
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1928
+ */
1929
+ await this.loadMarkets();
1930
+ const market = this.market(symbol);
1931
+ let response = undefined;
1932
+ let data = undefined;
1933
+ const uppercaseType = type.toUpperCase();
1934
+ const request = {
1935
+ 'side': side.toUpperCase(),
1936
+ 'type': uppercaseType,
1937
+ // 'timeInForce': '',
1938
+ // 'price': this.priceToPrecision (symbol, price),
1939
+ // 'newClientOrderId': clientOrderId, // automatically generated if not sent
1940
+ // 'stopPrice': this.priceToPrecision (symbol, 'stopPrice'),
1941
+ // 'icebergQty': this.amountToPrecision (symbol, icebergQty),
1942
+ };
1943
+ if (uppercaseType === 'LIMIT') {
1944
+ if (price === undefined) {
1945
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires a price argument');
1946
+ }
1947
+ request['price'] = this.priceToPrecision(symbol, price);
1948
+ }
1949
+ if (market['swap']) {
1950
+ const isMarket = uppercaseType === 'MARKET';
1951
+ const timeInForce = this.safeStringLower(params, 'timeInForce');
1952
+ const postOnly = this.isPostOnly(isMarket, undefined, params);
1953
+ if (postOnly) {
1954
+ request['type'] = 'POST_ONLY';
1955
+ }
1956
+ else if (timeInForce === 'fok') {
1957
+ request['type'] = 'FOK';
1958
+ }
1959
+ else if (timeInForce === 'ioc') {
1960
+ request['type'] = 'IOC';
1961
+ }
1962
+ request['contractName'] = market['id'];
1963
+ let createMarketBuyOrderRequiresPrice = true;
1964
+ [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
1965
+ if (isMarket && (side === 'buy') && createMarketBuyOrderRequiresPrice) {
1966
+ const cost = this.safeString(params, 'cost');
1967
+ params = this.omit(params, 'cost');
1968
+ if (price === undefined && cost === undefined) {
1969
+ throw new errors.InvalidOrder(this.id + ' createOrder() requires the price argument with swap market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options["createMarketBuyOrderRequiresPrice"] = false to supply the cost in the amount argument (the exchange-specific behaviour)');
1970
+ }
1971
+ else {
1972
+ const amountString = this.numberToString(amount);
1973
+ const priceString = this.numberToString(price);
1974
+ const quoteAmount = Precise["default"].stringMul(amountString, priceString);
1975
+ amount = (cost !== undefined) ? cost : quoteAmount;
1976
+ request['amount'] = this.costToPrecision(symbol, amount);
1977
+ request['volume'] = this.costToPrecision(symbol, amount);
1978
+ }
1979
+ }
1980
+ else {
1981
+ request['amount'] = this.parseToNumeric(amount);
1982
+ request['volume'] = this.parseToNumeric(amount);
1983
+ }
1984
+ request['positionType'] = 1;
1985
+ const reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1986
+ request['open'] = reduceOnly ? 'CLOSE' : 'OPEN';
1987
+ const leverage = this.safeString(params, 'leverage', '1');
1988
+ request['leverage'] = this.parseToNumeric(leverage);
1989
+ params = this.omit(params, ['leverage', 'reduceOnly', 'reduce_only', 'timeInForce']);
1990
+ if (market['linear']) {
1991
+ response = await this.fapiV2PrivatePostOrder(this.extend(request, params));
1992
+ }
1993
+ else if (market['inverse']) {
1994
+ response = await this.dapiV2PrivatePostOrder(this.extend(request, params));
1995
+ }
1996
+ data = this.safeValue(response, 'data', {});
1997
+ }
1998
+ else if (market['spot']) {
1999
+ request['symbol'] = market['id'];
2000
+ request['quantity'] = this.amountToPrecision(symbol, amount);
2001
+ const validOrderTypes = this.safeValue(market['info'], 'orderTypes');
2002
+ if (!this.inArray(uppercaseType, validOrderTypes)) {
2003
+ throw new errors.InvalidOrder(this.id + ' ' + type + ' is not a valid order type in market ' + symbol);
2004
+ }
2005
+ const clientOrderId = this.safeString2(params, 'newClientOrderId', 'clientOrderId');
2006
+ if (clientOrderId !== undefined) {
2007
+ params = this.omit(params, ['newClientOrderId', 'clientOrderId']);
2008
+ request['newClientOrderId'] = clientOrderId;
2009
+ }
2010
+ const stopPrice = this.safeValue2(params, 'triggerPrice', 'stopPrice');
2011
+ if (stopPrice !== undefined) {
2012
+ params = this.omit(params, ['triggerPrice', 'stopPrice']);
2013
+ request['stopPrice'] = this.priceToPrecision(symbol, stopPrice);
2014
+ }
2015
+ response = await this.spotV1PrivatePostOrder(this.extend(request, params));
2016
+ data = response;
2017
+ }
2018
+ else {
2019
+ throw new errors.NotSupported(this.id + ' createOrder only support spot & swap markets');
2020
+ }
2021
+ //
2022
+ // spot
2023
+ //
2024
+ // {
2025
+ // "symbol": "BTCUSDT",
2026
+ // "orderId": 307650651173648896,
2027
+ // "orderIdStr": "307650651173648896",
2028
+ // "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
2029
+ // "transactTime": 1507725176595
2030
+ // }
2031
+ //
2032
+ // swap
2033
+ //
2034
+ // {
2035
+ // "code": "0",
2036
+ // "msg": "Success",
2037
+ // "data": {
2038
+ // "orderId": 1690615676032452985
2039
+ // }
2040
+ // }
2041
+ //
2042
+ return this.parseOrder(data, market);
2043
+ }
2044
+ async fetchOrder(id, symbol = undefined, params = {}) {
2045
+ /**
2046
+ * @method
2047
+ * @name bitrue#fetchOrder
2048
+ * @description fetches information on an order made by the user
2049
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#query-order-user_data
2050
+ * @see https://www.bitrue.com/api-docs#query-order-user_data-hmac-sha256
2051
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#query-order-user_data-hmac-sha256
2052
+ * @param {string} symbol unified symbol of the market the order was made in
2053
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2054
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2055
+ */
2056
+ if (symbol === undefined) {
2057
+ throw new errors.ArgumentsRequired(this.id + ' fetchOrder() requires a symbol argument');
2058
+ }
2059
+ await this.loadMarkets();
2060
+ const market = this.market(symbol);
2061
+ const origClientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
2062
+ params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
2063
+ let response = undefined;
2064
+ let data = undefined;
2065
+ const request = {};
2066
+ if (origClientOrderId === undefined) {
2067
+ request['orderId'] = id;
2068
+ }
2069
+ else {
2070
+ if (market['swap']) {
2071
+ request['clientOrderId'] = origClientOrderId;
2072
+ }
2073
+ else {
2074
+ request['origClientOrderId'] = origClientOrderId;
2075
+ }
2076
+ }
2077
+ if (market['swap']) {
2078
+ request['contractName'] = market['id'];
2079
+ if (market['linear']) {
2080
+ response = await this.fapiV2PrivateGetOrder(this.extend(request, params));
2081
+ }
2082
+ else if (market['inverse']) {
2083
+ response = await this.dapiV2PrivateGetOrder(this.extend(request, params));
2084
+ }
2085
+ data = this.safeValue(response, 'data', {});
2086
+ }
2087
+ else if (market['spot']) {
2088
+ request['orderId'] = id; // spot market id is mandatory
2089
+ request['symbol'] = market['id'];
2090
+ response = await this.spotV1PrivateGetOrder(this.extend(request, params));
2091
+ data = response;
2092
+ }
2093
+ else {
2094
+ throw new errors.NotSupported(this.id + ' fetchOrder only support spot & swap markets');
2095
+ }
2096
+ //
2097
+ // spot
2098
+ //
2099
+ // {
2100
+ // "symbol": "LTCBTC",
2101
+ // "orderId": 1,
2102
+ // "clientOrderId": "myOrder1",
2103
+ // "price": "0.1",
2104
+ // "origQty": "1.0",
2105
+ // "executedQty": "0.0",
2106
+ // "cummulativeQuoteQty": "0.0",
2107
+ // "status": "NEW",
2108
+ // "timeInForce": "GTC",
2109
+ // "type": "LIMIT",
2110
+ // "side": "BUY",
2111
+ // "stopPrice": "0.0",
2112
+ // "icebergQty": "0.0",
2113
+ // "time": 1499827319559,
2114
+ // "updateTime": 1499827319559,
2115
+ // "isWorking": true
2116
+ // }
2117
+ //
2118
+ // swap
2119
+ //
2120
+ // {
2121
+ // "code":0,
2122
+ // "msg":"success",
2123
+ // "data":{
2124
+ // "orderId":1917641,
2125
+ // "price":100,
2126
+ // "origQty":10,
2127
+ // "origAmount":10,
2128
+ // "executedQty":1,
2129
+ // "avgPrice":10000,
2130
+ // "status":"INIT",
2131
+ // "type":"LIMIT",
2132
+ // "side":"BUY",
2133
+ // "action":"OPEN",
2134
+ // "transactTime":1686716571425
2135
+ // "clientOrderId":4949299210
2136
+ // }
2137
+ // }
2138
+ //
2139
+ return this.parseOrder(data, market);
2140
+ }
2141
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2142
+ /**
2143
+ * @method
2144
+ * @name bitrue#fetchClosedOrders
2145
+ * @description fetches information on multiple closed orders made by the user
2146
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#all-orders-user_data
2147
+ * @param {string} symbol unified market symbol of the market orders were made in
2148
+ * @param {int} [since] the earliest time in ms to fetch orders for
2149
+ * @param {int} [limit] the maximum number of order structures to retrieve
2150
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2151
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2152
+ */
2153
+ if (symbol === undefined) {
2154
+ throw new errors.ArgumentsRequired(this.id + ' fetchClosedOrders() requires a symbol argument');
2155
+ }
2156
+ await this.loadMarkets();
2157
+ const market = this.market(symbol);
2158
+ if (!market['spot']) {
2159
+ throw new errors.NotSupported(this.id + ' fetchClosedOrders only support spot markets');
2160
+ }
2161
+ const request = {
2162
+ 'symbol': market['id'],
2163
+ // 'orderId': 123445, // long
2164
+ // 'startTime': since,
2165
+ // 'endTime': this.milliseconds (),
2166
+ // 'limit': limit, // default 100, max 1000
2167
+ };
2168
+ if (since !== undefined) {
2169
+ request['startTime'] = since;
2170
+ }
2171
+ if (limit !== undefined) {
2172
+ request['limit'] = limit; // default 100, max 1000
2173
+ }
2174
+ const response = await this.spotV1PrivateGetAllOrders(this.extend(request, params));
2175
+ //
2176
+ // [
2177
+ // {
2178
+ // "symbol": "LTCBTC",
2179
+ // "orderId": 1,
2180
+ // "clientOrderId": "myOrder1",
2181
+ // "price": "0.1",
2182
+ // "origQty": "1.0",
2183
+ // "executedQty": "0.0",
2184
+ // "cummulativeQuoteQty": "0.0",
2185
+ // "status": "NEW",
2186
+ // "timeInForce": "GTC",
2187
+ // "type": "LIMIT",
2188
+ // "side": "BUY",
2189
+ // "stopPrice": "0.0",
2190
+ // "icebergQty": "0.0",
2191
+ // "time": 1499827319559,
2192
+ // "updateTime": 1499827319559,
2193
+ // "isWorking": true
2194
+ // }
2195
+ // ]
2196
+ //
2197
+ return this.parseOrders(response, market, since, limit);
2198
+ }
2199
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2200
+ /**
2201
+ * @method
2202
+ * @name bitrue#fetchOpenOrders
2203
+ * @description fetch all unfilled currently open orders
2204
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#current-open-orders-user_data
2205
+ * @see https://www.bitrue.com/api-docs#current-all-open-orders-user_data-hmac-sha256
2206
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-all-open-orders-user_data-hmac-sha256
2207
+ * @param {string} symbol unified market symbol
2208
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2209
+ * @param {int} [limit] the maximum number of open order structures to retrieve
2210
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2211
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2212
+ */
2213
+ if (symbol === undefined) {
2214
+ throw new errors.ArgumentsRequired(this.id + ' fetchOpenOrders() requires a symbol argument');
2215
+ }
2216
+ await this.loadMarkets();
2217
+ const market = this.market(symbol);
2218
+ let response = undefined;
2219
+ let data = undefined;
2220
+ const request = {};
2221
+ if (market['swap']) {
2222
+ request['contractName'] = market['id'];
2223
+ if (market['linear']) {
2224
+ response = await this.fapiV2PrivateGetOpenOrders(this.extend(request, params));
2225
+ }
2226
+ else if (market['inverse']) {
2227
+ response = await this.dapiV2PrivateGetOpenOrders(this.extend(request, params));
2228
+ }
2229
+ data = this.safeValue(response, 'data', []);
2230
+ }
2231
+ else if (market['spot']) {
2232
+ request['symbol'] = market['id'];
2233
+ response = await this.spotV1PrivateGetOpenOrders(this.extend(request, params));
2234
+ data = response;
2235
+ }
2236
+ else {
2237
+ throw new errors.NotSupported(this.id + ' fetchOpenOrders only support spot & swap markets');
2238
+ }
2239
+ //
2240
+ // spot
2241
+ //
2242
+ // [
2243
+ // {
2244
+ // "symbol":"USDCUSDT",
2245
+ // "orderId":"2878854881",
2246
+ // "clientOrderId":"",
2247
+ // "price":"1.1000000000000000",
2248
+ // "origQty":"100.0000000000000000",
2249
+ // "executedQty":"0.0000000000000000",
2250
+ // "cummulativeQuoteQty":"0.0000000000000000",
2251
+ // "status":"NEW",
2252
+ // "timeInForce":"",
2253
+ // "type":"LIMIT",
2254
+ // "side":"SELL",
2255
+ // "stopPrice":"",
2256
+ // "icebergQty":"",
2257
+ // "time":1635551031000,
2258
+ // "updateTime":1635551031000,
2259
+ // "isWorking":false
2260
+ // }
2261
+ // ]
2262
+ //
2263
+ // swap
2264
+ //
2265
+ // {
2266
+ // "code": "0",
2267
+ // "msg": "Success",
2268
+ // "data": [{
2269
+ // "orderId": 1917641,
2270
+ // "clientOrderId": "2488514315",
2271
+ // "price": 100,
2272
+ // "origQty": 10,
2273
+ // "origAmount": 10,
2274
+ // "executedQty": 1,
2275
+ // "avgPrice": 12451,
2276
+ // "status": "INIT",
2277
+ // "type": "LIMIT",
2278
+ // "side": "BUY",
2279
+ // "action": "OPEN",
2280
+ // "transactTime": 1686717303975
2281
+ // }
2282
+ // ]
2283
+ // }
2284
+ //
2285
+ return this.parseOrders(data, market, since, limit);
2286
+ }
2287
+ async cancelOrder(id, symbol = undefined, params = {}) {
2288
+ /**
2289
+ * @method
2290
+ * @name bitrue#cancelOrder
2291
+ * @description cancels an open order
2292
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#cancel-order-trade
2293
+ * @see https://www.bitrue.com/api-docs#cancel-order-trade-hmac-sha256
2294
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-order-trade-hmac-sha256
2295
+ * @param {string} id order id
2296
+ * @param {string} symbol unified symbol of the market the order was made in
2297
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2298
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2299
+ */
2300
+ if (symbol === undefined) {
2301
+ throw new errors.ArgumentsRequired(this.id + ' cancelOrder() requires a symbol argument');
2302
+ }
2303
+ await this.loadMarkets();
2304
+ const market = this.market(symbol);
2305
+ const origClientOrderId = this.safeValue2(params, 'origClientOrderId', 'clientOrderId');
2306
+ params = this.omit(params, ['origClientOrderId', 'clientOrderId']);
2307
+ let response = undefined;
2308
+ let data = undefined;
2309
+ const request = {};
2310
+ if (origClientOrderId === undefined) {
2311
+ request['orderId'] = id;
2312
+ }
2313
+ else {
2314
+ if (market['swap']) {
2315
+ request['clientOrderId'] = origClientOrderId;
2316
+ }
2317
+ else {
2318
+ request['origClientOrderId'] = origClientOrderId;
2319
+ }
2320
+ }
2321
+ if (market['swap']) {
2322
+ request['contractName'] = market['id'];
2323
+ if (market['linear']) {
2324
+ response = await this.fapiV2PrivatePostCancel(this.extend(request, params));
2325
+ }
2326
+ else if (market['inverse']) {
2327
+ response = await this.dapiV2PrivatePostCancel(this.extend(request, params));
2328
+ }
2329
+ data = this.safeValue(response, 'data', {});
2330
+ }
2331
+ else if (market['spot']) {
2332
+ request['symbol'] = market['id'];
2333
+ response = await this.spotV1PrivateDeleteOrder(this.extend(request, params));
2334
+ data = response;
2335
+ }
2336
+ else {
2337
+ throw new errors.NotSupported(this.id + ' cancelOrder only support spot & swap markets');
2338
+ }
2339
+ //
2340
+ // spot
2341
+ //
2342
+ // {
2343
+ // "symbol": "LTCBTC",
2344
+ // "origClientOrderId": "myOrder1",
2345
+ // "orderId": 1,
2346
+ // "clientOrderId": "cancelMyOrder1"
2347
+ // }
2348
+ //
2349
+ // swap
2350
+ //
2351
+ // {
2352
+ // "code": "0",
2353
+ // "msg": "Success",
2354
+ // "data": {
2355
+ // "orderId": 1690615847831143159
2356
+ // }
2357
+ // }
2358
+ //
2359
+ return this.parseOrder(data, market);
2360
+ }
2361
+ async cancelAllOrders(symbol = undefined, params = {}) {
2362
+ /**
2363
+ * @method
2364
+ * @name bitrue#cancelAllOrders
2365
+ * @description cancel all open orders in a market
2366
+ * @see https://www.bitrue.com/api-docs#cancel-all-open-orders-trade-hmac-sha256
2367
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-all-open-orders-trade-hmac-sha256
2368
+ * @param {string} symbol unified market symbol of the market to cancel orders in
2369
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2370
+ * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading
2371
+ * @returns {object[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure}
2372
+ */
2373
+ await this.loadMarkets();
2374
+ const market = this.market(symbol);
2375
+ let response = undefined;
2376
+ let data = undefined;
2377
+ if (market['swap']) {
2378
+ const request = {
2379
+ 'contractName': market['id'],
2380
+ };
2381
+ if (market['linear']) {
2382
+ response = await this.fapiV2PrivatePostAllOpenOrders(this.extend(request, params));
2383
+ }
2384
+ else if (market['inverse']) {
2385
+ response = await this.dapiV2PrivatePostAllOpenOrders(this.extend(request, params));
2386
+ }
2387
+ data = this.safeValue(response, 'data', []);
2388
+ }
2389
+ else {
2390
+ throw new errors.NotSupported(this.id + ' cancelAllOrders only support future markets');
2391
+ }
2392
+ //
2393
+ // swap
2394
+ //
2395
+ // {
2396
+ // 'code': '0',
2397
+ // 'msg': 'Success',
2398
+ // 'data': null
2399
+ // }
2400
+ //
2401
+ return this.parseOrders(data, market);
2402
+ }
2403
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2404
+ /**
2405
+ * @method
2406
+ * @name bitrue#fetchMyTrades
2407
+ * @description fetch all trades made by the user
2408
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-trade-list-user_data
2409
+ * @see https://www.bitrue.com/api-docs#account-trade-list-user_data-hmac-sha256
2410
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-trade-list-user_data-hmac-sha256
2411
+ * @param {string} symbol unified market symbol
2412
+ * @param {int} [since] the earliest time in ms to fetch trades for
2413
+ * @param {int} [limit] the maximum number of trades structures to retrieve
2414
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2415
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
2416
+ */
2417
+ await this.loadMarkets();
2418
+ if (symbol === undefined) {
2419
+ throw new errors.ArgumentsRequired(this.id + ' fetchMyTrades() requires a symbol argument');
2420
+ }
2421
+ const market = this.market(symbol);
2422
+ let response = undefined;
2423
+ let data = undefined;
2424
+ const request = {};
2425
+ if (since !== undefined) {
2426
+ request['startTime'] = since;
2427
+ }
2428
+ if (limit !== undefined) {
2429
+ if (limit > 1000) {
2430
+ limit = 1000;
2431
+ }
2432
+ request['limit'] = limit;
2433
+ }
2434
+ if (market['swap']) {
2435
+ request['contractName'] = market['id'];
2436
+ if (market['linear']) {
2437
+ response = await this.fapiV2PrivateGetMyTrades(this.extend(request, params));
2438
+ }
2439
+ else if (market['inverse']) {
2440
+ response = await this.dapiV2PrivateGetMyTrades(this.extend(request, params));
2441
+ }
2442
+ data = this.safeValue(response, 'data', []);
2443
+ }
2444
+ else if (market['spot']) {
2445
+ request['symbol'] = market['id'];
2446
+ response = await this.spotV2PrivateGetMyTrades(this.extend(request, params));
2447
+ data = response;
2448
+ }
2449
+ else {
2450
+ throw new errors.NotSupported(this.id + ' fetchMyTrades only support spot & swap markets');
2451
+ }
2452
+ //
2453
+ // spot
2454
+ //
2455
+ // [
2456
+ // {
2457
+ // "symbol":"USDCUSDT",
2458
+ // "id":20725156,
2459
+ // "orderId":2880918576,
2460
+ // "origClientOrderId":null,
2461
+ // "price":"0.9996000000000000",
2462
+ // "qty":"100.0000000000000000",
2463
+ // "commission":null,
2464
+ // "commissionAssert":null,
2465
+ // "time":1635558511000,
2466
+ // "isBuyer":false,
2467
+ // "isMaker":false,
2468
+ // "isBestMatch":true
2469
+ // }
2470
+ // ]
2471
+ //
2472
+ // swap
2473
+ //
2474
+ // {
2475
+ // "code":"0",
2476
+ // "msg":"Success",
2477
+ // "data":[
2478
+ // {
2479
+ // "tradeId":12,
2480
+ // "price":0.9,
2481
+ // "qty":1,
2482
+ // "amount":9,
2483
+ // "contractName":"E-SAND-USDT",
2484
+ // "side":"BUY",
2485
+ // "fee":"0.0018",
2486
+ // "bidId":1558124009467904992,
2487
+ // "askId":1558124043827644908,
2488
+ // "bidUserId":10294,
2489
+ // "askUserId":10467,
2490
+ // "isBuyer":true,
2491
+ // "isMaker":true,
2492
+ // "ctime":1678426306000
2493
+ // }
2494
+ // ]
2495
+ // }
2496
+ //
2497
+ return this.parseTrades(data, market, since, limit);
2498
+ }
2499
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2500
+ /**
2501
+ * @method
2502
+ * @name bitrue#fetchDeposits
2503
+ * @description fetch all deposits made to an account
2504
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#deposit-history--withdraw_data
2505
+ * @param {string} code unified currency code
2506
+ * @param {int} [since] the earliest time in ms to fetch deposits for
2507
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
2508
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2509
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2510
+ */
2511
+ if (code === undefined) {
2512
+ throw new errors.ArgumentsRequired(this.id + ' fetchDeposits() requires a code argument');
2513
+ }
2514
+ await this.loadMarkets();
2515
+ const currency = this.currency(code);
2516
+ const request = {
2517
+ 'coin': currency['id'],
2518
+ 'status': 1, // 0 init, 1 finished, default 0
2519
+ // 'offset': 0,
2520
+ // 'limit': limit, // default 10, max 1000
2521
+ // 'startTime': since,
2522
+ // 'endTime': this.milliseconds (),
2523
+ };
2524
+ if (since !== undefined) {
2525
+ request['startTime'] = since;
2526
+ // request['endTime'] = this.sum (since, 7776000000);
2527
+ }
2528
+ if (limit !== undefined) {
2529
+ request['limit'] = limit;
2530
+ }
2531
+ const response = await this.spotV1PrivateGetDepositHistory(this.extend(request, params));
2532
+ //
2533
+ // {
2534
+ // "code":200,
2535
+ // "msg":"succ",
2536
+ // "data":[
2537
+ // {
2538
+ // "id":2659137,
2539
+ // "symbol":"USDC",
2540
+ // "amount":"200.0000000000000000",
2541
+ // "fee":"0.0E-15",
2542
+ // "createdAt":1635503169000,
2543
+ // "updatedAt":1635503202000,
2544
+ // "addressFrom":"0x2faf487a4414fe77e2327f0bf4ae2a264a776ad2",
2545
+ // "addressTo":"0x190ceccb1f8bfbec1749180f0ba8922b488d865b",
2546
+ // "txid":"0x9970aec41099ac385568859517308707bc7d716df8dabae7b52f5b17351c3ed0",
2547
+ // "confirmations":5,
2548
+ // "status":0,
2549
+ // "tagType":null,
2550
+ // },
2551
+ // {
2552
+ // "id":2659137,
2553
+ // "symbol": "XRP",
2554
+ // "amount": "20.0000000000000000",
2555
+ // "fee": "0.0E-15",
2556
+ // "createdAt": 1544669393000,
2557
+ // "updatedAt": 1544669413000,
2558
+ // "addressFrom": "",
2559
+ // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
2560
+ // "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
2561
+ // "confirmations": 7,
2562
+ // "status": 1,
2563
+ // "tagType": "Tag"
2564
+ // }
2565
+ // ]
2566
+ // }
2567
+ //
2568
+ const data = this.safeValue(response, 'data', []);
2569
+ return this.parseTransactions(data, currency, since, limit);
2570
+ }
2571
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2572
+ /**
2573
+ * @method
2574
+ * @name bitrue#fetchWithdrawals
2575
+ * @description fetch all withdrawals made from an account
2576
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-history--withdraw_data
2577
+ * @param {string} code unified currency code
2578
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
2579
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2580
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2581
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2582
+ */
2583
+ if (code === undefined) {
2584
+ throw new errors.ArgumentsRequired(this.id + ' fetchWithdrawals() requires a code argument');
2585
+ }
2586
+ await this.loadMarkets();
2587
+ const currency = this.currency(code);
2588
+ const request = {
2589
+ 'coin': currency['id'],
2590
+ 'status': 5, // 0 init, 5 finished, 6 canceled, default 0
2591
+ // 'offset': 0,
2592
+ // 'limit': limit, // default 10, max 1000
2593
+ // 'startTime': since,
2594
+ // 'endTime': this.milliseconds (),
2595
+ };
2596
+ if (since !== undefined) {
2597
+ request['startTime'] = since;
2598
+ // request['endTime'] = this.sum (since, 7776000000);
2599
+ }
2600
+ if (limit !== undefined) {
2601
+ request['limit'] = limit;
2602
+ }
2603
+ const response = await this.spotV1PrivateGetWithdrawHistory(this.extend(request, params));
2604
+ //
2605
+ // {
2606
+ // "code": 200,
2607
+ // "msg": "succ",
2608
+ // "data": {
2609
+ // "msg": null,
2610
+ // "amount": 1000,
2611
+ // "fee": 1,
2612
+ // "ctime": null,
2613
+ // "coin": "usdt_erc20",
2614
+ // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
2615
+ // }
2616
+ // }
2617
+ //
2618
+ const data = this.safeValue(response, 'data', {});
2619
+ return this.parseTransactions(data, currency);
2620
+ }
2621
+ parseTransactionStatusByType(status, type = undefined) {
2622
+ const statusesByType = {
2623
+ 'deposit': {
2624
+ '0': 'pending',
2625
+ '1': 'ok',
2626
+ },
2627
+ 'withdrawal': {
2628
+ '0': 'pending',
2629
+ '5': 'ok',
2630
+ '6': 'canceled',
2631
+ },
2632
+ };
2633
+ const statuses = this.safeValue(statusesByType, type, {});
2634
+ return this.safeString(statuses, status, status);
2635
+ }
2636
+ parseTransaction(transaction, currency = undefined) {
2637
+ //
2638
+ // fetchDeposits
2639
+ //
2640
+ // {
2641
+ // "symbol": "XRP",
2642
+ // "amount": "261.3361000000000000",
2643
+ // "fee": "0.0E-15",
2644
+ // "createdAt": 1548816979000,
2645
+ // "updatedAt": 1548816999000,
2646
+ // "addressFrom": "",
2647
+ // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
2648
+ // "txid": "86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D",
2649
+ // "confirmations": 8,
2650
+ // "status": 1,
2651
+ // "tagType": "Tag"
2652
+ // },
2653
+ // {
2654
+ // "symbol": "XRP",
2655
+ // "amount": "20.0000000000000000",
2656
+ // "fee": "0.0E-15",
2657
+ // "createdAt": 1544669393000,
2658
+ // "updatedAt": 1544669413000,
2659
+ // "addressFrom": "",
2660
+ // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641",
2661
+ // "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC",
2662
+ // "confirmations": 7,
2663
+ // "status": 1,
2664
+ // "tagType": "Tag"
2665
+ // }
2666
+ //
2667
+ // fetchWithdrawals
2668
+ //
2669
+ // {
2670
+ // "id": 183745,
2671
+ // "symbol": "usdt_erc20",
2672
+ // "amount": "8.4000000000000000",
2673
+ // "fee": "1.6000000000000000",
2674
+ // "payAmount": "0.0000000000000000",
2675
+ // "createdAt": 1595336441000,
2676
+ // "updatedAt": 1595336576000,
2677
+ // "addressFrom": "",
2678
+ // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83",
2679
+ // "txid": "",
2680
+ // "confirmations": 0,
2681
+ // "status": 6,
2682
+ // "tagType": null
2683
+ // }
2684
+ //
2685
+ // withdraw
2686
+ //
2687
+ // {
2688
+ // "msg": null,
2689
+ // "amount": 1000,
2690
+ // "fee": 1,
2691
+ // "ctime": null,
2692
+ // "coin": "usdt_erc20",
2693
+ // "withdrawId": 1156423,
2694
+ // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
2695
+ // }
2696
+ //
2697
+ const id = this.safeString2(transaction, 'id', 'withdrawId');
2698
+ const tagType = this.safeString(transaction, 'tagType');
2699
+ let addressTo = this.safeString(transaction, 'addressTo');
2700
+ let addressFrom = this.safeString(transaction, 'addressFrom');
2701
+ let tagTo = undefined;
2702
+ let tagFrom = undefined;
2703
+ if (tagType !== undefined) {
2704
+ if (addressTo !== undefined) {
2705
+ const parts = addressTo.split('_');
2706
+ addressTo = this.safeString(parts, 0);
2707
+ tagTo = this.safeString(parts, 1);
2708
+ }
2709
+ if (addressFrom !== undefined) {
2710
+ const parts = addressFrom.split('_');
2711
+ addressFrom = this.safeString(parts, 0);
2712
+ tagFrom = this.safeString(parts, 1);
2713
+ }
2714
+ }
2715
+ const txid = this.safeString(transaction, 'txid');
2716
+ const timestamp = this.safeInteger(transaction, 'createdAt');
2717
+ const updated = this.safeInteger(transaction, 'updatedAt');
2718
+ const payAmount = ('payAmount' in transaction);
2719
+ const ctime = ('ctime' in transaction);
2720
+ const type = (payAmount || ctime) ? 'withdrawal' : 'deposit';
2721
+ const status = this.parseTransactionStatusByType(this.safeString(transaction, 'status'), type);
2722
+ const amount = this.safeNumber(transaction, 'amount');
2723
+ let network = undefined;
2724
+ let currencyId = this.safeString2(transaction, 'symbol', 'coin');
2725
+ if (currencyId !== undefined) {
2726
+ const parts = currencyId.split('_');
2727
+ currencyId = this.safeString(parts, 0);
2728
+ const networkId = this.safeString(parts, 1);
2729
+ if (networkId !== undefined) {
2730
+ network = networkId.toUpperCase();
2731
+ }
2732
+ }
2733
+ const code = this.safeCurrencyCode(currencyId, currency);
2734
+ const feeCost = this.safeNumber(transaction, 'fee');
2735
+ let fee = undefined;
2736
+ if (feeCost !== undefined) {
2737
+ fee = { 'currency': code, 'cost': feeCost };
2738
+ }
2739
+ return {
2740
+ 'info': transaction,
2741
+ 'id': id,
2742
+ 'txid': txid,
2743
+ 'timestamp': timestamp,
2744
+ 'datetime': this.iso8601(timestamp),
2745
+ 'network': network,
2746
+ 'address': addressTo,
2747
+ 'addressTo': addressTo,
2748
+ 'addressFrom': addressFrom,
2749
+ 'tag': tagTo,
2750
+ 'tagTo': tagTo,
2751
+ 'tagFrom': tagFrom,
2752
+ 'type': type,
2753
+ 'amount': amount,
2754
+ 'currency': code,
2755
+ 'status': status,
2756
+ 'updated': updated,
2757
+ 'internal': false,
2758
+ 'comment': undefined,
2759
+ 'fee': fee,
2760
+ };
2761
+ }
2762
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
2763
+ /**
2764
+ * @method
2765
+ * @name bitrue#withdraw
2766
+ * @description make a withdrawal
2767
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-commit--withdraw_data
2768
+ * @param {string} code unified currency code
2769
+ * @param {float} amount the amount to withdraw
2770
+ * @param {string} address the address to withdraw to
2771
+ * @param {string} tag
2772
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2773
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2774
+ */
2775
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
2776
+ this.checkAddress(address);
2777
+ await this.loadMarkets();
2778
+ const currency = this.currency(code);
2779
+ let chainName = this.safeString2(params, 'network', 'chainName');
2780
+ if (chainName === undefined) {
2781
+ const networks = this.safeValue(currency, 'networks', {});
2782
+ const optionsNetworks = this.safeValue(this.options, 'networks', {});
2783
+ let network = this.safeStringUpper(params, 'network'); // this line allows the user to specify either ERC20 or ETH
2784
+ network = this.safeString(optionsNetworks, network, network);
2785
+ const networkEntry = this.safeValue(networks, network, {});
2786
+ chainName = this.safeString(networkEntry, 'id'); // handle ERC20>ETH alias
2787
+ if (chainName === undefined) {
2788
+ throw new errors.ArgumentsRequired(this.id + ' withdraw() requires a network parameter or a chainName parameter');
2789
+ }
2790
+ params = this.omit(params, 'network');
2791
+ }
2792
+ const request = {
2793
+ 'coin': currency['id'].toUpperCase(),
2794
+ 'amount': amount,
2795
+ 'addressTo': address,
2796
+ 'chainName': chainName, // 'ERC20', 'TRC20', 'SOL'
2797
+ // 'addressMark': '', // mark of address
2798
+ // 'addrType': '', // type of address
2799
+ // 'tag': tag,
2800
+ };
2801
+ if (tag !== undefined) {
2802
+ request['tag'] = tag;
2803
+ }
2804
+ const response = await this.spotV1PrivatePostWithdrawCommit(this.extend(request, params));
2805
+ //
2806
+ // {
2807
+ // "code": 200,
2808
+ // "msg": "succ",
2809
+ // "data": {
2810
+ // "msg": null,
2811
+ // "amount": 1000,
2812
+ // "fee": 1,
2813
+ // "ctime": null,
2814
+ // "coin": "usdt_erc20",
2815
+ // "withdrawId": 1156423,
2816
+ // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83"
2817
+ // }
2818
+ // }
2819
+ //
2820
+ const data = this.safeValue(response, 'data', {});
2821
+ return this.parseTransaction(data, currency);
2822
+ }
2823
+ parseDepositWithdrawFee(fee, currency = undefined) {
2824
+ //
2825
+ // {
2826
+ // "coin": "adx",
2827
+ // "coinFulName": "Ambire AdEx",
2828
+ // "chains": [ "BSC" ],
2829
+ // "chainDetail": [ [Object] ]
2830
+ // }
2831
+ //
2832
+ const chainDetails = this.safeValue(fee, 'chainDetail', []);
2833
+ const chainDetailLength = chainDetails.length;
2834
+ const result = {
2835
+ 'info': fee,
2836
+ 'withdraw': {
2837
+ 'fee': undefined,
2838
+ 'percentage': undefined,
2839
+ },
2840
+ 'deposit': {
2841
+ 'fee': undefined,
2842
+ 'percentage': undefined,
2843
+ },
2844
+ 'networks': {},
2845
+ };
2846
+ if (chainDetailLength !== 0) {
2847
+ for (let i = 0; i < chainDetailLength; i++) {
2848
+ const chainDetail = chainDetails[i];
2849
+ const networkId = this.safeString(chainDetail, 'chain');
2850
+ const currencyCode = this.safeString(currency, 'code');
2851
+ const networkCode = this.networkIdToCode(networkId, currencyCode);
2852
+ result['networks'][networkCode] = {
2853
+ 'deposit': { 'fee': undefined, 'percentage': undefined },
2854
+ 'withdraw': { 'fee': this.safeNumber(chainDetail, 'withdrawFee'), 'percentage': false },
2855
+ };
2856
+ if (chainDetailLength === 1) {
2857
+ result['withdraw']['fee'] = this.safeNumber(chainDetail, 'withdrawFee');
2858
+ result['withdraw']['percentage'] = false;
2859
+ }
2860
+ }
2861
+ }
2862
+ return result;
2863
+ }
2864
+ async fetchDepositWithdrawFees(codes = undefined, params = {}) {
2865
+ /**
2866
+ * @method
2867
+ * @name bitrue#fetchDepositWithdrawFees
2868
+ * @description fetch deposit and withdraw fees
2869
+ * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint
2870
+ * @param {string[]|undefined} codes list of unified currency codes
2871
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2872
+ * @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure}
2873
+ */
2874
+ await this.loadMarkets();
2875
+ const response = await this.spotV1PublicGetExchangeInfo(params);
2876
+ const coins = this.safeValue(response, 'coins');
2877
+ return this.parseDepositWithdrawFees(coins, codes, 'coin');
2878
+ }
2879
+ parseTransfer(transfer, currency = undefined) {
2880
+ //
2881
+ // fetchTransfers
2882
+ //
2883
+ // {
2884
+ // 'transferType': 'wallet_to_contract',
2885
+ // 'symbol': 'USDT',
2886
+ // 'amount': 1.0,
2887
+ // 'status': 1,
2888
+ // 'ctime': 1685404575000
2889
+ // }
2890
+ //
2891
+ // transfer
2892
+ //
2893
+ // {}
2894
+ //
2895
+ const transferType = this.safeString(transfer, 'transferType');
2896
+ let fromAccount = undefined;
2897
+ let toAccount = undefined;
2898
+ if (transferType !== undefined) {
2899
+ const accountSplit = transferType.split('_to_');
2900
+ fromAccount = this.safeString(accountSplit, 0);
2901
+ toAccount = this.safeString(accountSplit, 1);
2902
+ }
2903
+ const timestamp = this.safeInteger(transfer, 'ctime');
2904
+ return {
2905
+ 'info': transfer,
2906
+ 'id': undefined,
2907
+ 'timestamp': timestamp,
2908
+ 'datetime': this.iso8601(timestamp),
2909
+ 'currency': this.safeString(currency, 'code'),
2910
+ 'amount': this.safeNumber(transfer, 'amount'),
2911
+ 'fromAccount': fromAccount,
2912
+ 'toAccount': toAccount,
2913
+ 'status': 'ok',
2914
+ };
2915
+ }
2916
+ async fetchTransfers(code = undefined, since = undefined, limit = undefined, params = {}) {
2917
+ /**
2918
+ * @method
2919
+ * @name bitrue#fetchTransfers
2920
+ * @description fetch a history of internal transfers made on an account
2921
+ * @see https://www.bitrue.com/api-docs#get-future-account-transfer-history-list-user_data-hmac-sha256
2922
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#get-future-account-transfer-history-list-user_data-hmac-sha256
2923
+ * @param {string} code unified currency code of the currency transferred
2924
+ * @param {int} [since] the earliest time in ms to fetch transfers for
2925
+ * @param {int} [limit] the maximum number of transfers structures to retrieve
2926
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2927
+ * @param {int} [params.until] the latest time in ms to fetch transfers for
2928
+ * @param {string} [params.type] transfer type wallet_to_contract or contract_to_wallet
2929
+ * @returns {object[]} a list of [transfer structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
2930
+ */
2931
+ await this.loadMarkets();
2932
+ const type = this.safeString2(params, 'type', 'transferType');
2933
+ const request = {
2934
+ 'transferType': type,
2935
+ };
2936
+ let currency = undefined;
2937
+ if (code !== undefined) {
2938
+ currency = this.currency(code);
2939
+ request['coinSymbol'] = currency['id'];
2940
+ }
2941
+ if (since !== undefined) {
2942
+ request['beginTime'] = since;
2943
+ }
2944
+ if (limit !== undefined) {
2945
+ if (limit > 200) {
2946
+ limit = 200;
2947
+ }
2948
+ request['limit'] = limit;
2949
+ }
2950
+ const until = this.safeInteger(params, 'until');
2951
+ if (until !== undefined) {
2952
+ params = this.omit(params, 'until');
2953
+ request['endTime'] = until;
2954
+ }
2955
+ const response = await this.fapiV2PrivateGetFuturesTransferHistory(this.extend(request, params));
2956
+ //
2957
+ // {
2958
+ // 'code': '0',
2959
+ // 'msg': 'Success',
2960
+ // 'data': [{
2961
+ // 'transferType': 'wallet_to_contract',
2962
+ // 'symbol': 'USDT',
2963
+ // 'amount': 1.0,
2964
+ // 'status': 1,
2965
+ // 'ctime': 1685404575000
2966
+ // }]
2967
+ // }
2968
+ //
2969
+ const data = this.safeValue(response, 'data', {});
2970
+ return this.parseTransfers(data, currency, since, limit);
2971
+ }
2972
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2973
+ /**
2974
+ * @method
2975
+ * @name bitrue#transfer
2976
+ * @description transfer currency internally between wallets on the same account
2977
+ * @see https://www.bitrue.com/api-docs#new-future-account-transfer-user_data-hmac-sha256
2978
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#user-commission-rate-user_data-hmac-sha256
2979
+ * @param {string} code unified currency code
2980
+ * @param {float} amount amount to transfer
2981
+ * @param {string} fromAccount account to transfer from
2982
+ * @param {string} toAccount account to transfer to
2983
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2984
+ * @returns {object} a [transfer structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
2985
+ */
2986
+ await this.loadMarkets();
2987
+ const currency = this.currency(code);
2988
+ const accountTypes = this.safeValue(this.options, 'accountsByType', {});
2989
+ const fromId = this.safeString(accountTypes, fromAccount, fromAccount);
2990
+ const toId = this.safeString(accountTypes, toAccount, toAccount);
2991
+ const request = {
2992
+ 'coinSymbol': currency['id'],
2993
+ 'amount': this.currencyToPrecision(code, amount),
2994
+ 'transferType': fromId + '_to_' + toId,
2995
+ };
2996
+ const response = await this.fapiV2PrivatePostFuturesTransfer(this.extend(request, params));
2997
+ //
2998
+ // {
2999
+ // 'code': '0',
3000
+ // 'msg': 'Success',
3001
+ // 'data': null
3002
+ // }
3003
+ //
3004
+ const data = this.safeValue(response, 'data', {});
3005
+ return this.parseTransfer(data, currency);
3006
+ }
3007
+ async setLeverage(leverage, symbol = undefined, params = {}) {
3008
+ /**
3009
+ * @method
3010
+ * @name bitrue#setLeverage
3011
+ * @description set the level of leverage for a market
3012
+ * @see https://www.bitrue.com/api-docs#change-initial-leverage-trade-hmac-sha256
3013
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#change-initial-leverage-trade-hmac-sha256
3014
+ * @param {float} leverage the rate of leverage
3015
+ * @param {string} symbol unified market symbol
3016
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
3017
+ * @returns {object} response from the exchange
3018
+ */
3019
+ if (symbol === undefined) {
3020
+ throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
3021
+ }
3022
+ if ((leverage < 1) || (leverage > 125)) {
3023
+ throw new errors.BadRequest(this.id + ' leverage should be between 1 and 125');
3024
+ }
3025
+ await this.loadMarkets();
3026
+ const market = this.market(symbol);
3027
+ let response = undefined;
3028
+ const request = {
3029
+ 'contractName': market['id'],
3030
+ 'leverage': leverage,
3031
+ };
3032
+ if (!market['swap']) {
3033
+ throw new errors.NotSupported(this.id + ' setLeverage only support swap markets');
3034
+ }
3035
+ if (market['linear']) {
3036
+ response = await this.fapiV2PrivatePostLevelEdit(this.extend(request, params));
3037
+ }
3038
+ else if (market['inverse']) {
3039
+ response = await this.dapiV2PrivatePostLevelEdit(this.extend(request, params));
3040
+ }
3041
+ return response;
3042
+ }
3043
+ parseMarginModification(data, market = undefined) {
3044
+ return {
3045
+ 'info': data,
3046
+ 'type': undefined,
3047
+ 'amount': undefined,
3048
+ 'code': undefined,
3049
+ 'symbol': market['symbol'],
3050
+ 'status': undefined,
3051
+ };
3052
+ }
3053
+ async setMargin(symbol, amount, params = {}) {
3054
+ /**
3055
+ * @method
3056
+ * @name bitrue#setMargin
3057
+ * @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value
3058
+ * @see https://www.bitrue.com/api-docs#modify-isolated-position-margin-trade-hmac-sha256
3059
+ * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#modify-isolated-position-margin-trade-hmac-sha256
3060
+ * @param {string} symbol unified market symbol of the market to set margin in
3061
+ * @param {float} amount the amount to set the margin to
3062
+ * @param {object} [params] parameters specific to the exchange API endpoint
3063
+ * @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure}
3064
+ */
3065
+ await this.loadMarkets();
3066
+ const market = this.market(symbol);
3067
+ if (!market['swap']) {
3068
+ throw new errors.NotSupported(this.id + ' setMargin only support swap markets');
3069
+ }
3070
+ let response = undefined;
3071
+ const request = {
3072
+ 'contractName': market['id'],
3073
+ 'amount': this.parseToNumeric(amount),
3074
+ };
3075
+ if (market['linear']) {
3076
+ response = await this.fapiV2PrivatePostPositionMargin(this.extend(request, params));
3077
+ }
3078
+ else if (market['inverse']) {
3079
+ response = await this.dapiV2PrivatePostPositionMargin(this.extend(request, params));
3080
+ }
3081
+ //
3082
+ // {
3083
+ // "code": 0,
3084
+ // "msg": "success"
3085
+ // "data": null
3086
+ // }
3087
+ //
3088
+ return this.parseMarginModification(response, market);
3089
+ }
3090
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
3091
+ const type = this.safeString(api, 0);
3092
+ const version = this.safeString(api, 1);
3093
+ const access = this.safeString(api, 2);
3094
+ let url = undefined;
3095
+ if (type === 'api' && version === 'kline') {
3096
+ url = this.urls['api'][type];
3097
+ }
3098
+ else {
3099
+ url = this.urls['api'][type] + '/' + version;
3100
+ }
3101
+ url = url + '/' + this.implodeParams(path, params);
3102
+ params = this.omit(params, this.extractParams(path));
3103
+ if (access === 'private') {
3104
+ this.checkRequiredCredentials();
3105
+ const recvWindow = this.safeInteger(this.options, 'recvWindow', 5000);
3106
+ if (type === 'spot') {
3107
+ let query = this.urlencode(this.extend({
3108
+ 'timestamp': this.nonce(),
3109
+ 'recvWindow': recvWindow,
3110
+ }, params));
3111
+ const signature = this.hmac(this.encode(query), this.encode(this.secret), sha256.sha256);
3112
+ query += '&' + 'signature=' + signature;
3113
+ headers = {
3114
+ 'X-MBX-APIKEY': this.apiKey,
3115
+ };
3116
+ if ((method === 'GET') || (method === 'DELETE')) {
3117
+ url += '?' + query;
3118
+ }
3119
+ else {
3120
+ body = query;
3121
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
3122
+ }
3123
+ }
3124
+ else {
3125
+ const timestamp = this.nonce().toString();
3126
+ let signPath = undefined;
3127
+ if (type === 'fapi') {
3128
+ signPath = '/fapi';
3129
+ }
3130
+ else if (type === 'dapi') {
3131
+ signPath = '/dapi';
3132
+ }
3133
+ signPath = signPath + '/' + version + '/' + path;
3134
+ let signMessage = timestamp + method + signPath;
3135
+ if (method === 'GET') {
3136
+ const signature = this.hmac(this.encode(signMessage), this.encode(this.secret), sha256.sha256);
3137
+ headers = {
3138
+ 'X-CH-APIKEY': this.apiKey,
3139
+ 'X-CH-SIGN': signature,
3140
+ 'X-CH-TS': timestamp,
3141
+ };
3142
+ url += '?' + this.urlencode(params);
3143
+ }
3144
+ else {
3145
+ const query = this.extend({
3146
+ 'recvWindow': recvWindow,
3147
+ }, params);
3148
+ body = this.json(query);
3149
+ signMessage = signMessage + JSON.stringify(body);
3150
+ const signature = this.hmac(this.encode(signMessage), this.encode(this.secret), sha256.sha256);
3151
+ headers = {
3152
+ 'Content-Type': 'application/json',
3153
+ 'X-CH-APIKEY': this.apiKey,
3154
+ 'X-CH-SIGN': signature,
3155
+ 'X-CH-TS': timestamp,
3156
+ };
3157
+ }
3158
+ }
3159
+ }
3160
+ else {
3161
+ if (Object.keys(params).length) {
3162
+ url += '?' + this.urlencode(params);
3163
+ }
3164
+ }
3165
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3166
+ }
3167
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3168
+ if ((code === 418) || (code === 429)) {
3169
+ throw new errors.DDoSProtection(this.id + ' ' + code.toString() + ' ' + reason + ' ' + body);
3170
+ }
3171
+ // error response in a form: { "code": -1013, "msg": "Invalid quantity." }
3172
+ // following block cointains legacy checks against message patterns in "msg" property
3173
+ // will switch "code" checks eventually, when we know all of them
3174
+ if (code >= 400) {
3175
+ if (body.indexOf('Price * QTY is zero or less') >= 0) {
3176
+ throw new errors.InvalidOrder(this.id + ' order cost = amount * price is zero or less ' + body);
3177
+ }
3178
+ if (body.indexOf('LOT_SIZE') >= 0) {
3179
+ throw new errors.InvalidOrder(this.id + ' order amount should be evenly divisible by lot size ' + body);
3180
+ }
3181
+ if (body.indexOf('PRICE_FILTER') >= 0) {
3182
+ throw new errors.InvalidOrder(this.id + ' order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) ' + body);
3183
+ }
3184
+ }
3185
+ if (response === undefined) {
3186
+ return undefined; // fallback to default error handler
3187
+ }
3188
+ // check success value for wapi endpoints
3189
+ // response in format {'msg': 'The coin does not exist.', 'success': true/false}
3190
+ const success = this.safeValue(response, 'success', true);
3191
+ if (!success) {
3192
+ const messageInner = this.safeString(response, 'msg');
3193
+ let parsedMessage = undefined;
3194
+ if (messageInner !== undefined) {
3195
+ try {
3196
+ parsedMessage = JSON.parse(messageInner);
3197
+ }
3198
+ catch (e) {
3199
+ // do nothing
3200
+ parsedMessage = undefined;
3201
+ }
3202
+ if (parsedMessage !== undefined) {
3203
+ response = parsedMessage;
3204
+ }
3205
+ }
3206
+ }
3207
+ const message = this.safeString(response, 'msg');
3208
+ if (message !== undefined) {
3209
+ this.throwExactlyMatchedException(this.exceptions['exact'], message, this.id + ' ' + message);
3210
+ this.throwBroadlyMatchedException(this.exceptions['broad'], message, this.id + ' ' + message);
3211
+ }
3212
+ // checks against error codes
3213
+ const error = this.safeString(response, 'code');
3214
+ if (error !== undefined) {
3215
+ // https://github.com/ccxt/ccxt/issues/6501
3216
+ // https://github.com/ccxt/ccxt/issues/7742
3217
+ if ((error === '200') || Precise["default"].stringEquals(error, '0')) {
3218
+ return undefined;
3219
+ }
3220
+ // a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."}
3221
+ // despite that their message is very confusing, it is raised by Binance
3222
+ // on a temporary ban, the API key is valid, but disabled for a while
3223
+ if ((error === '-2015') && this.options['hasAlreadyAuthenticatedSuccessfully']) {
3224
+ throw new errors.DDoSProtection(this.id + ' temporary banned: ' + body);
3225
+ }
3226
+ const feedback = this.id + ' ' + body;
3227
+ this.throwExactlyMatchedException(this.exceptions['exact'], error, feedback);
3228
+ throw new errors.ExchangeError(feedback);
3229
+ }
3230
+ if (!success) {
3231
+ throw new errors.ExchangeError(this.id + ' ' + body);
3232
+ }
3233
+ return undefined;
3234
+ }
3235
+ calculateRateLimiterCost(api, method, path, params, config = {}) {
3236
+ if (('noSymbol' in config) && !('symbol' in params)) {
3237
+ return config['noSymbol'];
3238
+ }
3239
+ else if (('byLimit' in config) && ('limit' in params)) {
3240
+ const limit = params['limit'];
3241
+ const byLimit = config['byLimit'];
3242
+ for (let i = 0; i < byLimit.length; i++) {
3243
+ const entry = byLimit[i];
3244
+ if (limit <= entry[0]) {
3245
+ return entry[1];
3246
+ }
3247
+ }
3248
+ }
3249
+ return this.safeValue(config, 'cost', 1);
3250
+ }
3251
+ }
3252
+
3253
+ module.exports = bitrue;