ccxt 4.2.11 → 4.2.13

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 (392) hide show
  1. package/README.md +5 -5
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +1347 -490
  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 +2209 -0
  125. package/dist/cjs/js/src/binance.js +9736 -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 +3807 -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 +8291 -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 +3424 -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 +7072 -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 +9049 -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 +761 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2857 -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 +2851 -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 +7330 -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 +4722 -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 +1608 -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 +1867 -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 +2765 -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/js/ccxt.d.ts +1 -1
  329. package/js/ccxt.js +1 -1
  330. package/js/src/abstract/bigone.d.ts +18 -0
  331. package/js/src/abstract/binance.d.ts +2 -0
  332. package/js/src/abstract/binancecoinm.d.ts +2 -0
  333. package/js/src/abstract/binanceus.d.ts +2 -0
  334. package/js/src/abstract/binanceusdm.d.ts +2 -0
  335. package/js/src/abstract/bingx.d.ts +2 -0
  336. package/js/src/abstract/bybit.d.ts +1 -0
  337. package/js/src/abstract/gate.d.ts +11 -0
  338. package/js/src/abstract/gateio.d.ts +11 -0
  339. package/js/src/abstract/okx.d.ts +1 -0
  340. package/js/src/alpaca.js +18 -18
  341. package/js/src/base/Exchange.d.ts +5 -1
  342. package/js/src/base/Exchange.js +101 -12
  343. package/js/src/bigone.d.ts +3 -2
  344. package/js/src/bigone.js +429 -167
  345. package/js/src/binance.js +48 -34
  346. package/js/src/bingx.js +115 -38
  347. package/js/src/bitfinex.d.ts +2 -2
  348. package/js/src/bitfinex.js +2 -3
  349. package/js/src/bitget.js +33 -13
  350. package/js/src/bitmart.d.ts +2 -2
  351. package/js/src/bitmart.js +5 -5
  352. package/js/src/bitmex.js +1 -0
  353. package/js/src/bybit.js +2 -0
  354. package/js/src/coinbase.d.ts +26 -3
  355. package/js/src/coinbase.js +176 -26
  356. package/js/src/coinlist.js +3 -4
  357. package/js/src/coinone.js +1 -1
  358. package/js/src/coinsph.js +2 -3
  359. package/js/src/deribit.js +1 -0
  360. package/js/src/gate.d.ts +4 -4
  361. package/js/src/gate.js +96 -59
  362. package/js/src/gemini.js +1 -1
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.d.ts +1 -0
  366. package/js/src/htx.js +29 -7
  367. package/js/src/huobijp.js +2 -3
  368. package/js/src/independentreserve.js +7 -5
  369. package/js/src/kraken.js +3 -6
  370. package/js/src/lbank.js +59 -33
  371. package/js/src/mexc.js +2 -1
  372. package/js/src/oceanex.js +1 -1
  373. package/js/src/okx.js +14 -3
  374. package/js/src/phemex.js +9 -2
  375. package/js/src/pro/binance.d.ts +2 -23
  376. package/js/src/pro/binance.js +58 -22
  377. package/js/src/pro/coinbase.d.ts +2 -2
  378. package/js/src/pro/coinbase.js +4 -1
  379. package/js/src/pro/coinbasepro.d.ts +2 -2
  380. package/js/src/pro/hitbtc.d.ts +2 -2
  381. package/js/src/pro/kraken.js +1 -1
  382. package/js/src/pro/okx.d.ts +1 -0
  383. package/js/src/pro/okx.js +52 -2
  384. package/js/src/pro/poloniex.d.ts +2 -2
  385. package/js/src/probit.js +4 -2
  386. package/js/src/upbit.d.ts +3 -101
  387. package/js/src/upbit.js +12 -12
  388. package/js/src/wavesexchange.js +1 -1
  389. package/js/src/woo.d.ts +2 -0
  390. package/js/src/woo.js +52 -0
  391. package/package.json +1 -1
  392. package/skip-tests.json +5 -0
@@ -0,0 +1,2857 @@
1
+ 'use strict';
2
+
3
+ var kraken$1 = require('./abstract/kraken.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
+ var sha512 = require('./static_dependencies/noble-hashes/sha512.js');
9
+
10
+ // ---------------------------------------------------------------------------
11
+ // ---------------------------------------------------------------------------
12
+ /**
13
+ * @class kraken
14
+ * @augments Exchange
15
+ */
16
+ class kraken extends kraken$1 {
17
+ describe() {
18
+ return this.deepExtend(super.describe(), {
19
+ 'id': 'kraken',
20
+ 'name': 'Kraken',
21
+ 'countries': ['US'],
22
+ 'version': '0',
23
+ 'rateLimit': 1000,
24
+ 'certified': false,
25
+ 'pro': true,
26
+ 'has': {
27
+ 'CORS': undefined,
28
+ 'spot': true,
29
+ 'margin': true,
30
+ 'swap': false,
31
+ 'future': false,
32
+ 'option': false,
33
+ 'addMargin': false,
34
+ 'cancelAllOrders': true,
35
+ 'cancelOrder': true,
36
+ 'cancelOrders': true,
37
+ 'createDepositAddress': true,
38
+ 'createOrder': true,
39
+ 'createStopLimitOrder': true,
40
+ 'createStopMarketOrder': true,
41
+ 'createStopOrder': true,
42
+ 'createTrailingAmountOrder': true,
43
+ 'editOrder': true,
44
+ 'fetchBalance': true,
45
+ 'fetchBorrowInterest': false,
46
+ 'fetchBorrowRateHistories': false,
47
+ 'fetchBorrowRateHistory': false,
48
+ 'fetchClosedOrders': true,
49
+ 'fetchCrossBorrowRate': false,
50
+ 'fetchCrossBorrowRates': false,
51
+ 'fetchCurrencies': true,
52
+ 'fetchDepositAddress': true,
53
+ 'fetchDeposits': true,
54
+ 'fetchFundingHistory': false,
55
+ 'fetchFundingRate': false,
56
+ 'fetchFundingRateHistory': false,
57
+ 'fetchFundingRates': false,
58
+ 'fetchIndexOHLCV': false,
59
+ 'fetchIsolatedBorrowRate': false,
60
+ 'fetchIsolatedBorrowRates': false,
61
+ 'fetchLedger': true,
62
+ 'fetchLedgerEntry': true,
63
+ 'fetchLeverageTiers': false,
64
+ 'fetchMarkets': true,
65
+ 'fetchMarkOHLCV': false,
66
+ 'fetchMyTrades': true,
67
+ 'fetchOHLCV': true,
68
+ 'fetchOpenInterestHistory': false,
69
+ 'fetchOpenOrders': true,
70
+ 'fetchOrder': true,
71
+ 'fetchOrderBook': true,
72
+ 'fetchOrderTrades': 'emulated',
73
+ 'fetchPositions': true,
74
+ 'fetchPremiumIndexOHLCV': false,
75
+ 'fetchTicker': true,
76
+ 'fetchTickers': true,
77
+ 'fetchTime': true,
78
+ 'fetchTrades': true,
79
+ 'fetchTradingFee': true,
80
+ 'fetchTradingFees': false,
81
+ 'fetchWithdrawals': true,
82
+ 'setLeverage': false,
83
+ 'setMarginMode': false,
84
+ 'transfer': true,
85
+ 'withdraw': true,
86
+ },
87
+ 'timeframes': {
88
+ '1m': 1,
89
+ '5m': 5,
90
+ '15m': 15,
91
+ '30m': 30,
92
+ '1h': 60,
93
+ '4h': 240,
94
+ '1d': 1440,
95
+ '1w': 10080,
96
+ '2w': 21600,
97
+ },
98
+ 'urls': {
99
+ 'logo': 'https://user-images.githubusercontent.com/51840849/76173629-fc67fb00-61b1-11ea-84fe-f2de582f58a3.jpg',
100
+ 'api': {
101
+ 'public': 'https://api.kraken.com',
102
+ 'private': 'https://api.kraken.com',
103
+ 'zendesk': 'https://kraken.zendesk.com/api/v2/help_center/en-us/articles', // use the public zendesk api to receive article bodies and bypass new anti-spam protections
104
+ },
105
+ 'www': 'https://www.kraken.com',
106
+ 'doc': 'https://www.kraken.com/features/api',
107
+ 'fees': 'https://www.kraken.com/en-us/features/fee-schedule',
108
+ },
109
+ 'fees': {
110
+ 'trading': {
111
+ 'tierBased': true,
112
+ 'percentage': true,
113
+ 'taker': this.parseNumber('0.0026'),
114
+ 'maker': this.parseNumber('0.0016'),
115
+ 'tiers': {
116
+ 'taker': [
117
+ [this.parseNumber('0'), this.parseNumber('0.0026')],
118
+ [this.parseNumber('50000'), this.parseNumber('0.0024')],
119
+ [this.parseNumber('100000'), this.parseNumber('0.0022')],
120
+ [this.parseNumber('250000'), this.parseNumber('0.0020')],
121
+ [this.parseNumber('500000'), this.parseNumber('0.0018')],
122
+ [this.parseNumber('1000000'), this.parseNumber('0.0016')],
123
+ [this.parseNumber('2500000'), this.parseNumber('0.0014')],
124
+ [this.parseNumber('5000000'), this.parseNumber('0.0012')],
125
+ [this.parseNumber('10000000'), this.parseNumber('0.0001')],
126
+ ],
127
+ 'maker': [
128
+ [this.parseNumber('0'), this.parseNumber('0.0016')],
129
+ [this.parseNumber('50000'), this.parseNumber('0.0014')],
130
+ [this.parseNumber('100000'), this.parseNumber('0.0012')],
131
+ [this.parseNumber('250000'), this.parseNumber('0.0010')],
132
+ [this.parseNumber('500000'), this.parseNumber('0.0008')],
133
+ [this.parseNumber('1000000'), this.parseNumber('0.0006')],
134
+ [this.parseNumber('2500000'), this.parseNumber('0.0004')],
135
+ [this.parseNumber('5000000'), this.parseNumber('0.0002')],
136
+ [this.parseNumber('10000000'), this.parseNumber('0.0')],
137
+ ],
138
+ },
139
+ },
140
+ },
141
+ 'handleContentTypeApplicationZip': true,
142
+ 'api': {
143
+ 'zendesk': {
144
+ 'get': [
145
+ // we should really refrain from putting fixed fee numbers and stop hardcoding
146
+ // we will be using their web APIs to scrape all numbers from these articles
147
+ '360000292886',
148
+ '201893608', // -What-are-the-withdrawal-fees-
149
+ ],
150
+ },
151
+ 'public': {
152
+ 'get': {
153
+ // public endpoint rate-limits are described in article: https://support.kraken.com/hc/en-us/articles/206548367-What-are-the-API-rate-limits-#1
154
+ 'Assets': 1,
155
+ 'AssetPairs': 1,
156
+ 'Depth': 1,
157
+ 'OHLC': 1,
158
+ 'Spread': 1,
159
+ 'SystemStatus': 1,
160
+ 'Ticker': 1,
161
+ 'Time': 1,
162
+ 'Trades': 1,
163
+ },
164
+ },
165
+ 'private': {
166
+ 'post': {
167
+ 'AddOrder': 0,
168
+ 'AddOrderBatch': 0,
169
+ 'AddExport': 3,
170
+ 'Balance': 3,
171
+ 'CancelAll': 3,
172
+ 'CancelAllOrdersAfter': 3,
173
+ 'CancelOrder': 0,
174
+ 'CancelOrderBatch': 0,
175
+ 'ClosedOrders': 6,
176
+ 'DepositAddresses': 3,
177
+ 'DepositMethods': 3,
178
+ 'DepositStatus': 3,
179
+ 'EditOrder': 0,
180
+ 'ExportStatus': 3,
181
+ 'GetWebSocketsToken': 3,
182
+ 'Ledgers': 6,
183
+ 'OpenOrders': 3,
184
+ 'OpenPositions': 3,
185
+ 'QueryLedgers': 3,
186
+ 'QueryOrders': 3,
187
+ 'QueryTrades': 3,
188
+ 'RetrieveExport': 3,
189
+ 'RemoveExport': 3,
190
+ 'BalanceEx': 3,
191
+ 'TradeBalance': 3,
192
+ 'TradesHistory': 6,
193
+ 'TradeVolume': 3,
194
+ 'Withdraw': 3,
195
+ 'WithdrawCancel': 3,
196
+ 'WithdrawInfo': 3,
197
+ 'WithdrawMethods': 3,
198
+ 'WithdrawAddresses': 3,
199
+ 'WithdrawStatus': 3,
200
+ 'WalletTransfer': 3,
201
+ // sub accounts
202
+ 'CreateSubaccount': 3,
203
+ 'AccountTransfer': 3,
204
+ // earn
205
+ 'Earn/Allocate': 3,
206
+ 'Earn/Deallocate': 3,
207
+ 'Earn/AllocateStatus': 3,
208
+ 'Earn/DeallocateStatus': 3,
209
+ 'Earn/Strategies': 3,
210
+ 'Earn/Allocations': 3,
211
+ },
212
+ },
213
+ },
214
+ 'commonCurrencies': {
215
+ 'LUNA': 'LUNC',
216
+ 'LUNA2': 'LUNA',
217
+ 'REPV2': 'REP',
218
+ 'REP': 'REPV1',
219
+ 'UST': 'USTC',
220
+ 'XBT': 'BTC',
221
+ 'XBT.M': 'BTC.M',
222
+ 'XDG': 'DOGE',
223
+ },
224
+ 'options': {
225
+ 'marketsByAltname': {},
226
+ 'delistedMarketsById': {},
227
+ // cannot withdraw/deposit these
228
+ 'inactiveCurrencies': ['CAD', 'USD', 'JPY', 'GBP'],
229
+ 'networks': {
230
+ 'ETH': 'ERC20',
231
+ 'TRX': 'TRC20',
232
+ },
233
+ 'depositMethods': {
234
+ '1INCH': '1inch (1INCH)',
235
+ 'AAVE': 'Aave',
236
+ 'ADA': 'ADA',
237
+ 'ALGO': 'Algorand',
238
+ 'ANKR': 'ANKR (ANKR)',
239
+ 'ANT': 'Aragon (ANT)',
240
+ 'ATOM': 'Cosmos',
241
+ 'AXS': 'Axie Infinity Shards (AXS)',
242
+ 'BADGER': 'Bager DAO (BADGER)',
243
+ 'BAL': 'Balancer (BAL)',
244
+ 'BAND': 'Band Protocol (BAND)',
245
+ 'BAT': 'BAT',
246
+ 'BCH': 'Bitcoin Cash',
247
+ 'BNC': 'Bifrost (BNC)',
248
+ 'BNT': 'Bancor (BNT)',
249
+ 'BTC': 'Bitcoin',
250
+ 'CHZ': 'Chiliz (CHZ)',
251
+ 'COMP': 'Compound (COMP)',
252
+ 'CQT': '\tCovalent Query Token (CQT)',
253
+ 'CRV': 'Curve DAO Token (CRV)',
254
+ 'CTSI': 'Cartesi (CTSI)',
255
+ 'DAI': 'Dai',
256
+ 'DASH': 'Dash',
257
+ 'DOGE': 'Dogecoin',
258
+ 'DOT': 'Polkadot',
259
+ 'DYDX': 'dYdX (DYDX)',
260
+ 'ENJ': 'Enjin Coin (ENJ)',
261
+ 'EOS': 'EOS',
262
+ 'ETC': 'Ether Classic (Hex)',
263
+ 'ETH': 'Ether (Hex)',
264
+ 'EWT': 'Energy Web Token',
265
+ 'FEE': 'Kraken Fee Credit',
266
+ 'FIL': 'Filecoin',
267
+ 'FLOW': 'Flow',
268
+ 'GHST': 'Aavegotchi (GHST)',
269
+ 'GNO': 'GNO',
270
+ 'GRT': 'GRT',
271
+ 'ICX': 'Icon',
272
+ 'INJ': 'Injective Protocol (INJ)',
273
+ 'KAR': 'Karura (KAR)',
274
+ 'KAVA': 'Kava',
275
+ 'KEEP': 'Keep Token (KEEP)',
276
+ 'KNC': 'Kyber Network (KNC)',
277
+ 'KSM': 'Kusama',
278
+ 'LINK': 'Link',
279
+ 'LPT': 'Livepeer Token (LPT)',
280
+ 'LRC': 'Loopring (LRC)',
281
+ 'LSK': 'Lisk',
282
+ 'LTC': 'Litecoin',
283
+ 'MANA': 'MANA',
284
+ 'MATIC': 'Polygon (MATIC)',
285
+ 'MINA': 'Mina',
286
+ 'MIR': 'Mirror Protocol (MIR)',
287
+ 'MKR': 'Maker (MKR)',
288
+ 'MLN': 'MLN',
289
+ 'MOVR': 'Moonriver (MOVR)',
290
+ 'NANO': 'NANO',
291
+ 'OCEAN': 'OCEAN',
292
+ 'OGN': 'Origin Protocol (OGN)',
293
+ 'OMG': 'OMG',
294
+ 'OXT': 'Orchid (OXT)',
295
+ 'OXY': 'Oxygen (OXY)',
296
+ 'PAXG': 'PAX (Gold)',
297
+ 'PERP': 'Perpetual Protocol (PERP)',
298
+ 'PHA': 'Phala (PHA)',
299
+ 'QTUM': 'QTUM',
300
+ 'RARI': 'Rarible (RARI)',
301
+ 'RAY': 'Raydium (RAY)',
302
+ 'REN': 'Ren Protocol (REN)',
303
+ 'REP': 'REPv2',
304
+ 'REPV1': 'REP',
305
+ 'SAND': 'The Sandbox (SAND)',
306
+ 'SC': 'Siacoin',
307
+ 'SDN': 'Shiden (SDN)',
308
+ 'SOL': 'Solana',
309
+ 'SNX': 'Synthetix Network (SNX)',
310
+ 'SRM': 'Serum',
311
+ 'STORJ': 'Storj (STORJ)',
312
+ 'SUSHI': 'Sushiswap (SUSHI)',
313
+ 'TBTC': 'tBTC',
314
+ 'TRX': 'Tron',
315
+ 'UNI': 'UNI',
316
+ 'USDC': 'USDC',
317
+ 'USDT': 'Tether USD (ERC20)',
318
+ 'USDT-TRC20': 'Tether USD (TRC20)',
319
+ 'WAVES': 'Waves',
320
+ 'WBTC': 'Wrapped Bitcoin (WBTC)',
321
+ 'XLM': 'Stellar XLM',
322
+ 'XMR': 'Monero',
323
+ 'XRP': 'Ripple XRP',
324
+ 'XTZ': 'XTZ',
325
+ 'YFI': 'YFI',
326
+ 'ZEC': 'Zcash (Transparent)',
327
+ 'ZRX': '0x (ZRX)',
328
+ },
329
+ 'withdrawMethods': {
330
+ 'Lightning': 'Lightning',
331
+ 'Bitcoin': 'BTC',
332
+ 'Ripple': 'XRP',
333
+ 'Litecoin': 'LTC',
334
+ 'Dogecoin': 'DOGE',
335
+ 'Stellar': 'XLM',
336
+ 'Ethereum': 'ERC20',
337
+ 'Arbitrum One': 'Arbitrum',
338
+ 'Polygon': 'MATIC',
339
+ 'Arbitrum Nova': 'Arbitrum',
340
+ 'Optimism': 'Optimism',
341
+ 'zkSync Era': 'zkSync',
342
+ 'Ethereum Classic': 'ETC',
343
+ 'Zcash': 'ZEC',
344
+ 'Monero': 'XMR',
345
+ 'Tron': 'TRC20',
346
+ 'Solana': 'SOL',
347
+ 'EOS': 'EOS',
348
+ 'Bitcoin Cash': 'BCH',
349
+ 'Cardano': 'ADA',
350
+ 'Qtum': 'QTUM',
351
+ 'Tezos': 'XTZ',
352
+ 'Cosmos': 'ATOM',
353
+ 'Nano': 'NANO',
354
+ 'Siacoin': 'SC',
355
+ 'Lisk': 'LSK',
356
+ 'Waves': 'WAVES',
357
+ 'ICON': 'ICX',
358
+ 'Algorand': 'ALGO',
359
+ 'Polygon - USDC.e': 'MATIC',
360
+ 'Arbitrum One - USDC.e': 'Arbitrum',
361
+ 'Polkadot': 'DOT',
362
+ 'Kava': 'KAVA',
363
+ 'Filecoin': 'FIL',
364
+ 'Kusama': 'KSM',
365
+ 'Flow': 'FLOW',
366
+ 'Energy Web': 'EW',
367
+ 'Mina': 'MINA',
368
+ 'Centrifuge': 'CFG',
369
+ 'Karura': 'KAR',
370
+ 'Moonriver': 'MOVR',
371
+ 'Shiden': 'SDN',
372
+ 'Khala': 'PHA',
373
+ 'Bifrost Kusama': 'BNC',
374
+ 'Songbird': 'SGB',
375
+ 'Terra classic': 'LUNC',
376
+ 'KILT': 'KILT',
377
+ 'Basilisk': 'BSX',
378
+ 'Flare': 'FLR',
379
+ 'Avalanche C-Chain': 'AVAX',
380
+ 'Kintsugi': 'KINT',
381
+ 'Altair': 'AIR',
382
+ 'Moonbeam': 'GLMR',
383
+ 'Acala': 'ACA',
384
+ 'Astar': 'ASTR',
385
+ 'Akash': 'AKT',
386
+ 'Robonomics': 'XRT',
387
+ 'Fantom': 'FTM',
388
+ 'Elrond': 'EGLD',
389
+ 'THORchain': 'RUNE',
390
+ 'Secret': 'SCRT',
391
+ 'Near': 'NEAR',
392
+ 'Internet Computer Protocol': 'ICP',
393
+ 'Picasso': 'PICA',
394
+ 'Crust Shadow': 'CSM',
395
+ 'Integritee': 'TEER',
396
+ 'Parallel Finance': 'PARA',
397
+ 'HydraDX': 'HDX',
398
+ 'Interlay': 'INTR',
399
+ 'Fetch.ai': 'FET',
400
+ 'NYM': 'NYM',
401
+ 'Terra 2.0': 'LUNA2',
402
+ 'Juno': 'JUNO',
403
+ 'Nodle': 'NODL',
404
+ 'Stacks': 'STX',
405
+ 'Ethereum PoW': 'ETHW',
406
+ 'Aptos': 'APT',
407
+ 'Sui': 'SUI',
408
+ 'Genshiro': 'GENS',
409
+ 'Aventus': 'AVT',
410
+ 'Sei': 'SEI',
411
+ 'OriginTrail': 'OTP',
412
+ 'Celestia': 'TIA',
413
+ },
414
+ },
415
+ 'precisionMode': number.TICK_SIZE,
416
+ 'exceptions': {
417
+ 'EQuery:Invalid asset pair': errors.BadSymbol,
418
+ 'EAPI:Invalid key': errors.AuthenticationError,
419
+ 'EFunding:Unknown withdraw key': errors.InvalidAddress,
420
+ 'EFunding:Invalid amount': errors.InsufficientFunds,
421
+ 'EService:Unavailable': errors.ExchangeNotAvailable,
422
+ 'EDatabase:Internal error': errors.ExchangeNotAvailable,
423
+ 'EService:Busy': errors.ExchangeNotAvailable,
424
+ 'EQuery:Unknown asset': errors.BadSymbol,
425
+ 'EAPI:Rate limit exceeded': errors.DDoSProtection,
426
+ 'EOrder:Rate limit exceeded': errors.DDoSProtection,
427
+ 'EGeneral:Internal error': errors.ExchangeNotAvailable,
428
+ 'EGeneral:Temporary lockout': errors.DDoSProtection,
429
+ 'EGeneral:Permission denied': errors.PermissionDenied,
430
+ 'EOrder:Unknown order': errors.InvalidOrder,
431
+ 'EOrder:Order minimum not met': errors.InvalidOrder,
432
+ 'EGeneral:Invalid arguments': errors.BadRequest,
433
+ 'ESession:Invalid session': errors.AuthenticationError,
434
+ 'EAPI:Invalid nonce': errors.InvalidNonce,
435
+ 'EFunding:No funding method': errors.BadRequest,
436
+ 'EFunding:Unknown asset': errors.BadSymbol,
437
+ 'EService:Market in post_only mode': errors.OnMaintenance,
438
+ 'EGeneral:Too many requests': errors.DDoSProtection,
439
+ 'ETrade:User Locked': errors.AccountSuspended, // {"error":["ETrade:User Locked"]}
440
+ },
441
+ });
442
+ }
443
+ feeToPrecision(symbol, fee) {
444
+ return this.decimalToPrecision(fee, number.TRUNCATE, this.markets[symbol]['precision']['amount'], this.precisionMode);
445
+ }
446
+ async fetchMarkets(params = {}) {
447
+ /**
448
+ * @method
449
+ * @name kraken#fetchMarkets
450
+ * @description retrieves data on all markets for kraken
451
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getTradableAssetPairs
452
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
453
+ * @returns {object[]} an array of objects representing market data
454
+ */
455
+ const response = await this.publicGetAssetPairs(params);
456
+ //
457
+ // {
458
+ // "error": [],
459
+ // "result": {
460
+ // "ADAETH": {
461
+ // "altname": "ADAETH",
462
+ // "wsname": "ADA\/ETH",
463
+ // "aclass_base": "currency",
464
+ // "base": "ADA",
465
+ // "aclass_quote": "currency",
466
+ // "quote": "XETH",
467
+ // "lot": "unit",
468
+ // "pair_decimals": 7,
469
+ // "lot_decimals": 8,
470
+ // "lot_multiplier": 1,
471
+ // "leverage_buy": [],
472
+ // "leverage_sell": [],
473
+ // "fees": [
474
+ // [0, 0.26],
475
+ // [50000, 0.24],
476
+ // [100000, 0.22],
477
+ // [250000, 0.2],
478
+ // [500000, 0.18],
479
+ // [1000000, 0.16],
480
+ // [2500000, 0.14],
481
+ // [5000000, 0.12],
482
+ // [10000000, 0.1]
483
+ // ],
484
+ // "fees_maker": [
485
+ // [0, 0.16],
486
+ // [50000, 0.14],
487
+ // [100000, 0.12],
488
+ // [250000, 0.1],
489
+ // [500000, 0.08],
490
+ // [1000000, 0.06],
491
+ // [2500000, 0.04],
492
+ // [5000000, 0.02],
493
+ // [10000000, 0]
494
+ // ],
495
+ // "fee_volume_currency": "ZUSD",
496
+ // "margin_call": 80,
497
+ // "margin_stop": 40,
498
+ // "ordermin": "1"
499
+ // },
500
+ // }
501
+ // }
502
+ //
503
+ const markets = this.safeValue(response, 'result', {});
504
+ const keys = Object.keys(markets);
505
+ let result = [];
506
+ for (let i = 0; i < keys.length; i++) {
507
+ const id = keys[i];
508
+ const market = markets[id];
509
+ const baseId = this.safeString(market, 'base');
510
+ const quoteId = this.safeString(market, 'quote');
511
+ const base = this.safeCurrencyCode(baseId);
512
+ const quote = this.safeCurrencyCode(quoteId);
513
+ const darkpool = id.indexOf('.d') >= 0;
514
+ const altname = this.safeString(market, 'altname');
515
+ const makerFees = this.safeValue(market, 'fees_maker', []);
516
+ const firstMakerFee = this.safeValue(makerFees, 0, []);
517
+ const firstMakerFeeRate = this.safeString(firstMakerFee, 1);
518
+ let maker = undefined;
519
+ if (firstMakerFeeRate !== undefined) {
520
+ maker = this.parseNumber(Precise["default"].stringDiv(firstMakerFeeRate, '100'));
521
+ }
522
+ const takerFees = this.safeValue(market, 'fees', []);
523
+ const firstTakerFee = this.safeValue(takerFees, 0, []);
524
+ const firstTakerFeeRate = this.safeString(firstTakerFee, 1);
525
+ let taker = undefined;
526
+ if (firstTakerFeeRate !== undefined) {
527
+ taker = this.parseNumber(Precise["default"].stringDiv(firstTakerFeeRate, '100'));
528
+ }
529
+ const leverageBuy = this.safeValue(market, 'leverage_buy', []);
530
+ const leverageBuyLength = leverageBuy.length;
531
+ const precisionPrice = this.parseNumber(this.parsePrecision(this.safeString(market, 'pair_decimals')));
532
+ result.push({
533
+ 'id': id,
534
+ 'wsId': this.safeString(market, 'wsname'),
535
+ 'symbol': darkpool ? altname : (base + '/' + quote),
536
+ 'base': base,
537
+ 'quote': quote,
538
+ 'settle': undefined,
539
+ 'baseId': baseId,
540
+ 'quoteId': quoteId,
541
+ 'settleId': undefined,
542
+ 'darkpool': darkpool,
543
+ 'altname': market['altname'],
544
+ 'type': 'spot',
545
+ 'spot': true,
546
+ 'margin': (leverageBuyLength > 0),
547
+ 'swap': false,
548
+ 'future': false,
549
+ 'option': false,
550
+ 'active': true,
551
+ 'contract': false,
552
+ 'linear': undefined,
553
+ 'inverse': undefined,
554
+ 'taker': taker,
555
+ 'maker': maker,
556
+ 'contractSize': undefined,
557
+ 'expiry': undefined,
558
+ 'expiryDatetime': undefined,
559
+ 'strike': undefined,
560
+ 'optionType': undefined,
561
+ 'precision': {
562
+ 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'lot_decimals'))),
563
+ 'price': precisionPrice,
564
+ },
565
+ 'limits': {
566
+ 'leverage': {
567
+ 'min': this.parseNumber('1'),
568
+ 'max': this.safeNumber(leverageBuy, leverageBuyLength - 1, 1),
569
+ },
570
+ 'amount': {
571
+ 'min': this.safeNumber(market, 'ordermin'),
572
+ 'max': undefined,
573
+ },
574
+ 'price': {
575
+ 'min': precisionPrice,
576
+ 'max': undefined,
577
+ },
578
+ 'cost': {
579
+ 'min': this.safeNumber(market, 'costmin'),
580
+ 'max': undefined,
581
+ },
582
+ },
583
+ 'created': undefined,
584
+ 'info': market,
585
+ });
586
+ }
587
+ result = this.appendInactiveMarkets(result);
588
+ this.options['marketsByAltname'] = this.indexBy(result, 'altname');
589
+ return result;
590
+ }
591
+ safeCurrency(currencyId, currency = undefined) {
592
+ if (currencyId !== undefined) {
593
+ if (currencyId.length > 3) {
594
+ if ((currencyId.indexOf('X') === 0) || (currencyId.indexOf('Z') === 0)) {
595
+ if (currencyId.indexOf('.') > 0) {
596
+ return super.safeCurrency(currencyId, currency);
597
+ }
598
+ else {
599
+ currencyId = currencyId.slice(1);
600
+ }
601
+ }
602
+ }
603
+ }
604
+ return super.safeCurrency(currencyId, currency);
605
+ }
606
+ appendInactiveMarkets(result) {
607
+ // result should be an array to append to
608
+ const precision = {
609
+ 'amount': this.parseNumber('1e-8'),
610
+ 'price': this.parseNumber('1e-8'),
611
+ };
612
+ const costLimits = { 'min': undefined, 'max': undefined };
613
+ const priceLimits = { 'min': precision['price'], 'max': undefined };
614
+ const amountLimits = { 'min': precision['amount'], 'max': undefined };
615
+ const limits = { 'amount': amountLimits, 'price': priceLimits, 'cost': costLimits };
616
+ const defaults = {
617
+ 'darkpool': false,
618
+ 'info': undefined,
619
+ 'maker': undefined,
620
+ 'taker': undefined,
621
+ 'active': false,
622
+ 'precision': precision,
623
+ 'limits': limits,
624
+ };
625
+ const markets = [
626
+ // { 'id': 'XXLMZEUR', 'symbol': 'XLM/EUR', 'base': 'XLM', 'quote': 'EUR', 'altname': 'XLMEUR' },
627
+ ];
628
+ for (let i = 0; i < markets.length; i++) {
629
+ result.push(this.extend(defaults, markets[i]));
630
+ }
631
+ return result;
632
+ }
633
+ async fetchCurrencies(params = {}) {
634
+ /**
635
+ * @method
636
+ * @name kraken#fetchCurrencies
637
+ * @description fetches all available currencies on an exchange
638
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getAssetInfo
639
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
640
+ * @returns {object} an associative dictionary of currencies
641
+ */
642
+ const response = await this.publicGetAssets(params);
643
+ //
644
+ // {
645
+ // "error": [],
646
+ // "result": {
647
+ // "ADA": { "aclass": "currency", "altname": "ADA", "decimals": 8, "display_decimals": 6 },
648
+ // "BCH": { "aclass": "currency", "altname": "BCH", "decimals": 10, "display_decimals": 5 },
649
+ // ...
650
+ // },
651
+ // }
652
+ //
653
+ const currencies = this.safeValue(response, 'result', {});
654
+ const ids = Object.keys(currencies);
655
+ const result = {};
656
+ for (let i = 0; i < ids.length; i++) {
657
+ const id = ids[i];
658
+ const currency = currencies[id];
659
+ // todo: will need to rethink the fees
660
+ // see: https://support.kraken.com/hc/en-us/articles/201893608-What-are-the-withdrawal-fees-
661
+ // to add support for multiple withdrawal/deposit methods and
662
+ // differentiated fees for each particular method
663
+ const code = this.safeCurrencyCode(this.safeString(currency, 'altname'));
664
+ const precision = this.parseNumber(this.parsePrecision(this.safeString(currency, 'decimals')));
665
+ // assumes all currencies are active except those listed above
666
+ const active = !this.inArray(code, this.options['inactiveCurrencies']);
667
+ result[code] = {
668
+ 'id': id,
669
+ 'code': code,
670
+ 'info': currency,
671
+ 'name': code,
672
+ 'active': active,
673
+ 'deposit': undefined,
674
+ 'withdraw': undefined,
675
+ 'fee': undefined,
676
+ 'precision': precision,
677
+ 'limits': {
678
+ 'amount': {
679
+ 'min': precision,
680
+ 'max': undefined,
681
+ },
682
+ 'withdraw': {
683
+ 'min': undefined,
684
+ 'max': undefined,
685
+ },
686
+ },
687
+ 'networks': {},
688
+ };
689
+ }
690
+ return result;
691
+ }
692
+ async fetchTradingFee(symbol, params = {}) {
693
+ /**
694
+ * @method
695
+ * @name kraken#fetchTradingFee
696
+ * @description fetch the trading fees for a market
697
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeVolume
698
+ * @param {string} symbol unified market symbol
699
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
700
+ * @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
701
+ */
702
+ await this.loadMarkets();
703
+ const market = this.market(symbol);
704
+ const request = {
705
+ 'pair': market['id'],
706
+ 'fee-info': true,
707
+ };
708
+ const response = await this.privatePostTradeVolume(this.extend(request, params));
709
+ //
710
+ // {
711
+ // "error": [],
712
+ // "result": {
713
+ // "currency": 'ZUSD',
714
+ // "volume": '0.0000',
715
+ // "fees": {
716
+ // "XXBTZUSD": {
717
+ // "fee": '0.2600',
718
+ // "minfee": '0.1000',
719
+ // "maxfee": '0.2600',
720
+ // "nextfee": '0.2400',
721
+ // "tiervolume": '0.0000',
722
+ // "nextvolume": '50000.0000'
723
+ // }
724
+ // },
725
+ // "fees_maker": {
726
+ // "XXBTZUSD": {
727
+ // "fee": '0.1600',
728
+ // "minfee": '0.0000',
729
+ // "maxfee": '0.1600',
730
+ // "nextfee": '0.1400',
731
+ // "tiervolume": '0.0000',
732
+ // "nextvolume": '50000.0000'
733
+ // }
734
+ // }
735
+ // }
736
+ // }
737
+ //
738
+ const result = this.safeValue(response, 'result', {});
739
+ return this.parseTradingFee(result, market);
740
+ }
741
+ parseTradingFee(response, market) {
742
+ const makerFees = this.safeValue(response, 'fees_maker', {});
743
+ const takerFees = this.safeValue(response, 'fees', {});
744
+ const symbolMakerFee = this.safeValue(makerFees, market['id'], {});
745
+ const symbolTakerFee = this.safeValue(takerFees, market['id'], {});
746
+ return {
747
+ 'info': response,
748
+ 'symbol': market['symbol'],
749
+ 'maker': this.safeNumber(symbolMakerFee, 'fee'),
750
+ 'taker': this.safeNumber(symbolTakerFee, 'fee'),
751
+ 'percentage': true,
752
+ 'tierBased': true,
753
+ };
754
+ }
755
+ parseBidAsk(bidask, priceKey = 0, amountKey = 1, countOrIdKey = 2) {
756
+ const price = this.safeNumber(bidask, priceKey);
757
+ const amount = this.safeNumber(bidask, amountKey);
758
+ const timestamp = this.safeInteger(bidask, 2);
759
+ return [price, amount, timestamp];
760
+ }
761
+ async fetchOrderBook(symbol, limit = undefined, params = {}) {
762
+ /**
763
+ * @method
764
+ * @name kraken#fetchOrderBook
765
+ * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
766
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getOrderBook
767
+ * @param {string} symbol unified symbol of the market to fetch the order book for
768
+ * @param {int} [limit] the maximum amount of order book entries to return
769
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
770
+ * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
771
+ */
772
+ await this.loadMarkets();
773
+ const market = this.market(symbol);
774
+ if (market['darkpool']) {
775
+ throw new errors.ExchangeError(this.id + ' fetchOrderBook() does not provide an order book for darkpool symbol ' + symbol);
776
+ }
777
+ const request = {
778
+ 'pair': market['id'],
779
+ };
780
+ if (limit !== undefined) {
781
+ request['count'] = limit; // 100
782
+ }
783
+ const response = await this.publicGetDepth(this.extend(request, params));
784
+ //
785
+ // {
786
+ // "error":[],
787
+ // "result":{
788
+ // "XETHXXBT":{
789
+ // "asks":[
790
+ // ["0.023480","4.000",1586321307],
791
+ // ["0.023490","50.095",1586321306],
792
+ // ["0.023500","28.535",1586321302],
793
+ // ],
794
+ // "bids":[
795
+ // ["0.023470","59.580",1586321307],
796
+ // ["0.023460","20.000",1586321301],
797
+ // ["0.023440","67.832",1586321306],
798
+ // ]
799
+ // }
800
+ // }
801
+ // }
802
+ //
803
+ const result = this.safeValue(response, 'result', {});
804
+ let orderbook = this.safeValue(result, market['id']);
805
+ // sometimes kraken returns wsname instead of market id
806
+ // https://github.com/ccxt/ccxt/issues/8662
807
+ const marketInfo = this.safeValue(market, 'info', {});
808
+ const wsName = this.safeValue(marketInfo, 'wsname');
809
+ if (wsName !== undefined) {
810
+ orderbook = this.safeValue(result, wsName, orderbook);
811
+ }
812
+ return this.parseOrderBook(orderbook, symbol);
813
+ }
814
+ parseTicker(ticker, market = undefined) {
815
+ //
816
+ // {
817
+ // "a":["2432.77000","1","1.000"],
818
+ // "b":["2431.37000","2","2.000"],
819
+ // "c":["2430.58000","0.04408910"],
820
+ // "v":["4147.94474901","8896.96086304"],
821
+ // "p":["2456.22239","2568.63032"],
822
+ // "t":[3907,10056],
823
+ // "l":["2302.18000","2302.18000"],
824
+ // "h":["2621.14000","2860.01000"],
825
+ // "o":"2571.56000"
826
+ // }
827
+ //
828
+ const symbol = this.safeSymbol(undefined, market);
829
+ const v = this.safeValue(ticker, 'v', []);
830
+ const baseVolume = this.safeString(v, 1);
831
+ const p = this.safeValue(ticker, 'p', []);
832
+ const vwap = this.safeString(p, 1);
833
+ const quoteVolume = Precise["default"].stringMul(baseVolume, vwap);
834
+ const c = this.safeValue(ticker, 'c', []);
835
+ const last = this.safeString(c, 0);
836
+ const high = this.safeValue(ticker, 'h', []);
837
+ const low = this.safeValue(ticker, 'l', []);
838
+ const bid = this.safeValue(ticker, 'b', []);
839
+ const ask = this.safeValue(ticker, 'a', []);
840
+ return this.safeTicker({
841
+ 'symbol': symbol,
842
+ 'timestamp': undefined,
843
+ 'datetime': undefined,
844
+ 'high': this.safeString(high, 1),
845
+ 'low': this.safeString(low, 1),
846
+ 'bid': this.safeString(bid, 0),
847
+ 'bidVolume': undefined,
848
+ 'ask': this.safeString(ask, 0),
849
+ 'askVolume': undefined,
850
+ 'vwap': vwap,
851
+ 'open': this.safeString(ticker, 'o'),
852
+ 'close': last,
853
+ 'last': last,
854
+ 'previousClose': undefined,
855
+ 'change': undefined,
856
+ 'percentage': undefined,
857
+ 'average': undefined,
858
+ 'baseVolume': baseVolume,
859
+ 'quoteVolume': quoteVolume,
860
+ 'info': ticker,
861
+ }, market);
862
+ }
863
+ async fetchTickers(symbols = undefined, params = {}) {
864
+ /**
865
+ * @method
866
+ * @name kraken#fetchTickers
867
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
868
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
869
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
870
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
871
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
872
+ */
873
+ await this.loadMarkets();
874
+ const request = {};
875
+ if (symbols !== undefined) {
876
+ symbols = this.marketSymbols(symbols);
877
+ const marketIds = [];
878
+ for (let i = 0; i < symbols.length; i++) {
879
+ const symbol = symbols[i];
880
+ const market = this.markets[symbol];
881
+ if (market['active'] && !market['darkpool']) {
882
+ marketIds.push(market['id']);
883
+ }
884
+ }
885
+ request['pair'] = marketIds.join(',');
886
+ }
887
+ const response = await this.publicGetTicker(this.extend(request, params));
888
+ const tickers = response['result'];
889
+ const ids = Object.keys(tickers);
890
+ const result = {};
891
+ for (let i = 0; i < ids.length; i++) {
892
+ const id = ids[i];
893
+ const market = this.safeMarket(id);
894
+ const symbol = market['symbol'];
895
+ const ticker = tickers[id];
896
+ result[symbol] = this.parseTicker(ticker, market);
897
+ }
898
+ return this.filterByArrayTickers(result, 'symbol', symbols);
899
+ }
900
+ async fetchTicker(symbol, params = {}) {
901
+ /**
902
+ * @method
903
+ * @name kraken#fetchTicker
904
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
905
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getTickerInformation
906
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
907
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
908
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
909
+ */
910
+ await this.loadMarkets();
911
+ const darkpool = symbol.indexOf('.d') >= 0;
912
+ if (darkpool) {
913
+ throw new errors.ExchangeError(this.id + ' fetchTicker() does not provide a ticker for darkpool symbol ' + symbol);
914
+ }
915
+ const market = this.market(symbol);
916
+ const request = {
917
+ 'pair': market['id'],
918
+ };
919
+ const response = await this.publicGetTicker(this.extend(request, params));
920
+ const ticker = response['result'][market['id']];
921
+ return this.parseTicker(ticker, market);
922
+ }
923
+ parseOHLCV(ohlcv, market = undefined) {
924
+ //
925
+ // [
926
+ // 1591475640,
927
+ // "0.02500",
928
+ // "0.02500",
929
+ // "0.02500",
930
+ // "0.02500",
931
+ // "0.02500",
932
+ // "9.12201000",
933
+ // 5
934
+ // ]
935
+ //
936
+ return [
937
+ this.safeTimestamp(ohlcv, 0),
938
+ this.safeNumber(ohlcv, 1),
939
+ this.safeNumber(ohlcv, 2),
940
+ this.safeNumber(ohlcv, 3),
941
+ this.safeNumber(ohlcv, 4),
942
+ this.safeNumber(ohlcv, 6),
943
+ ];
944
+ }
945
+ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
946
+ /**
947
+ * @method
948
+ * @name kraken#fetchOHLCV
949
+ * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
950
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getOHLCData
951
+ * @param {string} symbol unified symbol of the market to fetch OHLCV data for
952
+ * @param {string} timeframe the length of time each candle represents
953
+ * @param {int} [since] timestamp in ms of the earliest candle to fetch
954
+ * @param {int} [limit] the maximum amount of candles to fetch
955
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
956
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
957
+ * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
958
+ */
959
+ await this.loadMarkets();
960
+ let paginate = false;
961
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
962
+ if (paginate) {
963
+ return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 720);
964
+ }
965
+ const market = this.market(symbol);
966
+ const parsedTimeframe = this.safeInteger(this.timeframes, timeframe);
967
+ const request = {
968
+ 'pair': market['id'],
969
+ };
970
+ if (parsedTimeframe !== undefined) {
971
+ request['interval'] = parsedTimeframe;
972
+ }
973
+ else {
974
+ request['interval'] = timeframe;
975
+ }
976
+ if (since !== undefined) {
977
+ request['since'] = this.parseToInt((since - 1) / 1000);
978
+ }
979
+ const response = await this.publicGetOHLC(this.extend(request, params));
980
+ //
981
+ // {
982
+ // "error":[],
983
+ // "result":{
984
+ // "XETHXXBT":[
985
+ // [1591475580,"0.02499","0.02499","0.02499","0.02499","0.00000","0.00000000",0],
986
+ // [1591475640,"0.02500","0.02500","0.02500","0.02500","0.02500","9.12201000",5],
987
+ // [1591475700,"0.02499","0.02499","0.02499","0.02499","0.02499","1.28681415",2],
988
+ // [1591475760,"0.02499","0.02499","0.02499","0.02499","0.02499","0.08800000",1],
989
+ // ],
990
+ // "last":1591517580
991
+ // }
992
+ // }
993
+ const result = this.safeValue(response, 'result', {});
994
+ const ohlcvs = this.safeValue(result, market['id'], []);
995
+ return this.parseOHLCVs(ohlcvs, market, timeframe, since, limit);
996
+ }
997
+ parseLedgerEntryType(type) {
998
+ const types = {
999
+ 'trade': 'trade',
1000
+ 'withdrawal': 'transaction',
1001
+ 'deposit': 'transaction',
1002
+ 'transfer': 'transfer',
1003
+ 'margin': 'margin',
1004
+ };
1005
+ return this.safeString(types, type, type);
1006
+ }
1007
+ parseLedgerEntry(item, currency = undefined) {
1008
+ //
1009
+ // {
1010
+ // 'LTFK7F-N2CUX-PNY4SX': {
1011
+ // "refid": "TSJTGT-DT7WN-GPPQMJ",
1012
+ // "time": 1520102320.555,
1013
+ // "type": "trade",
1014
+ // "aclass": "currency",
1015
+ // "asset": "XETH",
1016
+ // "amount": "0.1087194600",
1017
+ // "fee": "0.0000000000",
1018
+ // "balance": "0.2855851000"
1019
+ // },
1020
+ // ...
1021
+ // }
1022
+ //
1023
+ const id = this.safeString(item, 'id');
1024
+ let direction = undefined;
1025
+ const account = undefined;
1026
+ const referenceId = this.safeString(item, 'refid');
1027
+ const referenceAccount = undefined;
1028
+ const type = this.parseLedgerEntryType(this.safeString(item, 'type'));
1029
+ const code = this.safeCurrencyCode(this.safeString(item, 'asset'), currency);
1030
+ let amount = this.safeString(item, 'amount');
1031
+ if (Precise["default"].stringLt(amount, '0')) {
1032
+ direction = 'out';
1033
+ amount = Precise["default"].stringAbs(amount);
1034
+ }
1035
+ else {
1036
+ direction = 'in';
1037
+ }
1038
+ const timestamp = this.safeTimestamp(item, 'time');
1039
+ return {
1040
+ 'info': item,
1041
+ 'id': id,
1042
+ 'direction': direction,
1043
+ 'account': account,
1044
+ 'referenceId': referenceId,
1045
+ 'referenceAccount': referenceAccount,
1046
+ 'type': type,
1047
+ 'currency': code,
1048
+ 'amount': this.parseNumber(amount),
1049
+ 'before': undefined,
1050
+ 'after': this.safeNumber(item, 'balance'),
1051
+ 'status': 'ok',
1052
+ 'timestamp': timestamp,
1053
+ 'datetime': this.iso8601(timestamp),
1054
+ 'fee': {
1055
+ 'cost': this.safeNumber(item, 'fee'),
1056
+ 'currency': code,
1057
+ },
1058
+ };
1059
+ }
1060
+ async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
1061
+ /**
1062
+ * @method
1063
+ * @name kraken#fetchLedger
1064
+ * @description fetch the history of changes, actions done by the user or operations that altered balance of the user
1065
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getLedgers
1066
+ * @param {string} code unified currency code, default is undefined
1067
+ * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
1068
+ * @param {int} [limit] max number of ledger entrys to return, default is undefined
1069
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1070
+ * @param {int} [params.until] timestamp in ms of the latest ledger entry
1071
+ * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
1072
+ */
1073
+ // https://www.kraken.com/features/api#get-ledgers-info
1074
+ await this.loadMarkets();
1075
+ let request = {};
1076
+ let currency = undefined;
1077
+ if (code !== undefined) {
1078
+ currency = this.currency(code);
1079
+ request['asset'] = currency['id'];
1080
+ }
1081
+ if (since !== undefined) {
1082
+ request['start'] = this.parseToInt(since / 1000);
1083
+ }
1084
+ [request, params] = this.handleUntilOption('end', request, params);
1085
+ const response = await this.privatePostLedgers(this.extend(request, params));
1086
+ // { error: [],
1087
+ // "result": { ledger: { 'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
1088
+ // "time": 1520103488.314,
1089
+ // "type": "withdrawal",
1090
+ // "aclass": "currency",
1091
+ // "asset": "XETH",
1092
+ // "amount": "-0.2805800000",
1093
+ // "fee": "0.0050000000",
1094
+ // "balance": "0.0000051000" },
1095
+ const result = this.safeValue(response, 'result', {});
1096
+ const ledger = this.safeValue(result, 'ledger', {});
1097
+ const keys = Object.keys(ledger);
1098
+ const items = [];
1099
+ for (let i = 0; i < keys.length; i++) {
1100
+ const key = keys[i];
1101
+ const value = ledger[key];
1102
+ value['id'] = key;
1103
+ items.push(value);
1104
+ }
1105
+ return this.parseLedger(items, currency, since, limit);
1106
+ }
1107
+ async fetchLedgerEntriesByIds(ids, code = undefined, params = {}) {
1108
+ // https://www.kraken.com/features/api#query-ledgers
1109
+ await this.loadMarkets();
1110
+ ids = ids.join(',');
1111
+ const request = this.extend({
1112
+ 'id': ids,
1113
+ }, params);
1114
+ const response = await this.privatePostQueryLedgers(request);
1115
+ // { error: [],
1116
+ // "result": { 'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
1117
+ // "time": 1520103488.314,
1118
+ // "type": "withdrawal",
1119
+ // "aclass": "currency",
1120
+ // "asset": "XETH",
1121
+ // "amount": "-0.2805800000",
1122
+ // "fee": "0.0050000000",
1123
+ // "balance": "0.0000051000" } } }
1124
+ const result = response['result'];
1125
+ const keys = Object.keys(result);
1126
+ const items = [];
1127
+ for (let i = 0; i < keys.length; i++) {
1128
+ const key = keys[i];
1129
+ const value = result[key];
1130
+ value['id'] = key;
1131
+ items.push(value);
1132
+ }
1133
+ return this.parseLedger(items);
1134
+ }
1135
+ async fetchLedgerEntry(id, code = undefined, params = {}) {
1136
+ const items = await this.fetchLedgerEntriesByIds([id], code, params);
1137
+ return items[0];
1138
+ }
1139
+ parseTrade(trade, market = undefined) {
1140
+ //
1141
+ // fetchTrades (public)
1142
+ //
1143
+ // [
1144
+ // "0.032310", // price
1145
+ // "4.28169434", // amount
1146
+ // 1541390792.763, // timestamp
1147
+ // "s", // sell or buy
1148
+ // "l", // limit or market
1149
+ // ""
1150
+ // ]
1151
+ //
1152
+ // fetchOrderTrades (private)
1153
+ //
1154
+ // {
1155
+ // "id": 'TIMIRG-WUNNE-RRJ6GT', // injected from outside
1156
+ // "ordertxid": 'OQRPN2-LRHFY-HIFA7D',
1157
+ // "postxid": 'TKH2SE-M7IF5-CFI7LT',
1158
+ // "pair": 'USDCUSDT',
1159
+ // "time": 1586340086.457,
1160
+ // "type": 'sell',
1161
+ // "ordertype": 'market',
1162
+ // "price": '0.99860000',
1163
+ // "cost": '22.16892001',
1164
+ // "fee": '0.04433784',
1165
+ // "vol": '22.20000000',
1166
+ // "margin": '0.00000000',
1167
+ // "misc": ''
1168
+ // }
1169
+ //
1170
+ let timestamp = undefined;
1171
+ let side = undefined;
1172
+ let type = undefined;
1173
+ let price = undefined;
1174
+ let amount = undefined;
1175
+ let id = undefined;
1176
+ let orderId = undefined;
1177
+ let fee = undefined;
1178
+ let symbol = undefined;
1179
+ if (Array.isArray(trade)) {
1180
+ timestamp = this.safeTimestamp(trade, 2);
1181
+ side = (trade[3] === 's') ? 'sell' : 'buy';
1182
+ type = (trade[4] === 'l') ? 'limit' : 'market';
1183
+ price = this.safeString(trade, 0);
1184
+ amount = this.safeString(trade, 1);
1185
+ const tradeLength = trade.length;
1186
+ if (tradeLength > 6) {
1187
+ id = this.safeString(trade, 6); // artificially added as per #1794
1188
+ }
1189
+ }
1190
+ else if (typeof trade === 'string') {
1191
+ id = trade;
1192
+ }
1193
+ else if ('ordertxid' in trade) {
1194
+ const marketId = this.safeString(trade, 'pair');
1195
+ const foundMarket = this.findMarketByAltnameOrId(marketId);
1196
+ if (foundMarket !== undefined) {
1197
+ market = foundMarket;
1198
+ }
1199
+ else if (marketId !== undefined) {
1200
+ // delisted market ids go here
1201
+ market = this.getDelistedMarketById(marketId);
1202
+ }
1203
+ orderId = this.safeString(trade, 'ordertxid');
1204
+ id = this.safeString2(trade, 'id', 'postxid');
1205
+ timestamp = this.safeTimestamp(trade, 'time');
1206
+ side = this.safeString(trade, 'type');
1207
+ type = this.safeString(trade, 'ordertype');
1208
+ price = this.safeString(trade, 'price');
1209
+ amount = this.safeString(trade, 'vol');
1210
+ if ('fee' in trade) {
1211
+ let currency = undefined;
1212
+ if (market !== undefined) {
1213
+ currency = market['quote'];
1214
+ }
1215
+ fee = {
1216
+ 'cost': this.safeString(trade, 'fee'),
1217
+ 'currency': currency,
1218
+ };
1219
+ }
1220
+ }
1221
+ if (market !== undefined) {
1222
+ symbol = market['symbol'];
1223
+ }
1224
+ const cost = this.safeString(trade, 'cost');
1225
+ return this.safeTrade({
1226
+ 'id': id,
1227
+ 'order': orderId,
1228
+ 'info': trade,
1229
+ 'timestamp': timestamp,
1230
+ 'datetime': this.iso8601(timestamp),
1231
+ 'symbol': symbol,
1232
+ 'type': type,
1233
+ 'side': side,
1234
+ 'takerOrMaker': undefined,
1235
+ 'price': price,
1236
+ 'amount': amount,
1237
+ 'cost': cost,
1238
+ 'fee': fee,
1239
+ }, market);
1240
+ }
1241
+ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
1242
+ /**
1243
+ * @method
1244
+ * @name kraken#fetchTrades
1245
+ * @description get the list of most recent trades for a particular symbol
1246
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getRecentTrades
1247
+ * @param {string} symbol unified symbol of the market to fetch trades for
1248
+ * @param {int} [since] timestamp in ms of the earliest trade to fetch
1249
+ * @param {int} [limit] the maximum amount of trades to fetch
1250
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1251
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
1252
+ */
1253
+ await this.loadMarkets();
1254
+ const market = this.market(symbol);
1255
+ const id = market['id'];
1256
+ const request = {
1257
+ 'pair': id,
1258
+ };
1259
+ // https://support.kraken.com/hc/en-us/articles/218198197-How-to-pull-all-trade-data-using-the-Kraken-REST-API
1260
+ // https://github.com/ccxt/ccxt/issues/5677
1261
+ if (since !== undefined) {
1262
+ // php does not format it properly
1263
+ // therefore we use string concatenation here
1264
+ request['since'] = since * 1e6;
1265
+ request['since'] = since.toString() + '000000'; // expected to be in nanoseconds
1266
+ }
1267
+ if (limit !== undefined) {
1268
+ request['count'] = limit;
1269
+ }
1270
+ const response = await this.publicGetTrades(this.extend(request, params));
1271
+ //
1272
+ // {
1273
+ // "error": [],
1274
+ // "result": {
1275
+ // "XETHXXBT": [
1276
+ // ["0.032310","4.28169434",1541390792.763,"s","l",""]
1277
+ // ],
1278
+ // "last": "1541439421200678657"
1279
+ // }
1280
+ // }
1281
+ //
1282
+ const result = response['result'];
1283
+ const trades = result[id];
1284
+ // trades is a sorted array: last (most recent trade) goes last
1285
+ const length = trades.length;
1286
+ if (length <= 0) {
1287
+ return [];
1288
+ }
1289
+ const lastTrade = trades[length - 1];
1290
+ const lastTradeId = this.safeString(result, 'last');
1291
+ lastTrade.push(lastTradeId);
1292
+ return this.parseTrades(trades, market, since, limit);
1293
+ }
1294
+ parseBalance(response) {
1295
+ const balances = this.safeValue(response, 'result', {});
1296
+ const result = {
1297
+ 'info': response,
1298
+ 'timestamp': undefined,
1299
+ 'datetime': undefined,
1300
+ };
1301
+ const currencyIds = Object.keys(balances);
1302
+ for (let i = 0; i < currencyIds.length; i++) {
1303
+ const currencyId = currencyIds[i];
1304
+ const code = this.safeCurrencyCode(currencyId);
1305
+ const balance = this.safeValue(balances, currencyId, {});
1306
+ const account = this.account();
1307
+ account['used'] = this.safeString(balance, 'hold_trade');
1308
+ account['total'] = this.safeString(balance, 'balance');
1309
+ result[code] = account;
1310
+ }
1311
+ return this.safeBalance(result);
1312
+ }
1313
+ async fetchBalance(params = {}) {
1314
+ /**
1315
+ * @method
1316
+ * @name kraken#fetchBalance
1317
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1318
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getExtendedBalance
1319
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1320
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1321
+ */
1322
+ await this.loadMarkets();
1323
+ const response = await this.privatePostBalanceEx(params);
1324
+ //
1325
+ // {
1326
+ // "error": [],
1327
+ // "result": {
1328
+ // "ZUSD": {
1329
+ // "balance": 25435.21,
1330
+ // "hold_trade": 8249.76
1331
+ // },
1332
+ // "XXBT": {
1333
+ // "balance": 1.2435,
1334
+ // "hold_trade": 0.8423
1335
+ // }
1336
+ // }
1337
+ // }
1338
+ //
1339
+ return this.parseBalance(response);
1340
+ }
1341
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1342
+ /**
1343
+ * @method
1344
+ * @name kraken#createOrder
1345
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1346
+ * @description create a trade order
1347
+ * @param {string} symbol unified symbol of the market to create an order in
1348
+ * @param {string} type 'market' or 'limit'
1349
+ * @param {string} side 'buy' or 'sell'
1350
+ * @param {float} amount how much of currency you want to trade in units of base currency
1351
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1352
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1353
+ * @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
1354
+ * @param {bool} [params.reduceOnly] *margin only* indicates if this order is to reduce the size of a position
1355
+ * @param {float} [params.stopLossPrice] *margin only* the price that a stop loss order is triggered at
1356
+ * @param {float} [params.takeProfitPrice] *margin only* the price that a take profit order is triggered at
1357
+ * @param {string} [params.trailingAmount] *margin only* the quote amount to trail away from the current market price
1358
+ * @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount
1359
+ * @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
1360
+ * @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last'
1361
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1362
+ */
1363
+ await this.loadMarkets();
1364
+ const market = this.market(symbol);
1365
+ const request = {
1366
+ 'pair': market['id'],
1367
+ 'type': side,
1368
+ 'ordertype': type,
1369
+ 'volume': this.amountToPrecision(symbol, amount),
1370
+ };
1371
+ const orderRequest = this.orderRequest('createOrder()', symbol, type, request, price, params);
1372
+ const response = await this.privatePostAddOrder(this.extend(orderRequest[0], orderRequest[1]));
1373
+ //
1374
+ // {
1375
+ // "error": [],
1376
+ // "result": {
1377
+ // "descr": { order: 'buy 0.02100000 ETHUSDT @ limit 330.00' },
1378
+ // "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
1379
+ // }
1380
+ // }
1381
+ //
1382
+ const result = this.safeValue(response, 'result');
1383
+ return this.parseOrder(result);
1384
+ }
1385
+ findMarketByAltnameOrId(id) {
1386
+ const marketsByAltname = this.safeValue(this.options, 'marketsByAltname', {});
1387
+ if (id in marketsByAltname) {
1388
+ return marketsByAltname[id];
1389
+ }
1390
+ else {
1391
+ return this.safeMarket(id);
1392
+ }
1393
+ }
1394
+ getDelistedMarketById(id) {
1395
+ if (id === undefined) {
1396
+ return id;
1397
+ }
1398
+ let market = this.safeValue(this.options['delistedMarketsById'], id);
1399
+ if (market !== undefined) {
1400
+ return market;
1401
+ }
1402
+ const baseIdStart = 0;
1403
+ let baseIdEnd = 3;
1404
+ let quoteIdStart = 3;
1405
+ let quoteIdEnd = 6;
1406
+ if (id.length === 8) {
1407
+ baseIdEnd = 4;
1408
+ quoteIdStart = 4;
1409
+ quoteIdEnd = 8;
1410
+ }
1411
+ else if (id.length === 7) {
1412
+ baseIdEnd = 4;
1413
+ quoteIdStart = 4;
1414
+ quoteIdEnd = 7;
1415
+ }
1416
+ const baseId = id.slice(baseIdStart, baseIdEnd);
1417
+ const quoteId = id.slice(quoteIdStart, quoteIdEnd);
1418
+ const base = this.safeCurrencyCode(baseId);
1419
+ const quote = this.safeCurrencyCode(quoteId);
1420
+ const symbol = base + '/' + quote;
1421
+ market = {
1422
+ 'symbol': symbol,
1423
+ 'base': base,
1424
+ 'quote': quote,
1425
+ 'baseId': baseId,
1426
+ 'quoteId': quoteId,
1427
+ };
1428
+ this.options['delistedMarketsById'][id] = market;
1429
+ return market;
1430
+ }
1431
+ parseOrderStatus(status) {
1432
+ const statuses = {
1433
+ 'pending': 'open',
1434
+ 'open': 'open',
1435
+ 'closed': 'closed',
1436
+ 'canceled': 'canceled',
1437
+ 'expired': 'expired',
1438
+ };
1439
+ return this.safeString(statuses, status, status);
1440
+ }
1441
+ parseOrder(order, market = undefined) {
1442
+ //
1443
+ // createOrder for regular orders
1444
+ //
1445
+ // {
1446
+ // "descr": { order: 'buy 0.02100000 ETHUSDT @ limit 330.00' },
1447
+ // "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
1448
+ // }
1449
+ // {
1450
+ // "txid": [ "TX_ID_HERE" ],
1451
+ // "descr": { "order":"buy 0.12345678 ETHEUR @ market" },
1452
+ // }
1453
+ //
1454
+ //
1455
+ // createOrder for stop orders
1456
+ //
1457
+ // {
1458
+ // "txid":["OSILNC-VQI5Q-775ZDQ"],
1459
+ // "descr":{"order":"sell 167.28002676 ADAXBT @ stop loss 0.00003280 -> limit 0.00003212"}
1460
+ // }
1461
+ //
1462
+ //
1463
+ // {
1464
+ // "txid":["OVHMJV-BZW2V-6NZFWF"],
1465
+ // "descr":{"order":"sell 0.00100000 ETHUSD @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"}
1466
+ // }
1467
+ //
1468
+ // editOrder
1469
+ //
1470
+ // {
1471
+ // "status": "ok",
1472
+ // "txid": "OAW2BO-7RWEK-PZY5UO",
1473
+ // "originaltxid": "OXL6SS-UPNMC-26WBE7",
1474
+ // "volume": "0.00075000",
1475
+ // "price": "13500.0",
1476
+ // "orders_cancelled": 1,
1477
+ // "descr": {
1478
+ // "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
1479
+ // }
1480
+ // }
1481
+ // ws - createOrder
1482
+ // {
1483
+ // "descr": 'sell 0.00010000 XBTUSDT @ market',
1484
+ // "event": 'addOrderStatus',
1485
+ // "reqid": 1,
1486
+ // "status": 'ok',
1487
+ // "txid": 'OAVXZH-XIE54-JCYYDG'
1488
+ // }
1489
+ // ws - editOrder
1490
+ // {
1491
+ // "descr": "order edited price = 9000.00000000",
1492
+ // "event": "editOrderStatus",
1493
+ // "originaltxid": "O65KZW-J4AW3-VFS74A",
1494
+ // "reqid": 3,
1495
+ // "status": "ok",
1496
+ // "txid": "OTI672-HJFAO-XOIPPK"
1497
+ // }
1498
+ //
1499
+ const description = this.safeValue(order, 'descr', {});
1500
+ const orderDescription = this.safeString(description, 'order', description);
1501
+ let side = undefined;
1502
+ let type = undefined;
1503
+ let marketId = undefined;
1504
+ let price = undefined;
1505
+ let amount = undefined;
1506
+ let stopPrice = undefined;
1507
+ if (orderDescription !== undefined) {
1508
+ const parts = orderDescription.split(' ');
1509
+ side = this.safeString(parts, 0);
1510
+ amount = this.safeString(parts, 1);
1511
+ marketId = this.safeString(parts, 2);
1512
+ type = this.safeString(parts, 4);
1513
+ if (type === 'stop') {
1514
+ stopPrice = this.safeString(parts, 6);
1515
+ price = this.safeString(parts, 9);
1516
+ }
1517
+ else if (type === 'limit') {
1518
+ price = this.safeString(parts, 5);
1519
+ }
1520
+ }
1521
+ side = this.safeString(description, 'type', side);
1522
+ type = this.safeString(description, 'ordertype', type);
1523
+ marketId = this.safeString(description, 'pair', marketId);
1524
+ const foundMarket = this.findMarketByAltnameOrId(marketId);
1525
+ let symbol = undefined;
1526
+ if (foundMarket !== undefined) {
1527
+ market = foundMarket;
1528
+ }
1529
+ else if (marketId !== undefined) {
1530
+ // delisted market ids go here
1531
+ market = this.getDelistedMarketById(marketId);
1532
+ }
1533
+ const timestamp = this.safeTimestamp(order, 'opentm');
1534
+ amount = this.safeString(order, 'vol', amount);
1535
+ const filled = this.safeString(order, 'vol_exec');
1536
+ let fee = undefined;
1537
+ // kraken truncates the cost in the api response so we will ignore it and calculate it from average & filled
1538
+ // const cost = this.safeString (order, 'cost');
1539
+ price = this.safeString(description, 'price', price);
1540
+ if ((price === undefined) || Precise["default"].stringEquals(price, '0')) {
1541
+ price = this.safeString(description, 'price2');
1542
+ }
1543
+ if ((price === undefined) || Precise["default"].stringEquals(price, '0')) {
1544
+ price = this.safeString(order, 'price', price);
1545
+ }
1546
+ const flags = this.safeString(order, 'oflags', '');
1547
+ const isPostOnly = flags.indexOf('post') > -1;
1548
+ const average = this.safeNumber(order, 'price');
1549
+ if (market !== undefined) {
1550
+ symbol = market['symbol'];
1551
+ if ('fee' in order) {
1552
+ const feeCost = this.safeString(order, 'fee');
1553
+ fee = {
1554
+ 'cost': feeCost,
1555
+ 'rate': undefined,
1556
+ };
1557
+ if (flags.indexOf('fciq') >= 0) {
1558
+ fee['currency'] = market['quote'];
1559
+ }
1560
+ else if (flags.indexOf('fcib') >= 0) {
1561
+ fee['currency'] = market['base'];
1562
+ }
1563
+ }
1564
+ }
1565
+ const status = this.parseOrderStatus(this.safeString(order, 'status'));
1566
+ let id = this.safeString2(order, 'id', 'txid');
1567
+ if ((id === undefined) || (id.slice(0, 1) === '[')) {
1568
+ const txid = this.safeValue(order, 'txid');
1569
+ id = this.safeString(txid, 0);
1570
+ }
1571
+ const clientOrderId = this.safeString(order, 'userref');
1572
+ const rawTrades = this.safeValue(order, 'trades', []);
1573
+ const trades = [];
1574
+ for (let i = 0; i < rawTrades.length; i++) {
1575
+ const rawTrade = rawTrades[i];
1576
+ if (typeof rawTrade === 'string') {
1577
+ trades.push(this.safeTrade({ 'id': rawTrade, 'orderId': id, 'symbol': symbol, 'info': {} }));
1578
+ }
1579
+ else {
1580
+ trades.push(rawTrade);
1581
+ }
1582
+ }
1583
+ stopPrice = this.safeNumber(order, 'stopprice', stopPrice);
1584
+ return this.safeOrder({
1585
+ 'id': id,
1586
+ 'clientOrderId': clientOrderId,
1587
+ 'info': order,
1588
+ 'timestamp': timestamp,
1589
+ 'datetime': this.iso8601(timestamp),
1590
+ 'lastTradeTimestamp': undefined,
1591
+ 'status': status,
1592
+ 'symbol': symbol,
1593
+ 'type': type,
1594
+ 'timeInForce': undefined,
1595
+ 'postOnly': isPostOnly,
1596
+ 'side': side,
1597
+ 'price': price,
1598
+ 'stopPrice': stopPrice,
1599
+ 'triggerPrice': stopPrice,
1600
+ 'cost': undefined,
1601
+ 'amount': amount,
1602
+ 'filled': filled,
1603
+ 'average': average,
1604
+ 'remaining': undefined,
1605
+ 'fee': fee,
1606
+ 'trades': trades,
1607
+ }, market);
1608
+ }
1609
+ orderRequest(method, symbol, type, request, price = undefined, params = {}) {
1610
+ const clientOrderId = this.safeString2(params, 'userref', 'clientOrderId');
1611
+ params = this.omit(params, ['userref', 'clientOrderId']);
1612
+ if (clientOrderId !== undefined) {
1613
+ request['userref'] = clientOrderId;
1614
+ }
1615
+ const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
1616
+ const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
1617
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
1618
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
1619
+ const isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
1620
+ const trailingAmount = this.safeString(params, 'trailingAmount');
1621
+ const trailingLimitAmount = this.safeString(params, 'trailingLimitAmount');
1622
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1623
+ if ((type === 'limit') && !isTrailingAmountOrder) {
1624
+ request['price'] = this.priceToPrecision(symbol, price);
1625
+ }
1626
+ let reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1627
+ if (isStopLossOrTakeProfitTrigger) {
1628
+ if (isStopLossTriggerOrder) {
1629
+ request['price'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
1630
+ request['ordertype'] = 'stop-loss-limit';
1631
+ }
1632
+ else if (isTakeProfitTriggerOrder) {
1633
+ request['price'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
1634
+ request['ordertype'] = 'take-profit-limit';
1635
+ }
1636
+ request['price2'] = this.priceToPrecision(symbol, price);
1637
+ reduceOnly = true;
1638
+ }
1639
+ else if (isTrailingAmountOrder) {
1640
+ const trailingActivationPriceType = this.safeString(params, 'trigger', 'last');
1641
+ const trailingAmountString = '+' + trailingAmount;
1642
+ request['trigger'] = trailingActivationPriceType;
1643
+ if ((type === 'limit') || (trailingLimitAmount !== undefined)) {
1644
+ const offset = this.safeString(params, 'offset', '-');
1645
+ const trailingLimitAmountString = offset + this.numberToString(trailingLimitAmount);
1646
+ request['price'] = trailingAmountString;
1647
+ request['price2'] = trailingLimitAmountString;
1648
+ request['ordertype'] = 'trailing-stop-limit';
1649
+ }
1650
+ else {
1651
+ request['price'] = trailingAmountString;
1652
+ request['ordertype'] = 'trailing-stop';
1653
+ }
1654
+ }
1655
+ if (reduceOnly) {
1656
+ request['reduce_only'] = 'true'; // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
1657
+ }
1658
+ let close = this.safeValue(params, 'close');
1659
+ if (close !== undefined) {
1660
+ close = this.extend({}, close);
1661
+ const closePrice = this.safeValue(close, 'price');
1662
+ if (closePrice !== undefined) {
1663
+ close['price'] = this.priceToPrecision(symbol, closePrice);
1664
+ }
1665
+ const closePrice2 = this.safeValue(close, 'price2'); // stopPrice
1666
+ if (closePrice2 !== undefined) {
1667
+ close['price2'] = this.priceToPrecision(symbol, closePrice2);
1668
+ }
1669
+ request['close'] = close;
1670
+ }
1671
+ const timeInForce = this.safeString2(params, 'timeInForce', 'timeinforce');
1672
+ if (timeInForce !== undefined) {
1673
+ request['timeinforce'] = timeInForce;
1674
+ }
1675
+ const isMarket = (type === 'market');
1676
+ let postOnly = undefined;
1677
+ [postOnly, params] = this.handlePostOnly(isMarket, false, params);
1678
+ if (postOnly) {
1679
+ request['oflags'] = 'post';
1680
+ }
1681
+ params = this.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset']);
1682
+ return [request, params];
1683
+ }
1684
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1685
+ /**
1686
+ * @method
1687
+ * @name kraken#editOrder
1688
+ * @description edit a trade order
1689
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/editOrder
1690
+ * @param {string} id order id
1691
+ * @param {string} symbol unified symbol of the market to create an order in
1692
+ * @param {string} type 'market' or 'limit'
1693
+ * @param {string} side 'buy' or 'sell'
1694
+ * @param {float} amount how much of the currency you want to trade in units of the base currency
1695
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1696
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1697
+ * @param {float} [params.stopLossPrice] *margin only* the price that a stop loss order is triggered at
1698
+ * @param {float} [params.takeProfitPrice] *margin only* the price that a take profit order is triggered at
1699
+ * @param {string} [params.trailingAmount] *margin only* the quote price away from the current market price
1700
+ * @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount
1701
+ * @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
1702
+ * @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last'
1703
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1704
+ */
1705
+ await this.loadMarkets();
1706
+ const market = this.market(symbol);
1707
+ if (!market['spot']) {
1708
+ throw new errors.NotSupported(this.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted');
1709
+ }
1710
+ const request = {
1711
+ 'txid': id,
1712
+ 'pair': market['id'],
1713
+ };
1714
+ if (amount !== undefined) {
1715
+ request['volume'] = this.amountToPrecision(symbol, amount);
1716
+ }
1717
+ const orderRequest = this.orderRequest('editOrder()', symbol, type, request, price, params);
1718
+ const response = await this.privatePostEditOrder(this.extend(orderRequest[0], orderRequest[1]));
1719
+ //
1720
+ // {
1721
+ // "error": [],
1722
+ // "result": {
1723
+ // "status": "ok",
1724
+ // "txid": "OAW2BO-7RWEK-PZY5UO",
1725
+ // "originaltxid": "OXL6SS-UPNMC-26WBE7",
1726
+ // "volume": "0.00075000",
1727
+ // "price": "13500.0",
1728
+ // "orders_cancelled": 1,
1729
+ // "descr": {
1730
+ // "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
1731
+ // }
1732
+ // }
1733
+ // }
1734
+ //
1735
+ const data = this.safeValue(response, 'result', {});
1736
+ return this.parseOrder(data, market);
1737
+ }
1738
+ async fetchOrder(id, symbol = undefined, params = {}) {
1739
+ /**
1740
+ * @method
1741
+ * @name kraken#fetchOrder
1742
+ * @description fetches information on an order made by the user
1743
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOrdersInfo
1744
+ * @param {string} symbol not used by kraken fetchOrder
1745
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1746
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1747
+ */
1748
+ await this.loadMarkets();
1749
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
1750
+ const request = {
1751
+ 'trades': true, // whether or not to include trades in output (optional, default false)
1752
+ // 'txid': id, // do not comma separate a list of ids - use fetchOrdersByIds instead
1753
+ // 'userref': 'optional', // restrict results to given user reference id (optional)
1754
+ };
1755
+ let query = params;
1756
+ if (clientOrderId !== undefined) {
1757
+ request['userref'] = clientOrderId;
1758
+ query = this.omit(params, ['userref', 'clientOrderId']);
1759
+ }
1760
+ else {
1761
+ request['txid'] = id;
1762
+ }
1763
+ const response = await this.privatePostQueryOrders(this.extend(request, query));
1764
+ //
1765
+ // {
1766
+ // "error":[],
1767
+ // "result":{
1768
+ // "OTLAS3-RRHUF-NDWH5A":{
1769
+ // "refid":null,
1770
+ // "userref":null,
1771
+ // "status":"closed",
1772
+ // "reason":null,
1773
+ // "opentm":1586822919.3342,
1774
+ // "closetm":1586822919.365,
1775
+ // "starttm":0,
1776
+ // "expiretm":0,
1777
+ // "descr":{
1778
+ // "pair":"XBTUSDT",
1779
+ // "type":"sell",
1780
+ // "ordertype":"market",
1781
+ // "price":"0",
1782
+ // "price2":"0",
1783
+ // "leverage":"none",
1784
+ // "order":"sell 0.21804000 XBTUSDT @ market",
1785
+ // "close":""
1786
+ // },
1787
+ // "vol":"0.21804000",
1788
+ // "vol_exec":"0.21804000",
1789
+ // "cost":"1493.9",
1790
+ // "fee":"3.8",
1791
+ // "price":"6851.5",
1792
+ // "stopprice":"0.00000",
1793
+ // "limitprice":"0.00000",
1794
+ // "misc":"",
1795
+ // "oflags":"fciq",
1796
+ // "trades":["TT5UC3-GOIRW-6AZZ6R"]
1797
+ // }
1798
+ // }
1799
+ // }
1800
+ //
1801
+ const result = this.safeValue(response, 'result', []);
1802
+ if (!(id in result)) {
1803
+ throw new errors.OrderNotFound(this.id + ' fetchOrder() could not find order id ' + id);
1804
+ }
1805
+ return this.parseOrder(this.extend({ 'id': id }, result[id]));
1806
+ }
1807
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1808
+ /**
1809
+ * @method
1810
+ * @name kraken#fetchOrderTrades
1811
+ * @description fetch all the trades made from a single order
1812
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradesInfo
1813
+ * @param {string} id order id
1814
+ * @param {string} symbol unified market symbol
1815
+ * @param {int} [since] the earliest time in ms to fetch trades for
1816
+ * @param {int} [limit] the maximum number of trades to retrieve
1817
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1818
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1819
+ */
1820
+ const orderTrades = this.safeValue(params, 'trades');
1821
+ const tradeIds = [];
1822
+ if (orderTrades === undefined) {
1823
+ throw new errors.ArgumentsRequired(this.id + " fetchOrderTrades() requires a unified order structure in the params argument or a 'trades' param (an array of trade id strings)");
1824
+ }
1825
+ else {
1826
+ for (let i = 0; i < orderTrades.length; i++) {
1827
+ const orderTrade = orderTrades[i];
1828
+ if (typeof orderTrade === 'string') {
1829
+ tradeIds.push(orderTrade);
1830
+ }
1831
+ else {
1832
+ tradeIds.push(orderTrade['id']);
1833
+ }
1834
+ }
1835
+ }
1836
+ await this.loadMarkets();
1837
+ if (symbol !== undefined) {
1838
+ symbol = this.symbol(symbol);
1839
+ }
1840
+ const options = this.safeValue(this.options, 'fetchOrderTrades', {});
1841
+ const batchSize = this.safeInteger(options, 'batchSize', 20);
1842
+ const numTradeIds = tradeIds.length;
1843
+ let numBatches = this.parseToInt(numTradeIds / batchSize);
1844
+ numBatches = this.sum(numBatches, 1);
1845
+ let result = [];
1846
+ for (let j = 0; j < numBatches; j++) {
1847
+ const requestIds = [];
1848
+ for (let k = 0; k < batchSize; k++) {
1849
+ const index = this.sum(j * batchSize, k);
1850
+ if (index < numTradeIds) {
1851
+ requestIds.push(tradeIds[index]);
1852
+ }
1853
+ }
1854
+ const request = {
1855
+ 'txid': requestIds.join(','),
1856
+ };
1857
+ const response = await this.privatePostQueryTrades(request);
1858
+ //
1859
+ // {
1860
+ // "error": [],
1861
+ // "result": {
1862
+ // 'TIMIRG-WUNNE-RRJ6GT': {
1863
+ // "ordertxid": 'OQRPN2-LRHFY-HIFA7D',
1864
+ // "postxid": 'TKH2SE-M7IF5-CFI7LT',
1865
+ // "pair": 'USDCUSDT',
1866
+ // "time": 1586340086.457,
1867
+ // "type": 'sell',
1868
+ // "ordertype": 'market',
1869
+ // "price": '0.99860000',
1870
+ // "cost": '22.16892001',
1871
+ // "fee": '0.04433784',
1872
+ // "vol": '22.20000000',
1873
+ // "margin": '0.00000000',
1874
+ // "misc": ''
1875
+ // }
1876
+ // }
1877
+ // }
1878
+ //
1879
+ const rawTrades = this.safeValue(response, 'result');
1880
+ const ids = Object.keys(rawTrades);
1881
+ for (let i = 0; i < ids.length; i++) {
1882
+ rawTrades[ids[i]]['id'] = ids[i];
1883
+ }
1884
+ const trades = this.parseTrades(rawTrades, undefined, since, limit);
1885
+ const tradesFilteredBySymbol = this.filterBySymbol(trades, symbol);
1886
+ result = this.arrayConcat(result, tradesFilteredBySymbol);
1887
+ }
1888
+ return result;
1889
+ }
1890
+ async fetchOrdersByIds(ids, symbol = undefined, params = {}) {
1891
+ /**
1892
+ * @method
1893
+ * @name kraken#fetchOrdersByIds
1894
+ * @description fetch orders by the list of order id
1895
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
1896
+ * @param {string[]|undefined} ids list of order id
1897
+ * @param {object} [params] extra parameters specific to the kraken api endpoint
1898
+ * @returns {object[]} a list of [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1899
+ */
1900
+ await this.loadMarkets();
1901
+ const response = await this.privatePostQueryOrders(this.extend({
1902
+ 'trades': true,
1903
+ 'txid': ids.join(','), // comma delimited list of transaction ids to query info about (20 maximum)
1904
+ }, params));
1905
+ const result = this.safeValue(response, 'result', {});
1906
+ const orders = [];
1907
+ const orderIds = Object.keys(result);
1908
+ for (let i = 0; i < orderIds.length; i++) {
1909
+ const id = orderIds[i];
1910
+ const item = result[id];
1911
+ const order = this.parseOrder(this.extend({ 'id': id }, item));
1912
+ orders.push(order);
1913
+ }
1914
+ return orders;
1915
+ }
1916
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1917
+ /**
1918
+ * @method
1919
+ * @name kraken#fetchMyTrades
1920
+ * @description fetch all trades made by the user
1921
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeHistory
1922
+ * @param {string} symbol unified market symbol
1923
+ * @param {int} [since] the earliest time in ms to fetch trades for
1924
+ * @param {int} [limit] the maximum number of trades structures to retrieve
1925
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1926
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1927
+ */
1928
+ await this.loadMarkets();
1929
+ const request = {
1930
+ // 'type': 'all', // any position, closed position, closing position, no position
1931
+ // 'trades': false, // whether or not to include trades related to position in output
1932
+ // 'start': 1234567890, // starting unix timestamp or trade tx id of results (exclusive)
1933
+ // 'end': 1234567890, // ending unix timestamp or trade tx id of results (inclusive)
1934
+ // 'ofs' = result offset
1935
+ };
1936
+ if (since !== undefined) {
1937
+ request['start'] = this.parseToInt(since / 1000);
1938
+ }
1939
+ const response = await this.privatePostTradesHistory(this.extend(request, params));
1940
+ //
1941
+ // {
1942
+ // "error": [],
1943
+ // "result": {
1944
+ // "trades": {
1945
+ // "GJ3NYQ-XJRTF-THZABF": {
1946
+ // "ordertxid": "TKH2SE-ZIF5E-CFI7LT",
1947
+ // "postxid": "OEN3VX-M7IF5-JNBJAM",
1948
+ // "pair": "XICNXETH",
1949
+ // "time": 1527213229.4491,
1950
+ // "type": "sell",
1951
+ // "ordertype": "limit",
1952
+ // "price": "0.001612",
1953
+ // "cost": "0.025792",
1954
+ // "fee": "0.000026",
1955
+ // "vol": "16.00000000",
1956
+ // "margin": "0.000000",
1957
+ // "misc": ""
1958
+ // },
1959
+ // ...
1960
+ // },
1961
+ // "count": 9760,
1962
+ // },
1963
+ // }
1964
+ //
1965
+ const trades = response['result']['trades'];
1966
+ const ids = Object.keys(trades);
1967
+ for (let i = 0; i < ids.length; i++) {
1968
+ trades[ids[i]]['id'] = ids[i];
1969
+ }
1970
+ let market = undefined;
1971
+ if (symbol !== undefined) {
1972
+ market = this.market(symbol);
1973
+ }
1974
+ return this.parseTrades(trades, market, since, limit);
1975
+ }
1976
+ async cancelOrder(id, symbol = undefined, params = {}) {
1977
+ /**
1978
+ * @method
1979
+ * @name kraken#cancelOrder
1980
+ * @description cancels an open order
1981
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelOrder
1982
+ * @param {string} id order id
1983
+ * @param {string} symbol unified symbol of the market the order was made in
1984
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1985
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1986
+ */
1987
+ await this.loadMarkets();
1988
+ let response = undefined;
1989
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId', id);
1990
+ const request = {
1991
+ 'txid': clientOrderId, // order id or userref
1992
+ };
1993
+ params = this.omit(params, ['userref', 'clientOrderId']);
1994
+ try {
1995
+ response = await this.privatePostCancelOrder(this.extend(request, params));
1996
+ }
1997
+ catch (e) {
1998
+ if (this.last_http_response) {
1999
+ if (this.last_http_response.indexOf('EOrder:Unknown order') >= 0) {
2000
+ throw new errors.OrderNotFound(this.id + ' cancelOrder() error ' + this.last_http_response);
2001
+ }
2002
+ }
2003
+ throw e;
2004
+ }
2005
+ return response;
2006
+ }
2007
+ async cancelOrders(ids, symbol = undefined, params = {}) {
2008
+ /**
2009
+ * @method
2010
+ * @name kraken#cancelOrders
2011
+ * @description cancel multiple orders
2012
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelOrderBatch
2013
+ * @param {string[]} ids open orders transaction ID (txid) or user reference (userref)
2014
+ * @param {string} symbol unified market symbol
2015
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2016
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2017
+ */
2018
+ const request = {
2019
+ 'orders': ids,
2020
+ };
2021
+ const response = await this.privatePostCancelOrderBatch(this.extend(request, params));
2022
+ //
2023
+ // {
2024
+ // "error": [],
2025
+ // "result": {
2026
+ // "count": 2
2027
+ // }
2028
+ // }
2029
+ //
2030
+ return response;
2031
+ }
2032
+ async cancelAllOrders(symbol = undefined, params = {}) {
2033
+ /**
2034
+ * @method
2035
+ * @name kraken#cancelAllOrders
2036
+ * @description cancel all open orders
2037
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelAllOrders
2038
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
2039
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2040
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2041
+ */
2042
+ await this.loadMarkets();
2043
+ return await this.privatePostCancelAll(params);
2044
+ }
2045
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2046
+ /**
2047
+ * @method
2048
+ * @name kraken#fetchOpenOrders
2049
+ * @description fetch all unfilled currently open orders
2050
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenOrders
2051
+ * @param {string} symbol unified market symbol
2052
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2053
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
2054
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2055
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2056
+ */
2057
+ await this.loadMarkets();
2058
+ const request = {};
2059
+ if (since !== undefined) {
2060
+ request['start'] = this.parseToInt(since / 1000);
2061
+ }
2062
+ let query = params;
2063
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
2064
+ if (clientOrderId !== undefined) {
2065
+ request['userref'] = clientOrderId;
2066
+ query = this.omit(params, ['userref', 'clientOrderId']);
2067
+ }
2068
+ const response = await this.privatePostOpenOrders(this.extend(request, query));
2069
+ let market = undefined;
2070
+ if (symbol !== undefined) {
2071
+ market = this.market(symbol);
2072
+ }
2073
+ const result = this.safeValue(response, 'result', {});
2074
+ const orders = this.safeValue(result, 'open', []);
2075
+ return this.parseOrders(orders, market, since, limit);
2076
+ }
2077
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2078
+ /**
2079
+ * @method
2080
+ * @name kraken#fetchClosedOrders
2081
+ * @description fetches information on multiple closed orders made by the user
2082
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
2083
+ * @param {string} symbol unified market symbol of the market orders were made in
2084
+ * @param {int} [since] the earliest time in ms to fetch orders for
2085
+ * @param {int} [limit] the maximum number of order structures to retrieve
2086
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2087
+ * @param {int} [params.until] timestamp in ms of the latest entry
2088
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2089
+ */
2090
+ await this.loadMarkets();
2091
+ let request = {};
2092
+ if (since !== undefined) {
2093
+ request['start'] = this.parseToInt(since / 1000);
2094
+ }
2095
+ let query = params;
2096
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
2097
+ if (clientOrderId !== undefined) {
2098
+ request['userref'] = clientOrderId;
2099
+ query = this.omit(params, ['userref', 'clientOrderId']);
2100
+ }
2101
+ [request, params] = this.handleUntilOption('end', request, params);
2102
+ const response = await this.privatePostClosedOrders(this.extend(request, query));
2103
+ //
2104
+ // {
2105
+ // "error":[],
2106
+ // "result":{
2107
+ // "closed":{
2108
+ // "OETZYO-UL524-QJMXCT":{
2109
+ // "refid":null,
2110
+ // "userref":null,
2111
+ // "status":"canceled",
2112
+ // "reason":"User requested",
2113
+ // "opentm":1601489313.3898,
2114
+ // "closetm":1601489346.5507,
2115
+ // "starttm":0,
2116
+ // "expiretm":0,
2117
+ // "descr":{
2118
+ // "pair":"ETHUSDT",
2119
+ // "type":"buy",
2120
+ // "ordertype":"limit",
2121
+ // "price":"330.00",
2122
+ // "price2":"0",
2123
+ // "leverage":"none",
2124
+ // "order":"buy 0.02100000 ETHUSDT @ limit 330.00",
2125
+ // "close":""
2126
+ // },
2127
+ // "vol":"0.02100000",
2128
+ // "vol_exec":"0.00000000",
2129
+ // "cost":"0.00000",
2130
+ // "fee":"0.00000",
2131
+ // "price":"0.00000",
2132
+ // "stopprice":"0.00000",
2133
+ // "limitprice":"0.00000",
2134
+ // "misc":"",
2135
+ // "oflags":"fciq"
2136
+ // },
2137
+ // },
2138
+ // "count":16
2139
+ // }
2140
+ // }
2141
+ //
2142
+ let market = undefined;
2143
+ if (symbol !== undefined) {
2144
+ market = this.market(symbol);
2145
+ }
2146
+ const result = this.safeValue(response, 'result', {});
2147
+ const orders = this.safeValue(result, 'closed', []);
2148
+ return this.parseOrders(orders, market, since, limit);
2149
+ }
2150
+ parseTransactionStatus(status) {
2151
+ // IFEX transaction states
2152
+ const statuses = {
2153
+ 'Initial': 'pending',
2154
+ 'Pending': 'pending',
2155
+ 'Success': 'ok',
2156
+ 'Settled': 'pending',
2157
+ 'Failure': 'failed',
2158
+ 'Partial': 'ok',
2159
+ };
2160
+ return this.safeString(statuses, status, status);
2161
+ }
2162
+ parseNetwork(network) {
2163
+ const withdrawMethods = this.safeValue(this.options, 'withdrawMethods', {});
2164
+ return this.safeString(withdrawMethods, network, network);
2165
+ }
2166
+ parseTransaction(transaction, currency = undefined) {
2167
+ //
2168
+ // fetchDeposits
2169
+ //
2170
+ // {
2171
+ // "method": "Ether (Hex)",
2172
+ // "aclass": "currency",
2173
+ // "asset": "XETH",
2174
+ // "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
2175
+ // "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
2176
+ // "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
2177
+ // "amount": "7.9999257900",
2178
+ // "fee": "0.0000000000",
2179
+ // "time": 1529223212,
2180
+ // "status": "Success"
2181
+ // }
2182
+ //
2183
+ // there can be an additional 'status-prop' field present
2184
+ // deposit pending review by exchange => 'on-hold'
2185
+ // the deposit is initiated by the exchange => 'return'
2186
+ //
2187
+ // {
2188
+ // "type": 'deposit',
2189
+ // "method": 'Fidor Bank AG (Wire Transfer)',
2190
+ // "aclass": 'currency',
2191
+ // "asset": 'ZEUR',
2192
+ // "refid": 'xxx-xxx-xxx',
2193
+ // "txid": '12341234',
2194
+ // "info": 'BANKCODEXXX',
2195
+ // "amount": '38769.08',
2196
+ // "fee": '0.0000',
2197
+ // "time": 1644306552,
2198
+ // "status": 'Success',
2199
+ // status-prop: 'on-hold'
2200
+ // }
2201
+ //
2202
+ //
2203
+ // fetchWithdrawals
2204
+ //
2205
+ // {
2206
+ // "method": "Ether",
2207
+ // "aclass": "currency",
2208
+ // "asset": "XETH",
2209
+ // "refid": "A2BF34S-O7LBNQ-UE4Y4O",
2210
+ // "txid": "0x288b83c6b0904d8400ef44e1c9e2187b5c8f7ea3d838222d53f701a15b5c274d",
2211
+ // "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
2212
+ // "amount": "9.9950000000",
2213
+ // "fee": "0.0050000000",
2214
+ // "time": 1530481750,
2215
+ // "status": "Success"
2216
+ // "key":"Huobi wallet",
2217
+ // "network":"Tron"
2218
+ // status-prop: 'on-hold' // this field might not be present in some cases
2219
+ // }
2220
+ //
2221
+ // withdraw
2222
+ //
2223
+ // {
2224
+ // "refid": "AGBSO6T-UFMTTQ-I7KGS6"
2225
+ // }
2226
+ //
2227
+ const id = this.safeString(transaction, 'refid');
2228
+ const txid = this.safeString(transaction, 'txid');
2229
+ const timestamp = this.safeTimestamp(transaction, 'time');
2230
+ const currencyId = this.safeString(transaction, 'asset');
2231
+ const code = this.safeCurrencyCode(currencyId, currency);
2232
+ const address = this.safeString(transaction, 'info');
2233
+ const amount = this.safeNumber(transaction, 'amount');
2234
+ let status = this.parseTransactionStatus(this.safeString(transaction, 'status'));
2235
+ const statusProp = this.safeString(transaction, 'status-prop');
2236
+ const isOnHoldDeposit = statusProp === 'on-hold';
2237
+ const isCancellationRequest = statusProp === 'cancel-pending';
2238
+ const isOnHoldWithdrawal = statusProp === 'onhold';
2239
+ if (isOnHoldDeposit || isCancellationRequest || isOnHoldWithdrawal) {
2240
+ status = 'pending';
2241
+ }
2242
+ const type = this.safeString(transaction, 'type'); // injected from the outside
2243
+ let feeCost = this.safeNumber(transaction, 'fee');
2244
+ if (feeCost === undefined) {
2245
+ if (type === 'deposit') {
2246
+ feeCost = 0;
2247
+ }
2248
+ }
2249
+ return {
2250
+ 'info': transaction,
2251
+ 'id': id,
2252
+ 'currency': code,
2253
+ 'amount': amount,
2254
+ 'network': this.parseNetwork(this.safeString(transaction, 'network')),
2255
+ 'address': address,
2256
+ 'addressTo': undefined,
2257
+ 'addressFrom': undefined,
2258
+ 'tag': undefined,
2259
+ 'tagTo': undefined,
2260
+ 'tagFrom': undefined,
2261
+ 'status': status,
2262
+ 'type': type,
2263
+ 'updated': undefined,
2264
+ 'txid': txid,
2265
+ 'timestamp': timestamp,
2266
+ 'datetime': this.iso8601(timestamp),
2267
+ 'comment': undefined,
2268
+ 'internal': undefined,
2269
+ 'fee': {
2270
+ 'currency': code,
2271
+ 'cost': feeCost,
2272
+ },
2273
+ };
2274
+ }
2275
+ parseTransactionsByType(type, transactions, code = undefined, since = undefined, limit = undefined) {
2276
+ const result = [];
2277
+ for (let i = 0; i < transactions.length; i++) {
2278
+ const transaction = this.parseTransaction(this.extend({
2279
+ 'type': type,
2280
+ }, transactions[i]));
2281
+ result.push(transaction);
2282
+ }
2283
+ return this.filterByCurrencySinceLimit(result, code, since, limit);
2284
+ }
2285
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2286
+ /**
2287
+ * @method
2288
+ * @name kraken#fetchDeposits
2289
+ * @description fetch all deposits made to an account
2290
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentDeposits
2291
+ * @param {string} code unified currency code
2292
+ * @param {int} [since] the earliest time in ms to fetch deposits for
2293
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
2294
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2295
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2296
+ */
2297
+ // https://www.kraken.com/en-us/help/api#deposit-status
2298
+ if (code === undefined) {
2299
+ throw new errors.ArgumentsRequired(this.id + ' fetchDeposits() requires a currency code argument');
2300
+ }
2301
+ await this.loadMarkets();
2302
+ const currency = this.currency(code);
2303
+ const request = {
2304
+ 'asset': currency['id'],
2305
+ };
2306
+ if (since !== undefined) {
2307
+ request['start'] = since;
2308
+ }
2309
+ const response = await this.privatePostDepositStatus(this.extend(request, params));
2310
+ //
2311
+ // { error: [],
2312
+ // "result": [ { "method": "Ether (Hex)",
2313
+ // "aclass": "currency",
2314
+ // "asset": "XETH",
2315
+ // "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
2316
+ // "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
2317
+ // "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
2318
+ // "amount": "7.9999257900",
2319
+ // "fee": "0.0000000000",
2320
+ // "time": 1529223212,
2321
+ // "status": "Success" } ] }
2322
+ //
2323
+ return this.parseTransactionsByType('deposit', response['result'], code, since, limit);
2324
+ }
2325
+ async fetchTime(params = {}) {
2326
+ /**
2327
+ * @method
2328
+ * @name kraken#fetchTime
2329
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
2330
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getServerTime
2331
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2332
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
2333
+ */
2334
+ // https://www.kraken.com/en-us/features/api#get-server-time
2335
+ const response = await this.publicGetTime(params);
2336
+ //
2337
+ // {
2338
+ // "error": [],
2339
+ // "result": {
2340
+ // "unixtime": 1591502873,
2341
+ // "rfc1123": "Sun, 7 Jun 20 04:07:53 +0000"
2342
+ // }
2343
+ // }
2344
+ //
2345
+ const result = this.safeValue(response, 'result', {});
2346
+ return this.safeTimestamp(result, 'unixtime');
2347
+ }
2348
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2349
+ /**
2350
+ * @method
2351
+ * @name kraken#fetchWithdrawals
2352
+ * @description fetch all withdrawals made from an account
2353
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentWithdrawals
2354
+ * @param {string} code unified currency code
2355
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
2356
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2357
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2358
+ * @param {object} [params.end] End timestamp, withdrawals created strictly after will be not be included in the response
2359
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times
2360
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2361
+ */
2362
+ await this.loadMarkets();
2363
+ let paginate = false;
2364
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchWithdrawals', 'paginate');
2365
+ if (paginate) {
2366
+ params['cursor'] = true;
2367
+ return await this.fetchPaginatedCallCursor('fetchWithdrawals', code, since, limit, params, 'next_cursor', 'cursor');
2368
+ }
2369
+ const request = {};
2370
+ if (code !== undefined) {
2371
+ const currency = this.currency(code);
2372
+ request['asset'] = currency['id'];
2373
+ }
2374
+ if (since !== undefined) {
2375
+ request['since'] = since.toString();
2376
+ }
2377
+ const response = await this.privatePostWithdrawStatus(this.extend(request, params));
2378
+ //
2379
+ // with no pagination
2380
+ // { error: [],
2381
+ // "result": [ { "method": "Ether",
2382
+ // "aclass": "currency",
2383
+ // "asset": "XETH",
2384
+ // "refid": "A2BF34S-O7LBNQ-UE4Y4O",
2385
+ // "txid": "0x298c83c7b0904d8400ef43e1c9e2287b518f7ea3d838822d53f704a1565c274d",
2386
+ // "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
2387
+ // "amount": "9.9950000000",
2388
+ // "fee": "0.0050000000",
2389
+ // "time": 1530481750,
2390
+ // "status": "Success" } ] }
2391
+ // with pagination
2392
+ // {
2393
+ // "error":[],
2394
+ // "result":{
2395
+ // "withdrawals":[
2396
+ // {
2397
+ // "method":"Tether USD (TRC20)",
2398
+ // "aclass":"currency",
2399
+ // "asset":"USDT",
2400
+ // "refid":"BSNFZU2-MEFN4G-J3NEZV",
2401
+ // "txid":"1c7a642fb7387bbc2c6a2c509fd1ae146937f4cf793b4079a4f0715e3a02615a",
2402
+ // "info":"TQmdxSuC16EhFg8FZWtYgrfFRosoRF7bCp",
2403
+ // "amount":"1996.50000000",
2404
+ // "fee":"2.50000000",
2405
+ // "time":1669126657,
2406
+ // "status":"Success",
2407
+ // "key":"poloniex",
2408
+ // "network":"Tron"
2409
+ // },
2410
+ // ...
2411
+ // ],
2412
+ // "next_cursor":"HgAAAAAAAABGVFRSd3k1LVF4Y0JQY05Gd0xRY0NxenFndHpybkwBAQH2AwEBAAAAAQAAAAAAAAABAAAAAAAZAAAAAAAAAA=="
2413
+ // }
2414
+ // }
2415
+ //
2416
+ let rawWithdrawals = undefined;
2417
+ const result = this.safeValue(response, 'result');
2418
+ if (!Array.isArray(result)) {
2419
+ rawWithdrawals = this.addPaginationCursorToResult(result);
2420
+ }
2421
+ else {
2422
+ rawWithdrawals = result;
2423
+ }
2424
+ return this.parseTransactionsByType('withdrawal', rawWithdrawals, code, since, limit);
2425
+ }
2426
+ addPaginationCursorToResult(result) {
2427
+ const cursor = this.safeString(result, 'next_cursor');
2428
+ const data = this.safeValue(result, 'withdrawals');
2429
+ const dataLength = data.length;
2430
+ if (cursor !== undefined && dataLength > 0) {
2431
+ const last = data[dataLength - 1];
2432
+ last['next_cursor'] = cursor;
2433
+ data[dataLength - 1] = last;
2434
+ }
2435
+ return data;
2436
+ }
2437
+ async createDepositAddress(code, params = {}) {
2438
+ /**
2439
+ * @method
2440
+ * @name kraken#createDepositAddress
2441
+ * @description create a currency deposit address
2442
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
2443
+ * @param {string} code unified currency code of the currency for the deposit address
2444
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2445
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2446
+ */
2447
+ const request = {
2448
+ 'new': 'true',
2449
+ };
2450
+ return await this.fetchDepositAddress(code, this.extend(request, params));
2451
+ }
2452
+ async fetchDepositMethods(code, params = {}) {
2453
+ /**
2454
+ * @method
2455
+ * @name kraken#fetchDepositMethods
2456
+ * @description fetch deposit methods for a currency associated with this account
2457
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositMethods
2458
+ * @param {string} code unified currency code
2459
+ * @param {object} [params] extra parameters specific to the kraken api endpoint
2460
+ * @returns {object} of deposit methods
2461
+ */
2462
+ await this.loadMarkets();
2463
+ const currency = this.currency(code);
2464
+ const request = {
2465
+ 'asset': currency['id'],
2466
+ };
2467
+ const response = await this.privatePostDepositMethods(this.extend(request, params));
2468
+ //
2469
+ // {
2470
+ // "error":[],
2471
+ // "result":[
2472
+ // {"method":"Ether (Hex)","limit":false,"gen-address":true}
2473
+ // ]
2474
+ // }
2475
+ //
2476
+ // {
2477
+ // "error":[],
2478
+ // "result":[
2479
+ // {"method":"Tether USD (ERC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true},
2480
+ // {"method":"Tether USD (TRC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true}
2481
+ // ]
2482
+ // }
2483
+ //
2484
+ // {
2485
+ // "error":[],
2486
+ // "result":[
2487
+ // {"method":"Bitcoin","limit":false,"fee":"0.0000000000","gen-address":true}
2488
+ // ]
2489
+ // }
2490
+ //
2491
+ return this.safeValue(response, 'result');
2492
+ }
2493
+ async fetchDepositAddress(code, params = {}) {
2494
+ /**
2495
+ * @method
2496
+ * @name kraken#fetchDepositAddress
2497
+ * @description fetch the deposit address for a currency associated with this account
2498
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
2499
+ * @param {string} code unified currency code
2500
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2501
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2502
+ */
2503
+ await this.loadMarkets();
2504
+ const currency = this.currency(code);
2505
+ let network = this.safeStringUpper(params, 'network');
2506
+ const networks = this.safeValue(this.options, 'networks', {});
2507
+ network = this.safeString(networks, network, network); // support ETH > ERC20 aliases
2508
+ params = this.omit(params, 'network');
2509
+ if ((code === 'USDT') && (network === 'TRC20')) {
2510
+ code = code + '-' + network;
2511
+ }
2512
+ const defaultDepositMethods = this.safeValue(this.options, 'depositMethods', {});
2513
+ const defaultDepositMethod = this.safeString(defaultDepositMethods, code);
2514
+ let depositMethod = this.safeString(params, 'method', defaultDepositMethod);
2515
+ // if the user has specified an exchange-specific method in params
2516
+ // we pass it as is, otherwise we take the 'network' unified param
2517
+ if (depositMethod === undefined) {
2518
+ const depositMethods = await this.fetchDepositMethods(code);
2519
+ if (network !== undefined) {
2520
+ // find best matching deposit method, or fallback to the first one
2521
+ for (let i = 0; i < depositMethods.length; i++) {
2522
+ const entry = this.safeString(depositMethods[i], 'method');
2523
+ if (entry.indexOf(network) >= 0) {
2524
+ depositMethod = entry;
2525
+ break;
2526
+ }
2527
+ }
2528
+ }
2529
+ // if depositMethod was not specified, fallback to the first available deposit method
2530
+ if (depositMethod === undefined) {
2531
+ const firstDepositMethod = this.safeValue(depositMethods, 0, {});
2532
+ depositMethod = this.safeString(firstDepositMethod, 'method');
2533
+ }
2534
+ }
2535
+ const request = {
2536
+ 'asset': currency['id'],
2537
+ 'method': depositMethod,
2538
+ };
2539
+ const response = await this.privatePostDepositAddresses(this.extend(request, params));
2540
+ //
2541
+ // {
2542
+ // "error":[],
2543
+ // "result":[
2544
+ // {"address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3","expiretm":"0"}
2545
+ // ]
2546
+ // }
2547
+ //
2548
+ const result = this.safeValue(response, 'result', []);
2549
+ const firstResult = this.safeValue(result, 0, {});
2550
+ if (firstResult === undefined) {
2551
+ throw new errors.InvalidAddress(this.id + ' privatePostDepositAddresses() returned no addresses for ' + code);
2552
+ }
2553
+ return this.parseDepositAddress(firstResult, currency);
2554
+ }
2555
+ parseDepositAddress(depositAddress, currency = undefined) {
2556
+ //
2557
+ // {
2558
+ // "address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3",
2559
+ // "expiretm":"0"
2560
+ // }
2561
+ //
2562
+ const address = this.safeString(depositAddress, 'address');
2563
+ const tag = this.safeString(depositAddress, 'tag');
2564
+ currency = this.safeCurrency(undefined, currency);
2565
+ const code = currency['code'];
2566
+ this.checkAddress(address);
2567
+ return {
2568
+ 'currency': code,
2569
+ 'address': address,
2570
+ 'tag': tag,
2571
+ 'network': undefined,
2572
+ 'info': depositAddress,
2573
+ };
2574
+ }
2575
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
2576
+ /**
2577
+ * @method
2578
+ * @name kraken#withdraw
2579
+ * @description make a withdrawal
2580
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/withdrawFunds
2581
+ * @param {string} code unified currency code
2582
+ * @param {float} amount the amount to withdraw
2583
+ * @param {string} address the address to withdraw to
2584
+ * @param {string} tag
2585
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2586
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2587
+ */
2588
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
2589
+ this.checkAddress(address);
2590
+ if ('key' in params) {
2591
+ await this.loadMarkets();
2592
+ const currency = this.currency(code);
2593
+ const request = {
2594
+ 'asset': currency['id'],
2595
+ 'amount': amount,
2596
+ 'address': address,
2597
+ };
2598
+ const response = await this.privatePostWithdraw(this.extend(request, params));
2599
+ //
2600
+ // {
2601
+ // "error": [],
2602
+ // "result": {
2603
+ // "refid": "AGBSO6T-UFMTTQ-I7KGS6"
2604
+ // }
2605
+ // }
2606
+ //
2607
+ const result = this.safeValue(response, 'result', {});
2608
+ return this.parseTransaction(result, currency);
2609
+ }
2610
+ throw new errors.ExchangeError(this.id + " withdraw() requires a 'key' parameter (withdrawal key name, as set up on your account)");
2611
+ }
2612
+ async fetchPositions(symbols = undefined, params = {}) {
2613
+ /**
2614
+ * @method
2615
+ * @name kraken#fetchPositions
2616
+ * @description fetch all open positions
2617
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
2618
+ * @param {string[]|undefined} symbols not used by kraken fetchPositions ()
2619
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2620
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2621
+ */
2622
+ await this.loadMarkets();
2623
+ const request = {
2624
+ // 'txid': 'comma delimited list of transaction ids to restrict output to',
2625
+ // 'docalcs': false, // whether or not to include profit/loss calculations
2626
+ // 'consolidation': 'market', // what to consolidate the positions data around, market will consolidate positions based on market pair
2627
+ };
2628
+ const response = await this.privatePostOpenPositions(this.extend(request, params));
2629
+ //
2630
+ // no consolidation
2631
+ //
2632
+ // {
2633
+ // "error": [],
2634
+ // "result": {
2635
+ // 'TGUFMY-FLESJ-VYIX3J': {
2636
+ // "ordertxid": "O3LRNU-ZKDG5-XNCDFR",
2637
+ // "posstatus": "open",
2638
+ // "pair": "ETHUSDT",
2639
+ // "time": 1611557231.4584,
2640
+ // "type": "buy",
2641
+ // "ordertype": "market",
2642
+ // "cost": "28.49800",
2643
+ // "fee": "0.07979",
2644
+ // "vol": "0.02000000",
2645
+ // "vol_closed": "0.00000000",
2646
+ // "margin": "14.24900",
2647
+ // "terms": "0.0200% per 4 hours",
2648
+ // "rollovertm": "1611571631",
2649
+ // "misc": "",
2650
+ // "oflags": ""
2651
+ // }
2652
+ // }
2653
+ // }
2654
+ //
2655
+ // consolidation by market
2656
+ //
2657
+ // {
2658
+ // "error": [],
2659
+ // "result": [
2660
+ // {
2661
+ // "pair": "ETHUSDT",
2662
+ // "positions": "1",
2663
+ // "type": "buy",
2664
+ // "leverage": "2.00000",
2665
+ // "cost": "28.49800",
2666
+ // "fee": "0.07979",
2667
+ // "vol": "0.02000000",
2668
+ // "vol_closed": "0.00000000",
2669
+ // "margin": "14.24900"
2670
+ // }
2671
+ // ]
2672
+ // }
2673
+ //
2674
+ const result = this.safeValue(response, 'result');
2675
+ // todo unify parsePosition/parsePositions
2676
+ return result;
2677
+ }
2678
+ parseAccount(account) {
2679
+ const accountByType = {
2680
+ 'spot': 'Spot Wallet',
2681
+ 'swap': 'Futures Wallet',
2682
+ 'future': 'Futures Wallet',
2683
+ };
2684
+ return this.safeString(accountByType, account, account);
2685
+ }
2686
+ async transferOut(code, amount, params = {}) {
2687
+ /**
2688
+ * @description transfer from spot wallet to futures wallet
2689
+ * @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
2690
+ * @param {str} code Unified currency code
2691
+ * @param {float} amount Size of the transfer
2692
+ * @param {dict} [params] Exchange specific parameters
2693
+ * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2694
+ */
2695
+ return await this.transfer(code, amount, 'spot', 'swap', params);
2696
+ }
2697
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2698
+ /**
2699
+ * @method
2700
+ * @name kraken#transfer
2701
+ * @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
2702
+ * @description transfers currencies between sub-accounts (only spot->swap direction is supported)
2703
+ * @param {string} code Unified currency code
2704
+ * @param {float} amount Size of the transfer
2705
+ * @param {string} fromAccount 'spot' or 'Spot Wallet'
2706
+ * @param {string} toAccount 'swap' or 'Futures Wallet'
2707
+ * @param {object} [params] Exchange specific parameters
2708
+ * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2709
+ */
2710
+ await this.loadMarkets();
2711
+ const currency = this.currency(code);
2712
+ fromAccount = this.parseAccount(fromAccount);
2713
+ toAccount = this.parseAccount(toAccount);
2714
+ const request = {
2715
+ 'amount': this.currencyToPrecision(code, amount),
2716
+ 'from': fromAccount,
2717
+ 'to': toAccount,
2718
+ 'asset': currency['id'],
2719
+ };
2720
+ if (fromAccount !== 'Spot Wallet') {
2721
+ throw new errors.BadRequest(this.id + ' transfer cannot transfer from ' + fromAccount + ' to ' + toAccount + '. Use krakenfutures instead to transfer from the futures account.');
2722
+ }
2723
+ const response = await this.privatePostWalletTransfer(this.extend(request, params));
2724
+ //
2725
+ // {
2726
+ // "error":[
2727
+ // ],
2728
+ // "result":{
2729
+ // "refid":"BOIUSIF-M7DLMN-UXZ3P5"
2730
+ // }
2731
+ // }
2732
+ //
2733
+ const transfer = this.parseTransfer(response, currency);
2734
+ return this.extend(transfer, {
2735
+ 'amount': amount,
2736
+ 'fromAccount': fromAccount,
2737
+ 'toAccount': toAccount,
2738
+ });
2739
+ }
2740
+ parseTransfer(transfer, currency = undefined) {
2741
+ //
2742
+ // transfer
2743
+ //
2744
+ // {
2745
+ // "error":[
2746
+ // ],
2747
+ // "result":{
2748
+ // "refid":"BOIUSIF-M7DLMN-UXZ3P5"
2749
+ // }
2750
+ // }
2751
+ //
2752
+ const result = this.safeValue(transfer, 'result', {});
2753
+ const refid = this.safeString(result, 'refid');
2754
+ return {
2755
+ 'info': transfer,
2756
+ 'id': refid,
2757
+ 'timestamp': undefined,
2758
+ 'datetime': undefined,
2759
+ 'currency': this.safeString(currency, 'code'),
2760
+ 'amount': undefined,
2761
+ 'fromAccount': undefined,
2762
+ 'toAccount': undefined,
2763
+ 'status': 'sucess',
2764
+ };
2765
+ }
2766
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
2767
+ let url = '/' + this.version + '/' + api + '/' + path;
2768
+ if (api === 'public') {
2769
+ if (Object.keys(params).length) {
2770
+ // urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2771
+ url += '?' + this.urlencodeNested(params);
2772
+ }
2773
+ }
2774
+ else if (api === 'private') {
2775
+ const isCancelOrderBatch = (path === 'CancelOrderBatch');
2776
+ this.checkRequiredCredentials();
2777
+ const nonce = this.nonce().toString();
2778
+ // urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2779
+ if (isCancelOrderBatch) {
2780
+ body = this.json(this.extend({ 'nonce': nonce }, params));
2781
+ }
2782
+ else {
2783
+ body = this.urlencodeNested(this.extend({ 'nonce': nonce }, params));
2784
+ }
2785
+ const auth = this.encode(nonce + body);
2786
+ const hash = this.hash(auth, sha256.sha256, 'binary');
2787
+ const binary = this.encode(url);
2788
+ const binhash = this.binaryConcat(binary, hash);
2789
+ const secret = this.base64ToBinary(this.secret);
2790
+ const signature = this.hmac(binhash, secret, sha512.sha512, 'base64');
2791
+ headers = {
2792
+ 'API-Key': this.apiKey,
2793
+ 'API-Sign': signature,
2794
+ // 'Content-Type': 'application/x-www-form-urlencoded',
2795
+ };
2796
+ if (isCancelOrderBatch) {
2797
+ headers['Content-Type'] = 'application/json';
2798
+ }
2799
+ else {
2800
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
2801
+ }
2802
+ }
2803
+ else {
2804
+ url = '/' + path;
2805
+ }
2806
+ url = this.urls['api'][api] + url;
2807
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
2808
+ }
2809
+ nonce() {
2810
+ return this.milliseconds();
2811
+ }
2812
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2813
+ if (code === 520) {
2814
+ throw new errors.ExchangeNotAvailable(this.id + ' ' + code.toString() + ' ' + reason);
2815
+ }
2816
+ // todo: rewrite this for "broad" exceptions matching
2817
+ if (body.indexOf('Invalid order') >= 0) {
2818
+ throw new errors.InvalidOrder(this.id + ' ' + body);
2819
+ }
2820
+ if (body.indexOf('Invalid nonce') >= 0) {
2821
+ throw new errors.InvalidNonce(this.id + ' ' + body);
2822
+ }
2823
+ if (body.indexOf('Insufficient funds') >= 0) {
2824
+ throw new errors.InsufficientFunds(this.id + ' ' + body);
2825
+ }
2826
+ if (body.indexOf('Cancel pending') >= 0) {
2827
+ throw new errors.CancelPending(this.id + ' ' + body);
2828
+ }
2829
+ if (body.indexOf('Invalid arguments:volume') >= 0) {
2830
+ throw new errors.InvalidOrder(this.id + ' ' + body);
2831
+ }
2832
+ if (body.indexOf('Rate limit exceeded') >= 0) {
2833
+ throw new errors.RateLimitExceeded(this.id + ' ' + body);
2834
+ }
2835
+ if (response === undefined) {
2836
+ return undefined;
2837
+ }
2838
+ if (body[0] === '{') {
2839
+ if (typeof response !== 'string') {
2840
+ if ('error' in response) {
2841
+ const numErrors = response['error'].length;
2842
+ if (numErrors) {
2843
+ const message = this.id + ' ' + body;
2844
+ for (let i = 0; i < response['error'].length; i++) {
2845
+ const error = response['error'][i];
2846
+ this.throwExactlyMatchedException(this.exceptions, error, message);
2847
+ }
2848
+ throw new errors.ExchangeError(message);
2849
+ }
2850
+ }
2851
+ }
2852
+ }
2853
+ return undefined;
2854
+ }
2855
+ }
2856
+
2857
+ module.exports = kraken;