ccxt 4.2.10 → 4.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/README.md +5 -5
  2. package/build.sh +4 -4
  3. package/dist/ccxt.browser.js +695 -282
  4. package/dist/ccxt.browser.min.js +3 -3
  5. package/dist/cjs/_virtual/agent.js +7 -0
  6. package/dist/cjs/_virtual/parse-proxy-response.js +7 -0
  7. package/dist/cjs/_virtual/promisify.js +7 -0
  8. package/dist/cjs/ccxt.js +1 -1
  9. package/dist/cjs/js/ccxt.js +474 -0
  10. package/dist/cjs/js/src/abstract/ace.js +9 -0
  11. package/dist/cjs/js/src/abstract/alpaca.js +9 -0
  12. package/dist/cjs/js/src/abstract/ascendex.js +9 -0
  13. package/dist/cjs/js/src/abstract/bigone.js +9 -0
  14. package/dist/cjs/js/src/abstract/binance.js +9 -0
  15. package/dist/cjs/js/src/abstract/bingx.js +9 -0
  16. package/dist/cjs/js/src/abstract/bit2c.js +9 -0
  17. package/dist/cjs/js/src/abstract/bitbank.js +9 -0
  18. package/dist/cjs/js/src/abstract/bitbns.js +9 -0
  19. package/dist/cjs/js/src/abstract/bitfinex.js +9 -0
  20. package/dist/cjs/js/src/abstract/bitfinex2.js +9 -0
  21. package/dist/cjs/js/src/abstract/bitflyer.js +9 -0
  22. package/dist/cjs/js/src/abstract/bitforex.js +9 -0
  23. package/dist/cjs/js/src/abstract/bitget.js +9 -0
  24. package/dist/cjs/js/src/abstract/bithumb.js +9 -0
  25. package/dist/cjs/js/src/abstract/bitmart.js +9 -0
  26. package/dist/cjs/js/src/abstract/bitmex.js +9 -0
  27. package/dist/cjs/js/src/abstract/bitopro.js +9 -0
  28. package/dist/cjs/js/src/abstract/bitpanda.js +9 -0
  29. package/dist/cjs/js/src/abstract/bitrue.js +9 -0
  30. package/dist/cjs/js/src/abstract/bitso.js +9 -0
  31. package/dist/cjs/js/src/abstract/bitstamp.js +9 -0
  32. package/dist/cjs/js/src/abstract/bitteam.js +9 -0
  33. package/dist/cjs/js/src/abstract/bitvavo.js +9 -0
  34. package/dist/cjs/js/src/abstract/bl3p.js +9 -0
  35. package/dist/cjs/js/src/abstract/blockchaincom.js +9 -0
  36. package/dist/cjs/js/src/abstract/btcalpha.js +9 -0
  37. package/dist/cjs/js/src/abstract/btcbox.js +9 -0
  38. package/dist/cjs/js/src/abstract/btcmarkets.js +9 -0
  39. package/dist/cjs/js/src/abstract/btcturk.js +9 -0
  40. package/dist/cjs/js/src/abstract/bybit.js +9 -0
  41. package/dist/cjs/js/src/abstract/cex.js +9 -0
  42. package/dist/cjs/js/src/abstract/coinbase.js +9 -0
  43. package/dist/cjs/js/src/abstract/coinbasepro.js +9 -0
  44. package/dist/cjs/js/src/abstract/coincheck.js +9 -0
  45. package/dist/cjs/js/src/abstract/coinex.js +9 -0
  46. package/dist/cjs/js/src/abstract/coinlist.js +9 -0
  47. package/dist/cjs/js/src/abstract/coinmate.js +9 -0
  48. package/dist/cjs/js/src/abstract/coinone.js +9 -0
  49. package/dist/cjs/js/src/abstract/coinsph.js +9 -0
  50. package/dist/cjs/js/src/abstract/coinspot.js +9 -0
  51. package/dist/cjs/js/src/abstract/cryptocom.js +9 -0
  52. package/dist/cjs/js/src/abstract/currencycom.js +9 -0
  53. package/dist/cjs/js/src/abstract/delta.js +9 -0
  54. package/dist/cjs/js/src/abstract/deribit.js +9 -0
  55. package/dist/cjs/js/src/abstract/digifinex.js +9 -0
  56. package/dist/cjs/js/src/abstract/exmo.js +9 -0
  57. package/dist/cjs/js/src/abstract/gate.js +9 -0
  58. package/dist/cjs/js/src/abstract/gemini.js +9 -0
  59. package/dist/cjs/js/src/abstract/hitbtc.js +9 -0
  60. package/dist/cjs/js/src/abstract/hollaex.js +9 -0
  61. package/dist/cjs/js/src/abstract/htx.js +9 -0
  62. package/dist/cjs/js/src/abstract/huobijp.js +9 -0
  63. package/dist/cjs/js/src/abstract/idex.js +9 -0
  64. package/dist/cjs/js/src/abstract/independentreserve.js +9 -0
  65. package/dist/cjs/js/src/abstract/indodax.js +9 -0
  66. package/dist/cjs/js/src/abstract/kraken.js +9 -0
  67. package/dist/cjs/js/src/abstract/krakenfutures.js +9 -0
  68. package/dist/cjs/js/src/abstract/kucoin.js +9 -0
  69. package/dist/cjs/js/src/abstract/kucoinfutures.js +9 -0
  70. package/dist/cjs/js/src/abstract/kuna.js +9 -0
  71. package/dist/cjs/js/src/abstract/latoken.js +9 -0
  72. package/dist/cjs/js/src/abstract/lbank.js +9 -0
  73. package/dist/cjs/js/src/abstract/luno.js +9 -0
  74. package/dist/cjs/js/src/abstract/lykke.js +9 -0
  75. package/dist/cjs/js/src/abstract/mercado.js +9 -0
  76. package/dist/cjs/js/src/abstract/mexc.js +9 -0
  77. package/dist/cjs/js/src/abstract/ndax.js +9 -0
  78. package/dist/cjs/js/src/abstract/novadax.js +9 -0
  79. package/dist/cjs/js/src/abstract/oceanex.js +9 -0
  80. package/dist/cjs/js/src/abstract/okcoin.js +9 -0
  81. package/dist/cjs/js/src/abstract/okx.js +9 -0
  82. package/dist/cjs/js/src/abstract/p2b.js +9 -0
  83. package/dist/cjs/js/src/abstract/paymium.js +9 -0
  84. package/dist/cjs/js/src/abstract/phemex.js +9 -0
  85. package/dist/cjs/js/src/abstract/poloniex.js +9 -0
  86. package/dist/cjs/js/src/abstract/poloniexfutures.js +9 -0
  87. package/dist/cjs/js/src/abstract/probit.js +9 -0
  88. package/dist/cjs/js/src/abstract/timex.js +9 -0
  89. package/dist/cjs/js/src/abstract/tokocrypto.js +9 -0
  90. package/dist/cjs/js/src/abstract/upbit.js +9 -0
  91. package/dist/cjs/js/src/abstract/wavesexchange.js +9 -0
  92. package/dist/cjs/js/src/abstract/wazirx.js +9 -0
  93. package/dist/cjs/js/src/abstract/whitebit.js +9 -0
  94. package/dist/cjs/js/src/abstract/woo.js +9 -0
  95. package/dist/cjs/js/src/abstract/yobit.js +9 -0
  96. package/dist/cjs/js/src/abstract/zaif.js +9 -0
  97. package/dist/cjs/js/src/abstract/zonda.js +9 -0
  98. package/dist/cjs/js/src/ace.js +1058 -0
  99. package/dist/cjs/js/src/alpaca.js +1125 -0
  100. package/dist/cjs/js/src/ascendex.js +3360 -0
  101. package/dist/cjs/js/src/base/Exchange.js +5110 -0
  102. package/dist/cjs/js/src/base/Precise.js +263 -0
  103. package/dist/cjs/js/src/base/errors.js +299 -0
  104. package/dist/cjs/js/src/base/functions/crypto.js +78 -0
  105. package/dist/cjs/js/src/base/functions/encode.js +44 -0
  106. package/dist/cjs/js/src/base/functions/generic.js +193 -0
  107. package/dist/cjs/js/src/base/functions/misc.js +96 -0
  108. package/dist/cjs/js/src/base/functions/number.js +297 -0
  109. package/dist/cjs/js/src/base/functions/platform.js +28 -0
  110. package/dist/cjs/js/src/base/functions/rsa.js +34 -0
  111. package/dist/cjs/js/src/base/functions/string.js +48 -0
  112. package/dist/cjs/js/src/base/functions/throttle.js +66 -0
  113. package/dist/cjs/js/src/base/functions/time.js +187 -0
  114. package/dist/cjs/js/src/base/functions/totp.js +24 -0
  115. package/dist/cjs/js/src/base/functions/type.js +162 -0
  116. package/dist/cjs/js/src/base/functions.js +157 -0
  117. package/dist/cjs/js/src/base/ws/Cache.js +254 -0
  118. package/dist/cjs/js/src/base/ws/Client.js +299 -0
  119. package/dist/cjs/js/src/base/ws/Future.js +34 -0
  120. package/dist/cjs/js/src/base/ws/OrderBook.js +107 -0
  121. package/dist/cjs/js/src/base/ws/OrderBookSide.js +281 -0
  122. package/dist/cjs/js/src/base/ws/WsClient.js +69 -0
  123. package/dist/cjs/js/src/bequant.js +33 -0
  124. package/dist/cjs/js/src/bigone.js +2142 -0
  125. package/dist/cjs/js/src/binance.js +9729 -0
  126. package/dist/cjs/js/src/binancecoinm.js +45 -0
  127. package/dist/cjs/js/src/binanceus.js +84 -0
  128. package/dist/cjs/js/src/binanceusdm.js +58 -0
  129. package/dist/cjs/js/src/bingx.js +3737 -0
  130. package/dist/cjs/js/src/bit2c.js +916 -0
  131. package/dist/cjs/js/src/bitbank.js +1000 -0
  132. package/dist/cjs/js/src/bitbay.js +17 -0
  133. package/dist/cjs/js/src/bitbns.js +1220 -0
  134. package/dist/cjs/js/src/bitcoincom.js +17 -0
  135. package/dist/cjs/js/src/bitfinex.js +1670 -0
  136. package/dist/cjs/js/src/bitfinex2.js +2990 -0
  137. package/dist/cjs/js/src/bitflyer.js +1045 -0
  138. package/dist/cjs/js/src/bitforex.js +852 -0
  139. package/dist/cjs/js/src/bitget.js +8284 -0
  140. package/dist/cjs/js/src/bithumb.js +1090 -0
  141. package/dist/cjs/js/src/bitmart.js +4454 -0
  142. package/dist/cjs/js/src/bitmex.js +2884 -0
  143. package/dist/cjs/js/src/bitopro.js +1724 -0
  144. package/dist/cjs/js/src/bitpanda.js +2002 -0
  145. package/dist/cjs/js/src/bitrue.js +3253 -0
  146. package/dist/cjs/js/src/bitso.js +1753 -0
  147. package/dist/cjs/js/src/bitstamp.js +2188 -0
  148. package/dist/cjs/js/src/bitteam.js +2309 -0
  149. package/dist/cjs/js/src/bitvavo.js +1968 -0
  150. package/dist/cjs/js/src/bl3p.js +447 -0
  151. package/dist/cjs/js/src/blockchaincom.js +1160 -0
  152. package/dist/cjs/js/src/btcalpha.js +929 -0
  153. package/dist/cjs/js/src/btcbox.js +565 -0
  154. package/dist/cjs/js/src/btcmarkets.js +1237 -0
  155. package/dist/cjs/js/src/btcturk.js +929 -0
  156. package/dist/cjs/js/src/bybit.js +7646 -0
  157. package/dist/cjs/js/src/cex.js +1693 -0
  158. package/dist/cjs/js/src/coinbase.js +3274 -0
  159. package/dist/cjs/js/src/coinbasepro.js +1866 -0
  160. package/dist/cjs/js/src/coincheck.js +843 -0
  161. package/dist/cjs/js/src/coinex.js +5414 -0
  162. package/dist/cjs/js/src/coinlist.js +2329 -0
  163. package/dist/cjs/js/src/coinmate.js +989 -0
  164. package/dist/cjs/js/src/coinone.js +1185 -0
  165. package/dist/cjs/js/src/coinsph.js +1933 -0
  166. package/dist/cjs/js/src/coinspot.js +548 -0
  167. package/dist/cjs/js/src/cryptocom.js +3007 -0
  168. package/dist/cjs/js/src/currencycom.js +2015 -0
  169. package/dist/cjs/js/src/delta.js +3256 -0
  170. package/dist/cjs/js/src/deribit.js +3306 -0
  171. package/dist/cjs/js/src/digifinex.js +4307 -0
  172. package/dist/cjs/js/src/exmo.js +2645 -0
  173. package/dist/cjs/js/src/fmfwio.js +34 -0
  174. package/dist/cjs/js/src/gate.js +7054 -0
  175. package/dist/cjs/js/src/gateio.js +16 -0
  176. package/dist/cjs/js/src/gemini.js +1801 -0
  177. package/dist/cjs/js/src/hitbtc.js +3660 -0
  178. package/dist/cjs/js/src/hitbtc3.js +19 -0
  179. package/dist/cjs/js/src/hollaex.js +1882 -0
  180. package/dist/cjs/js/src/htx.js +9024 -0
  181. package/dist/cjs/js/src/huobi.js +16 -0
  182. package/dist/cjs/js/src/huobijp.js +1918 -0
  183. package/dist/cjs/js/src/idex.js +1770 -0
  184. package/dist/cjs/js/src/independentreserve.js +759 -0
  185. package/dist/cjs/js/src/indodax.js +1069 -0
  186. package/dist/cjs/js/src/kraken.js +2861 -0
  187. package/dist/cjs/js/src/krakenfutures.js +2407 -0
  188. package/dist/cjs/js/src/kucoin.js +4489 -0
  189. package/dist/cjs/js/src/kucoinfutures.js +2475 -0
  190. package/dist/cjs/js/src/kuna.js +1949 -0
  191. package/dist/cjs/js/src/latoken.js +1729 -0
  192. package/dist/cjs/js/src/lbank.js +2825 -0
  193. package/dist/cjs/js/src/luno.js +1044 -0
  194. package/dist/cjs/js/src/lykke.js +1303 -0
  195. package/dist/cjs/js/src/mercado.js +897 -0
  196. package/dist/cjs/js/src/mexc.js +5407 -0
  197. package/dist/cjs/js/src/ndax.js +2450 -0
  198. package/dist/cjs/js/src/novadax.js +1556 -0
  199. package/dist/cjs/js/src/oceanex.js +964 -0
  200. package/dist/cjs/js/src/okcoin.js +3115 -0
  201. package/dist/cjs/js/src/okx.js +7329 -0
  202. package/dist/cjs/js/src/p2b.js +1243 -0
  203. package/dist/cjs/js/src/paymium.js +597 -0
  204. package/dist/cjs/js/src/phemex.js +4715 -0
  205. package/dist/cjs/js/src/poloniex.js +2356 -0
  206. package/dist/cjs/js/src/poloniexfutures.js +1794 -0
  207. package/dist/cjs/js/src/pro/alpaca.js +714 -0
  208. package/dist/cjs/js/src/pro/ascendex.js +957 -0
  209. package/dist/cjs/js/src/pro/bequant.js +33 -0
  210. package/dist/cjs/js/src/pro/binance.js +2796 -0
  211. package/dist/cjs/js/src/pro/binancecoinm.js +23 -0
  212. package/dist/cjs/js/src/pro/binanceus.js +51 -0
  213. package/dist/cjs/js/src/pro/binanceusdm.js +32 -0
  214. package/dist/cjs/js/src/pro/bingx.js +944 -0
  215. package/dist/cjs/js/src/pro/bitcoincom.js +29 -0
  216. package/dist/cjs/js/src/pro/bitfinex.js +672 -0
  217. package/dist/cjs/js/src/pro/bitfinex2.js +1159 -0
  218. package/dist/cjs/js/src/pro/bitget.js +1733 -0
  219. package/dist/cjs/js/src/pro/bitmart.js +1486 -0
  220. package/dist/cjs/js/src/pro/bitmex.js +1576 -0
  221. package/dist/cjs/js/src/pro/bitopro.js +327 -0
  222. package/dist/cjs/js/src/pro/bitpanda.js +1341 -0
  223. package/dist/cjs/js/src/pro/bitrue.js +462 -0
  224. package/dist/cjs/js/src/pro/bitstamp.js +547 -0
  225. package/dist/cjs/js/src/pro/bitvavo.js +704 -0
  226. package/dist/cjs/js/src/pro/blockchaincom.js +794 -0
  227. package/dist/cjs/js/src/pro/bybit.js +1843 -0
  228. package/dist/cjs/js/src/pro/cex.js +1510 -0
  229. package/dist/cjs/js/src/pro/coinbase.js +561 -0
  230. package/dist/cjs/js/src/pro/coinbasepro.js +968 -0
  231. package/dist/cjs/js/src/pro/coinex.js +1095 -0
  232. package/dist/cjs/js/src/pro/cryptocom.js +1020 -0
  233. package/dist/cjs/js/src/pro/currencycom.js +563 -0
  234. package/dist/cjs/js/src/pro/deribit.js +825 -0
  235. package/dist/cjs/js/src/pro/exmo.js +658 -0
  236. package/dist/cjs/js/src/pro/gate.js +1316 -0
  237. package/dist/cjs/js/src/pro/gateio.js +16 -0
  238. package/dist/cjs/js/src/pro/gemini.js +649 -0
  239. package/dist/cjs/js/src/pro/hitbtc.js +1293 -0
  240. package/dist/cjs/js/src/pro/hollaex.js +597 -0
  241. package/dist/cjs/js/src/pro/htx.js +2383 -0
  242. package/dist/cjs/js/src/pro/huobi.js +16 -0
  243. package/dist/cjs/js/src/pro/huobijp.js +606 -0
  244. package/dist/cjs/js/src/pro/idex.js +714 -0
  245. package/dist/cjs/js/src/pro/independentreserve.js +280 -0
  246. package/dist/cjs/js/src/pro/kraken.js +1364 -0
  247. package/dist/cjs/js/src/pro/krakenfutures.js +1500 -0
  248. package/dist/cjs/js/src/pro/kucoin.js +1052 -0
  249. package/dist/cjs/js/src/pro/kucoinfutures.js +981 -0
  250. package/dist/cjs/js/src/pro/luno.js +322 -0
  251. package/dist/cjs/js/src/pro/mexc.js +1170 -0
  252. package/dist/cjs/js/src/pro/ndax.js +545 -0
  253. package/dist/cjs/js/src/pro/okcoin.js +760 -0
  254. package/dist/cjs/js/src/pro/okx.js +1558 -0
  255. package/dist/cjs/js/src/pro/phemex.js +1511 -0
  256. package/dist/cjs/js/src/pro/poloniex.js +1253 -0
  257. package/dist/cjs/js/src/pro/poloniexfutures.js +1014 -0
  258. package/dist/cjs/js/src/pro/probit.js +586 -0
  259. package/dist/cjs/js/src/pro/upbit.js +234 -0
  260. package/dist/cjs/js/src/pro/wazirx.js +776 -0
  261. package/dist/cjs/js/src/pro/whitebit.js +927 -0
  262. package/dist/cjs/js/src/pro/woo.js +769 -0
  263. package/dist/cjs/js/src/probit.js +1865 -0
  264. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +401 -0
  265. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +195 -0
  266. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +308 -0
  267. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +554 -0
  268. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +94 -0
  269. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +70 -0
  270. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +91 -0
  271. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +16 -0
  272. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +1760 -0
  273. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +52 -0
  274. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +81 -0
  275. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +376 -0
  276. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +70 -0
  277. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +1580 -0
  278. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +74 -0
  279. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +24 -0
  280. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +158 -0
  281. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +429 -0
  282. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +176 -0
  283. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +324 -0
  284. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +163 -0
  285. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +245 -0
  286. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +1018 -0
  287. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +383 -0
  288. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +258 -0
  289. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +53 -0
  290. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +120 -0
  291. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +69 -0
  292. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +7 -0
  293. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +83 -0
  294. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +240 -0
  295. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +91 -0
  296. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +130 -0
  297. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +214 -0
  298. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +239 -0
  299. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +93 -0
  300. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +354 -0
  301. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +16 -0
  302. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +20 -0
  303. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +30 -0
  304. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +239 -0
  305. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +372 -0
  306. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +273 -0
  307. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +139 -0
  308. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +14 -0
  309. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +16 -0
  310. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +81 -0
  311. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +292 -0
  312. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +103 -0
  313. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +140 -0
  314. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +175 -0
  315. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +95 -0
  316. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +7 -0
  317. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +383 -0
  318. package/dist/cjs/js/src/timex.js +1562 -0
  319. package/dist/cjs/js/src/tokocrypto.js +2542 -0
  320. package/dist/cjs/js/src/upbit.js +1844 -0
  321. package/dist/cjs/js/src/wavesexchange.js +2607 -0
  322. package/dist/cjs/js/src/wazirx.js +953 -0
  323. package/dist/cjs/js/src/whitebit.js +2309 -0
  324. package/dist/cjs/js/src/woo.js +2715 -0
  325. package/dist/cjs/js/src/yobit.js +1314 -0
  326. package/dist/cjs/js/src/zaif.js +736 -0
  327. package/dist/cjs/js/src/zonda.js +1883 -0
  328. package/dist/cjs/src/base/Exchange.js +11 -0
  329. package/dist/cjs/src/bingx.js +0 -10
  330. package/dist/cjs/src/bitget.js +14 -5
  331. package/dist/cjs/src/bybit.js +1 -1
  332. package/dist/cjs/src/kucoin.js +29 -5
  333. package/js/ccxt.d.ts +1 -1
  334. package/js/ccxt.js +1 -1
  335. package/js/src/abstract/bigone.d.ts +18 -0
  336. package/js/src/abstract/binance.d.ts +2 -0
  337. package/js/src/abstract/binancecoinm.d.ts +2 -0
  338. package/js/src/abstract/binanceus.d.ts +2 -0
  339. package/js/src/abstract/binanceusdm.d.ts +2 -0
  340. package/js/src/abstract/bybit.d.ts +1 -0
  341. package/js/src/abstract/gate.d.ts +11 -0
  342. package/js/src/abstract/gateio.d.ts +11 -0
  343. package/js/src/alpaca.js +18 -18
  344. package/js/src/base/Exchange.d.ts +6 -1
  345. package/js/src/base/Exchange.js +112 -12
  346. package/js/src/bigone.d.ts +1 -2
  347. package/js/src/bigone.js +340 -145
  348. package/js/src/binance.js +15 -8
  349. package/js/src/bingx.d.ts +0 -1
  350. package/js/src/bingx.js +9 -12
  351. package/js/src/bitfinex.d.ts +2 -2
  352. package/js/src/bitfinex.js +2 -3
  353. package/js/src/bitget.js +35 -13
  354. package/js/src/bitmart.d.ts +2 -2
  355. package/js/src/bitmart.js +3 -3
  356. package/js/src/bitmex.js +1 -0
  357. package/js/src/bybit.js +3 -1
  358. package/js/src/coinlist.js +2 -3
  359. package/js/src/coinsph.js +2 -3
  360. package/js/src/deribit.js +1 -0
  361. package/js/src/gate.d.ts +4 -4
  362. package/js/src/gate.js +22 -3
  363. package/js/src/hitbtc.d.ts +4 -4
  364. package/js/src/hitbtc.js +2 -3
  365. package/js/src/htx.js +4 -7
  366. package/js/src/huobijp.js +2 -3
  367. package/js/src/kraken.js +1 -0
  368. package/js/src/kucoin.js +29 -5
  369. package/js/src/mexc.js +2 -1
  370. package/js/src/okx.js +13 -3
  371. package/js/src/pro/binance.d.ts +2 -23
  372. package/js/src/pro/binance.js +58 -22
  373. package/js/src/pro/coinbase.d.ts +2 -2
  374. package/js/src/pro/coinbase.js +4 -1
  375. package/js/src/pro/coinbasepro.d.ts +2 -2
  376. package/js/src/pro/hitbtc.d.ts +2 -2
  377. package/js/src/pro/poloniex.d.ts +2 -2
  378. package/js/src/upbit.d.ts +3 -101
  379. package/js/src/upbit.js +12 -12
  380. package/js/src/woo.js +2 -0
  381. package/package.json +11 -11
  382. package/skip-tests.json +5 -0
  383. package/tests-manager.sh +2 -2
@@ -0,0 +1,2861 @@
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
+ 'createTrailingAmountOrder': true,
42
+ 'createStopOrder': 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
+ // https://github.com/ccxt/ccxt/issues/5698
1268
+ if (limit !== undefined && limit !== 1000) {
1269
+ const fetchTradesWarning = this.safeValue(this.options, 'fetchTradesWarning', true);
1270
+ if (fetchTradesWarning) {
1271
+ throw new errors.ExchangeError(this.id + ' fetchTrades() cannot serve ' + limit.toString() + " trades without breaking the pagination, see https://github.com/ccxt/ccxt/issues/5698 for more details. Set exchange.options['fetchTradesWarning'] to acknowledge this warning and silence it.");
1272
+ }
1273
+ }
1274
+ const response = await this.publicGetTrades(this.extend(request, params));
1275
+ //
1276
+ // {
1277
+ // "error": [],
1278
+ // "result": {
1279
+ // "XETHXXBT": [
1280
+ // ["0.032310","4.28169434",1541390792.763,"s","l",""]
1281
+ // ],
1282
+ // "last": "1541439421200678657"
1283
+ // }
1284
+ // }
1285
+ //
1286
+ const result = response['result'];
1287
+ const trades = result[id];
1288
+ // trades is a sorted array: last (most recent trade) goes last
1289
+ const length = trades.length;
1290
+ if (length <= 0) {
1291
+ return [];
1292
+ }
1293
+ const lastTrade = trades[length - 1];
1294
+ const lastTradeId = this.safeString(result, 'last');
1295
+ lastTrade.push(lastTradeId);
1296
+ return this.parseTrades(trades, market, since, limit);
1297
+ }
1298
+ parseBalance(response) {
1299
+ const balances = this.safeValue(response, 'result', {});
1300
+ const result = {
1301
+ 'info': response,
1302
+ 'timestamp': undefined,
1303
+ 'datetime': undefined,
1304
+ };
1305
+ const currencyIds = Object.keys(balances);
1306
+ for (let i = 0; i < currencyIds.length; i++) {
1307
+ const currencyId = currencyIds[i];
1308
+ const code = this.safeCurrencyCode(currencyId);
1309
+ const balance = this.safeValue(balances, currencyId, {});
1310
+ const account = this.account();
1311
+ account['used'] = this.safeString(balance, 'hold_trade');
1312
+ account['total'] = this.safeString(balance, 'balance');
1313
+ result[code] = account;
1314
+ }
1315
+ return this.safeBalance(result);
1316
+ }
1317
+ async fetchBalance(params = {}) {
1318
+ /**
1319
+ * @method
1320
+ * @name kraken#fetchBalance
1321
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1322
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getExtendedBalance
1323
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1324
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1325
+ */
1326
+ await this.loadMarkets();
1327
+ const response = await this.privatePostBalanceEx(params);
1328
+ //
1329
+ // {
1330
+ // "error": [],
1331
+ // "result": {
1332
+ // "ZUSD": {
1333
+ // "balance": 25435.21,
1334
+ // "hold_trade": 8249.76
1335
+ // },
1336
+ // "XXBT": {
1337
+ // "balance": 1.2435,
1338
+ // "hold_trade": 0.8423
1339
+ // }
1340
+ // }
1341
+ // }
1342
+ //
1343
+ return this.parseBalance(response);
1344
+ }
1345
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1346
+ /**
1347
+ * @method
1348
+ * @name kraken#createOrder
1349
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/addOrder
1350
+ * @description create a trade order
1351
+ * @param {string} symbol unified symbol of the market to create an order in
1352
+ * @param {string} type 'market' or 'limit'
1353
+ * @param {string} side 'buy' or 'sell'
1354
+ * @param {float} amount how much of currency you want to trade in units of base currency
1355
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1356
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1357
+ * @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
1358
+ * @param {bool} [params.reduceOnly] *margin only* indicates if this order is to reduce the size of a position
1359
+ * @param {float} [params.stopLossPrice] *margin only* the price that a stop loss order is triggered at
1360
+ * @param {float} [params.takeProfitPrice] *margin only* the price that a take profit order is triggered at
1361
+ * @param {string} [params.trailingAmount] *margin only* the quote amount to trail away from the current market price
1362
+ * @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount
1363
+ * @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
1364
+ * @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last'
1365
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1366
+ */
1367
+ await this.loadMarkets();
1368
+ const market = this.market(symbol);
1369
+ const request = {
1370
+ 'pair': market['id'],
1371
+ 'type': side,
1372
+ 'ordertype': type,
1373
+ 'volume': this.amountToPrecision(symbol, amount),
1374
+ };
1375
+ const orderRequest = this.orderRequest('createOrder()', symbol, type, request, price, params);
1376
+ const response = await this.privatePostAddOrder(this.extend(orderRequest[0], orderRequest[1]));
1377
+ //
1378
+ // {
1379
+ // "error": [],
1380
+ // "result": {
1381
+ // "descr": { order: 'buy 0.02100000 ETHUSDT @ limit 330.00' },
1382
+ // "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
1383
+ // }
1384
+ // }
1385
+ //
1386
+ const result = this.safeValue(response, 'result');
1387
+ return this.parseOrder(result);
1388
+ }
1389
+ findMarketByAltnameOrId(id) {
1390
+ const marketsByAltname = this.safeValue(this.options, 'marketsByAltname', {});
1391
+ if (id in marketsByAltname) {
1392
+ return marketsByAltname[id];
1393
+ }
1394
+ else {
1395
+ return this.safeMarket(id);
1396
+ }
1397
+ }
1398
+ getDelistedMarketById(id) {
1399
+ if (id === undefined) {
1400
+ return id;
1401
+ }
1402
+ let market = this.safeValue(this.options['delistedMarketsById'], id);
1403
+ if (market !== undefined) {
1404
+ return market;
1405
+ }
1406
+ const baseIdStart = 0;
1407
+ let baseIdEnd = 3;
1408
+ let quoteIdStart = 3;
1409
+ let quoteIdEnd = 6;
1410
+ if (id.length === 8) {
1411
+ baseIdEnd = 4;
1412
+ quoteIdStart = 4;
1413
+ quoteIdEnd = 8;
1414
+ }
1415
+ else if (id.length === 7) {
1416
+ baseIdEnd = 4;
1417
+ quoteIdStart = 4;
1418
+ quoteIdEnd = 7;
1419
+ }
1420
+ const baseId = id.slice(baseIdStart, baseIdEnd);
1421
+ const quoteId = id.slice(quoteIdStart, quoteIdEnd);
1422
+ const base = this.safeCurrencyCode(baseId);
1423
+ const quote = this.safeCurrencyCode(quoteId);
1424
+ const symbol = base + '/' + quote;
1425
+ market = {
1426
+ 'symbol': symbol,
1427
+ 'base': base,
1428
+ 'quote': quote,
1429
+ 'baseId': baseId,
1430
+ 'quoteId': quoteId,
1431
+ };
1432
+ this.options['delistedMarketsById'][id] = market;
1433
+ return market;
1434
+ }
1435
+ parseOrderStatus(status) {
1436
+ const statuses = {
1437
+ 'pending': 'open',
1438
+ 'open': 'open',
1439
+ 'closed': 'closed',
1440
+ 'canceled': 'canceled',
1441
+ 'expired': 'expired',
1442
+ };
1443
+ return this.safeString(statuses, status, status);
1444
+ }
1445
+ parseOrder(order, market = undefined) {
1446
+ //
1447
+ // createOrder for regular orders
1448
+ //
1449
+ // {
1450
+ // "descr": { order: 'buy 0.02100000 ETHUSDT @ limit 330.00' },
1451
+ // "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
1452
+ // }
1453
+ // {
1454
+ // "txid": [ "TX_ID_HERE" ],
1455
+ // "descr": { "order":"buy 0.12345678 ETHEUR @ market" },
1456
+ // }
1457
+ //
1458
+ //
1459
+ // createOrder for stop orders
1460
+ //
1461
+ // {
1462
+ // "txid":["OSILNC-VQI5Q-775ZDQ"],
1463
+ // "descr":{"order":"sell 167.28002676 ADAXBT @ stop loss 0.00003280 -> limit 0.00003212"}
1464
+ // }
1465
+ //
1466
+ //
1467
+ // {
1468
+ // "txid":["OVHMJV-BZW2V-6NZFWF"],
1469
+ // "descr":{"order":"sell 0.00100000 ETHUSD @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"}
1470
+ // }
1471
+ //
1472
+ // editOrder
1473
+ //
1474
+ // {
1475
+ // "status": "ok",
1476
+ // "txid": "OAW2BO-7RWEK-PZY5UO",
1477
+ // "originaltxid": "OXL6SS-UPNMC-26WBE7",
1478
+ // "volume": "0.00075000",
1479
+ // "price": "13500.0",
1480
+ // "orders_cancelled": 1,
1481
+ // "descr": {
1482
+ // "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
1483
+ // }
1484
+ // }
1485
+ // ws - createOrder
1486
+ // {
1487
+ // "descr": 'sell 0.00010000 XBTUSDT @ market',
1488
+ // "event": 'addOrderStatus',
1489
+ // "reqid": 1,
1490
+ // "status": 'ok',
1491
+ // "txid": 'OAVXZH-XIE54-JCYYDG'
1492
+ // }
1493
+ // ws - editOrder
1494
+ // {
1495
+ // "descr": "order edited price = 9000.00000000",
1496
+ // "event": "editOrderStatus",
1497
+ // "originaltxid": "O65KZW-J4AW3-VFS74A",
1498
+ // "reqid": 3,
1499
+ // "status": "ok",
1500
+ // "txid": "OTI672-HJFAO-XOIPPK"
1501
+ // }
1502
+ //
1503
+ const description = this.safeValue(order, 'descr', {});
1504
+ const orderDescription = this.safeString(description, 'order', description);
1505
+ let side = undefined;
1506
+ let type = undefined;
1507
+ let marketId = undefined;
1508
+ let price = undefined;
1509
+ let amount = undefined;
1510
+ let stopPrice = undefined;
1511
+ if (orderDescription !== undefined) {
1512
+ const parts = orderDescription.split(' ');
1513
+ side = this.safeString(parts, 0);
1514
+ amount = this.safeString(parts, 1);
1515
+ marketId = this.safeString(parts, 2);
1516
+ type = this.safeString(parts, 4);
1517
+ if (type === 'stop') {
1518
+ stopPrice = this.safeString(parts, 6);
1519
+ price = this.safeString(parts, 9);
1520
+ }
1521
+ else if (type === 'limit') {
1522
+ price = this.safeString(parts, 5);
1523
+ }
1524
+ }
1525
+ side = this.safeString(description, 'type', side);
1526
+ type = this.safeString(description, 'ordertype', type);
1527
+ marketId = this.safeString(description, 'pair', marketId);
1528
+ const foundMarket = this.findMarketByAltnameOrId(marketId);
1529
+ let symbol = undefined;
1530
+ if (foundMarket !== undefined) {
1531
+ market = foundMarket;
1532
+ }
1533
+ else if (marketId !== undefined) {
1534
+ // delisted market ids go here
1535
+ market = this.getDelistedMarketById(marketId);
1536
+ }
1537
+ const timestamp = this.safeTimestamp(order, 'opentm');
1538
+ amount = this.safeString(order, 'vol', amount);
1539
+ const filled = this.safeString(order, 'vol_exec');
1540
+ let fee = undefined;
1541
+ // kraken truncates the cost in the api response so we will ignore it and calculate it from average & filled
1542
+ // const cost = this.safeString (order, 'cost');
1543
+ price = this.safeString(description, 'price', price);
1544
+ if ((price === undefined) || Precise["default"].stringEquals(price, '0')) {
1545
+ price = this.safeString(description, 'price2');
1546
+ }
1547
+ if ((price === undefined) || Precise["default"].stringEquals(price, '0')) {
1548
+ price = this.safeString(order, 'price', price);
1549
+ }
1550
+ const flags = this.safeString(order, 'oflags', '');
1551
+ const isPostOnly = flags.indexOf('post') > -1;
1552
+ const average = this.safeNumber(order, 'price');
1553
+ if (market !== undefined) {
1554
+ symbol = market['symbol'];
1555
+ if ('fee' in order) {
1556
+ const feeCost = this.safeString(order, 'fee');
1557
+ fee = {
1558
+ 'cost': feeCost,
1559
+ 'rate': undefined,
1560
+ };
1561
+ if (flags.indexOf('fciq') >= 0) {
1562
+ fee['currency'] = market['quote'];
1563
+ }
1564
+ else if (flags.indexOf('fcib') >= 0) {
1565
+ fee['currency'] = market['base'];
1566
+ }
1567
+ }
1568
+ }
1569
+ const status = this.parseOrderStatus(this.safeString(order, 'status'));
1570
+ let id = this.safeString2(order, 'id', 'txid');
1571
+ if ((id === undefined) || (id.slice(0, 1) === '[')) {
1572
+ const txid = this.safeValue(order, 'txid');
1573
+ id = this.safeString(txid, 0);
1574
+ }
1575
+ const clientOrderId = this.safeString(order, 'userref');
1576
+ const rawTrades = this.safeValue(order, 'trades', []);
1577
+ const trades = [];
1578
+ for (let i = 0; i < rawTrades.length; i++) {
1579
+ const rawTrade = rawTrades[i];
1580
+ if (typeof rawTrade === 'string') {
1581
+ trades.push(this.safeTrade({ 'id': rawTrade, 'orderId': id, 'symbol': symbol, 'info': {} }));
1582
+ }
1583
+ else {
1584
+ trades.push(rawTrade);
1585
+ }
1586
+ }
1587
+ stopPrice = this.safeNumber(order, 'stopprice', stopPrice);
1588
+ return this.safeOrder({
1589
+ 'id': id,
1590
+ 'clientOrderId': clientOrderId,
1591
+ 'info': order,
1592
+ 'timestamp': timestamp,
1593
+ 'datetime': this.iso8601(timestamp),
1594
+ 'lastTradeTimestamp': undefined,
1595
+ 'status': status,
1596
+ 'symbol': symbol,
1597
+ 'type': type,
1598
+ 'timeInForce': undefined,
1599
+ 'postOnly': isPostOnly,
1600
+ 'side': side,
1601
+ 'price': price,
1602
+ 'stopPrice': stopPrice,
1603
+ 'triggerPrice': stopPrice,
1604
+ 'cost': undefined,
1605
+ 'amount': amount,
1606
+ 'filled': filled,
1607
+ 'average': average,
1608
+ 'remaining': undefined,
1609
+ 'fee': fee,
1610
+ 'trades': trades,
1611
+ }, market);
1612
+ }
1613
+ orderRequest(method, symbol, type, request, price = undefined, params = {}) {
1614
+ const clientOrderId = this.safeString2(params, 'userref', 'clientOrderId');
1615
+ params = this.omit(params, ['userref', 'clientOrderId']);
1616
+ if (clientOrderId !== undefined) {
1617
+ request['userref'] = clientOrderId;
1618
+ }
1619
+ const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
1620
+ const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
1621
+ const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
1622
+ const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
1623
+ const isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
1624
+ const trailingAmount = this.safeString(params, 'trailingAmount');
1625
+ const trailingLimitAmount = this.safeString(params, 'trailingLimitAmount');
1626
+ const isTrailingAmountOrder = trailingAmount !== undefined;
1627
+ if ((type === 'limit') && !isTrailingAmountOrder) {
1628
+ request['price'] = this.priceToPrecision(symbol, price);
1629
+ }
1630
+ let reduceOnly = this.safeValue2(params, 'reduceOnly', 'reduce_only');
1631
+ if (isStopLossOrTakeProfitTrigger) {
1632
+ if (isStopLossTriggerOrder) {
1633
+ request['price'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
1634
+ request['ordertype'] = 'stop-loss-limit';
1635
+ }
1636
+ else if (isTakeProfitTriggerOrder) {
1637
+ request['price'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
1638
+ request['ordertype'] = 'take-profit-limit';
1639
+ }
1640
+ request['price2'] = this.priceToPrecision(symbol, price);
1641
+ reduceOnly = true;
1642
+ }
1643
+ else if (isTrailingAmountOrder) {
1644
+ const trailingActivationPriceType = this.safeString(params, 'trigger', 'last');
1645
+ const trailingAmountString = '+' + trailingAmount;
1646
+ request['trigger'] = trailingActivationPriceType;
1647
+ if ((type === 'limit') || (trailingLimitAmount !== undefined)) {
1648
+ const offset = this.safeString(params, 'offset', '-');
1649
+ const trailingLimitAmountString = offset + this.numberToString(trailingLimitAmount);
1650
+ request['price'] = trailingAmountString;
1651
+ request['price2'] = trailingLimitAmountString;
1652
+ request['ordertype'] = 'trailing-stop-limit';
1653
+ }
1654
+ else {
1655
+ request['price'] = trailingAmountString;
1656
+ request['ordertype'] = 'trailing-stop';
1657
+ }
1658
+ }
1659
+ if (reduceOnly) {
1660
+ request['reduce_only'] = 'true'; // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
1661
+ }
1662
+ let close = this.safeValue(params, 'close');
1663
+ if (close !== undefined) {
1664
+ close = this.extend({}, close);
1665
+ const closePrice = this.safeValue(close, 'price');
1666
+ if (closePrice !== undefined) {
1667
+ close['price'] = this.priceToPrecision(symbol, closePrice);
1668
+ }
1669
+ const closePrice2 = this.safeValue(close, 'price2'); // stopPrice
1670
+ if (closePrice2 !== undefined) {
1671
+ close['price2'] = this.priceToPrecision(symbol, closePrice2);
1672
+ }
1673
+ request['close'] = close;
1674
+ }
1675
+ const timeInForce = this.safeString2(params, 'timeInForce', 'timeinforce');
1676
+ if (timeInForce !== undefined) {
1677
+ request['timeinforce'] = timeInForce;
1678
+ }
1679
+ const isMarket = (type === 'market');
1680
+ let postOnly = undefined;
1681
+ [postOnly, params] = this.handlePostOnly(isMarket, false, params);
1682
+ if (postOnly) {
1683
+ request['oflags'] = 'post';
1684
+ }
1685
+ params = this.omit(params, ['timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset']);
1686
+ return [request, params];
1687
+ }
1688
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1689
+ /**
1690
+ * @method
1691
+ * @name kraken#editOrder
1692
+ * @description edit a trade order
1693
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/editOrder
1694
+ * @param {string} id order id
1695
+ * @param {string} symbol unified symbol of the market to create an order in
1696
+ * @param {string} type 'market' or 'limit'
1697
+ * @param {string} side 'buy' or 'sell'
1698
+ * @param {float} amount how much of the currency you want to trade in units of the base currency
1699
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1700
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1701
+ * @param {float} [params.stopLossPrice] *margin only* the price that a stop loss order is triggered at
1702
+ * @param {float} [params.takeProfitPrice] *margin only* the price that a take profit order is triggered at
1703
+ * @param {string} [params.trailingAmount] *margin only* the quote price away from the current market price
1704
+ * @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount
1705
+ * @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
1706
+ * @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last'
1707
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1708
+ */
1709
+ await this.loadMarkets();
1710
+ const market = this.market(symbol);
1711
+ if (!market['spot']) {
1712
+ throw new errors.NotSupported(this.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted');
1713
+ }
1714
+ const request = {
1715
+ 'txid': id,
1716
+ 'pair': market['id'],
1717
+ };
1718
+ if (amount !== undefined) {
1719
+ request['volume'] = this.amountToPrecision(symbol, amount);
1720
+ }
1721
+ const orderRequest = this.orderRequest('editOrder()', symbol, type, request, price, params);
1722
+ const response = await this.privatePostEditOrder(this.extend(orderRequest[0], orderRequest[1]));
1723
+ //
1724
+ // {
1725
+ // "error": [],
1726
+ // "result": {
1727
+ // "status": "ok",
1728
+ // "txid": "OAW2BO-7RWEK-PZY5UO",
1729
+ // "originaltxid": "OXL6SS-UPNMC-26WBE7",
1730
+ // "volume": "0.00075000",
1731
+ // "price": "13500.0",
1732
+ // "orders_cancelled": 1,
1733
+ // "descr": {
1734
+ // "order": "buy 0.00075000 XBTUSDT @ limit 13500.0"
1735
+ // }
1736
+ // }
1737
+ // }
1738
+ //
1739
+ const data = this.safeValue(response, 'result', {});
1740
+ return this.parseOrder(data, market);
1741
+ }
1742
+ async fetchOrder(id, symbol = undefined, params = {}) {
1743
+ /**
1744
+ * @method
1745
+ * @name kraken#fetchOrder
1746
+ * @description fetches information on an order made by the user
1747
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOrdersInfo
1748
+ * @param {string} symbol not used by kraken fetchOrder
1749
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1750
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1751
+ */
1752
+ await this.loadMarkets();
1753
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
1754
+ const request = {
1755
+ 'trades': true, // whether or not to include trades in output (optional, default false)
1756
+ // 'txid': id, // do not comma separate a list of ids - use fetchOrdersByIds instead
1757
+ // 'userref': 'optional', // restrict results to given user reference id (optional)
1758
+ };
1759
+ let query = params;
1760
+ if (clientOrderId !== undefined) {
1761
+ request['userref'] = clientOrderId;
1762
+ query = this.omit(params, ['userref', 'clientOrderId']);
1763
+ }
1764
+ else {
1765
+ request['txid'] = id;
1766
+ }
1767
+ const response = await this.privatePostQueryOrders(this.extend(request, query));
1768
+ //
1769
+ // {
1770
+ // "error":[],
1771
+ // "result":{
1772
+ // "OTLAS3-RRHUF-NDWH5A":{
1773
+ // "refid":null,
1774
+ // "userref":null,
1775
+ // "status":"closed",
1776
+ // "reason":null,
1777
+ // "opentm":1586822919.3342,
1778
+ // "closetm":1586822919.365,
1779
+ // "starttm":0,
1780
+ // "expiretm":0,
1781
+ // "descr":{
1782
+ // "pair":"XBTUSDT",
1783
+ // "type":"sell",
1784
+ // "ordertype":"market",
1785
+ // "price":"0",
1786
+ // "price2":"0",
1787
+ // "leverage":"none",
1788
+ // "order":"sell 0.21804000 XBTUSDT @ market",
1789
+ // "close":""
1790
+ // },
1791
+ // "vol":"0.21804000",
1792
+ // "vol_exec":"0.21804000",
1793
+ // "cost":"1493.9",
1794
+ // "fee":"3.8",
1795
+ // "price":"6851.5",
1796
+ // "stopprice":"0.00000",
1797
+ // "limitprice":"0.00000",
1798
+ // "misc":"",
1799
+ // "oflags":"fciq",
1800
+ // "trades":["TT5UC3-GOIRW-6AZZ6R"]
1801
+ // }
1802
+ // }
1803
+ // }
1804
+ //
1805
+ const result = this.safeValue(response, 'result', []);
1806
+ if (!(id in result)) {
1807
+ throw new errors.OrderNotFound(this.id + ' fetchOrder() could not find order id ' + id);
1808
+ }
1809
+ return this.parseOrder(this.extend({ 'id': id }, result[id]));
1810
+ }
1811
+ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
1812
+ /**
1813
+ * @method
1814
+ * @name kraken#fetchOrderTrades
1815
+ * @description fetch all the trades made from a single order
1816
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradesInfo
1817
+ * @param {string} id order id
1818
+ * @param {string} symbol unified market symbol
1819
+ * @param {int} [since] the earliest time in ms to fetch trades for
1820
+ * @param {int} [limit] the maximum number of trades to retrieve
1821
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1822
+ * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1823
+ */
1824
+ const orderTrades = this.safeValue(params, 'trades');
1825
+ const tradeIds = [];
1826
+ if (orderTrades === undefined) {
1827
+ 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)");
1828
+ }
1829
+ else {
1830
+ for (let i = 0; i < orderTrades.length; i++) {
1831
+ const orderTrade = orderTrades[i];
1832
+ if (typeof orderTrade === 'string') {
1833
+ tradeIds.push(orderTrade);
1834
+ }
1835
+ else {
1836
+ tradeIds.push(orderTrade['id']);
1837
+ }
1838
+ }
1839
+ }
1840
+ await this.loadMarkets();
1841
+ if (symbol !== undefined) {
1842
+ symbol = this.symbol(symbol);
1843
+ }
1844
+ const options = this.safeValue(this.options, 'fetchOrderTrades', {});
1845
+ const batchSize = this.safeInteger(options, 'batchSize', 20);
1846
+ const numTradeIds = tradeIds.length;
1847
+ let numBatches = this.parseToInt(numTradeIds / batchSize);
1848
+ numBatches = this.sum(numBatches, 1);
1849
+ let result = [];
1850
+ for (let j = 0; j < numBatches; j++) {
1851
+ const requestIds = [];
1852
+ for (let k = 0; k < batchSize; k++) {
1853
+ const index = this.sum(j * batchSize, k);
1854
+ if (index < numTradeIds) {
1855
+ requestIds.push(tradeIds[index]);
1856
+ }
1857
+ }
1858
+ const request = {
1859
+ 'txid': requestIds.join(','),
1860
+ };
1861
+ const response = await this.privatePostQueryTrades(request);
1862
+ //
1863
+ // {
1864
+ // "error": [],
1865
+ // "result": {
1866
+ // 'TIMIRG-WUNNE-RRJ6GT': {
1867
+ // "ordertxid": 'OQRPN2-LRHFY-HIFA7D',
1868
+ // "postxid": 'TKH2SE-M7IF5-CFI7LT',
1869
+ // "pair": 'USDCUSDT',
1870
+ // "time": 1586340086.457,
1871
+ // "type": 'sell',
1872
+ // "ordertype": 'market',
1873
+ // "price": '0.99860000',
1874
+ // "cost": '22.16892001',
1875
+ // "fee": '0.04433784',
1876
+ // "vol": '22.20000000',
1877
+ // "margin": '0.00000000',
1878
+ // "misc": ''
1879
+ // }
1880
+ // }
1881
+ // }
1882
+ //
1883
+ const rawTrades = this.safeValue(response, 'result');
1884
+ const ids = Object.keys(rawTrades);
1885
+ for (let i = 0; i < ids.length; i++) {
1886
+ rawTrades[ids[i]]['id'] = ids[i];
1887
+ }
1888
+ const trades = this.parseTrades(rawTrades, undefined, since, limit);
1889
+ const tradesFilteredBySymbol = this.filterBySymbol(trades, symbol);
1890
+ result = this.arrayConcat(result, tradesFilteredBySymbol);
1891
+ }
1892
+ return result;
1893
+ }
1894
+ async fetchOrdersByIds(ids, symbol = undefined, params = {}) {
1895
+ /**
1896
+ * @method
1897
+ * @name kraken#fetchOrdersByIds
1898
+ * @description fetch orders by the list of order id
1899
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
1900
+ * @param {string[]|undefined} ids list of order id
1901
+ * @param {object} [params] extra parameters specific to the kraken api endpoint
1902
+ * @returns {object[]} a list of [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1903
+ */
1904
+ await this.loadMarkets();
1905
+ const response = await this.privatePostQueryOrders(this.extend({
1906
+ 'trades': true,
1907
+ 'txid': ids.join(','), // comma delimited list of transaction ids to query info about (20 maximum)
1908
+ }, params));
1909
+ const result = this.safeValue(response, 'result', {});
1910
+ const orders = [];
1911
+ const orderIds = Object.keys(result);
1912
+ for (let i = 0; i < orderIds.length; i++) {
1913
+ const id = orderIds[i];
1914
+ const item = result[id];
1915
+ const order = this.parseOrder(this.extend({ 'id': id }, item));
1916
+ orders.push(order);
1917
+ }
1918
+ return orders;
1919
+ }
1920
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1921
+ /**
1922
+ * @method
1923
+ * @name kraken#fetchMyTrades
1924
+ * @description fetch all trades made by the user
1925
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeHistory
1926
+ * @param {string} symbol unified market symbol
1927
+ * @param {int} [since] the earliest time in ms to fetch trades for
1928
+ * @param {int} [limit] the maximum number of trades structures to retrieve
1929
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1930
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1931
+ */
1932
+ await this.loadMarkets();
1933
+ const request = {
1934
+ // 'type': 'all', // any position, closed position, closing position, no position
1935
+ // 'trades': false, // whether or not to include trades related to position in output
1936
+ // 'start': 1234567890, // starting unix timestamp or trade tx id of results (exclusive)
1937
+ // 'end': 1234567890, // ending unix timestamp or trade tx id of results (inclusive)
1938
+ // 'ofs' = result offset
1939
+ };
1940
+ if (since !== undefined) {
1941
+ request['start'] = this.parseToInt(since / 1000);
1942
+ }
1943
+ const response = await this.privatePostTradesHistory(this.extend(request, params));
1944
+ //
1945
+ // {
1946
+ // "error": [],
1947
+ // "result": {
1948
+ // "trades": {
1949
+ // "GJ3NYQ-XJRTF-THZABF": {
1950
+ // "ordertxid": "TKH2SE-ZIF5E-CFI7LT",
1951
+ // "postxid": "OEN3VX-M7IF5-JNBJAM",
1952
+ // "pair": "XICNXETH",
1953
+ // "time": 1527213229.4491,
1954
+ // "type": "sell",
1955
+ // "ordertype": "limit",
1956
+ // "price": "0.001612",
1957
+ // "cost": "0.025792",
1958
+ // "fee": "0.000026",
1959
+ // "vol": "16.00000000",
1960
+ // "margin": "0.000000",
1961
+ // "misc": ""
1962
+ // },
1963
+ // ...
1964
+ // },
1965
+ // "count": 9760,
1966
+ // },
1967
+ // }
1968
+ //
1969
+ const trades = response['result']['trades'];
1970
+ const ids = Object.keys(trades);
1971
+ for (let i = 0; i < ids.length; i++) {
1972
+ trades[ids[i]]['id'] = ids[i];
1973
+ }
1974
+ let market = undefined;
1975
+ if (symbol !== undefined) {
1976
+ market = this.market(symbol);
1977
+ }
1978
+ return this.parseTrades(trades, market, since, limit);
1979
+ }
1980
+ async cancelOrder(id, symbol = undefined, params = {}) {
1981
+ /**
1982
+ * @method
1983
+ * @name kraken#cancelOrder
1984
+ * @description cancels an open order
1985
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelOrder
1986
+ * @param {string} id order id
1987
+ * @param {string} symbol unified symbol of the market the order was made in
1988
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1989
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1990
+ */
1991
+ await this.loadMarkets();
1992
+ let response = undefined;
1993
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId', id);
1994
+ const request = {
1995
+ 'txid': clientOrderId, // order id or userref
1996
+ };
1997
+ params = this.omit(params, ['userref', 'clientOrderId']);
1998
+ try {
1999
+ response = await this.privatePostCancelOrder(this.extend(request, params));
2000
+ }
2001
+ catch (e) {
2002
+ if (this.last_http_response) {
2003
+ if (this.last_http_response.indexOf('EOrder:Unknown order') >= 0) {
2004
+ throw new errors.OrderNotFound(this.id + ' cancelOrder() error ' + this.last_http_response);
2005
+ }
2006
+ }
2007
+ throw e;
2008
+ }
2009
+ return response;
2010
+ }
2011
+ async cancelOrders(ids, symbol = undefined, params = {}) {
2012
+ /**
2013
+ * @method
2014
+ * @name kraken#cancelOrders
2015
+ * @description cancel multiple orders
2016
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelOrderBatch
2017
+ * @param {string[]} ids open orders transaction ID (txid) or user reference (userref)
2018
+ * @param {string} symbol unified market symbol
2019
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2020
+ * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2021
+ */
2022
+ const request = {
2023
+ 'orders': ids,
2024
+ };
2025
+ const response = await this.privatePostCancelOrderBatch(this.extend(request, params));
2026
+ //
2027
+ // {
2028
+ // "error": [],
2029
+ // "result": {
2030
+ // "count": 2
2031
+ // }
2032
+ // }
2033
+ //
2034
+ return response;
2035
+ }
2036
+ async cancelAllOrders(symbol = undefined, params = {}) {
2037
+ /**
2038
+ * @method
2039
+ * @name kraken#cancelAllOrders
2040
+ * @description cancel all open orders
2041
+ * @see https://docs.kraken.com/rest/#tag/Trading/operation/cancelAllOrders
2042
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
2043
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2044
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2045
+ */
2046
+ await this.loadMarkets();
2047
+ return await this.privatePostCancelAll(params);
2048
+ }
2049
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2050
+ /**
2051
+ * @method
2052
+ * @name kraken#fetchOpenOrders
2053
+ * @description fetch all unfilled currently open orders
2054
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenOrders
2055
+ * @param {string} symbol unified market symbol
2056
+ * @param {int} [since] the earliest time in ms to fetch open orders for
2057
+ * @param {int} [limit] the maximum number of open orders structures to retrieve
2058
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2059
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2060
+ */
2061
+ await this.loadMarkets();
2062
+ const request = {};
2063
+ if (since !== undefined) {
2064
+ request['start'] = this.parseToInt(since / 1000);
2065
+ }
2066
+ let query = params;
2067
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
2068
+ if (clientOrderId !== undefined) {
2069
+ request['userref'] = clientOrderId;
2070
+ query = this.omit(params, ['userref', 'clientOrderId']);
2071
+ }
2072
+ const response = await this.privatePostOpenOrders(this.extend(request, query));
2073
+ let market = undefined;
2074
+ if (symbol !== undefined) {
2075
+ market = this.market(symbol);
2076
+ }
2077
+ const result = this.safeValue(response, 'result', {});
2078
+ const orders = this.safeValue(result, 'open', []);
2079
+ return this.parseOrders(orders, market, since, limit);
2080
+ }
2081
+ async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2082
+ /**
2083
+ * @method
2084
+ * @name kraken#fetchClosedOrders
2085
+ * @description fetches information on multiple closed orders made by the user
2086
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
2087
+ * @param {string} symbol unified market symbol of the market orders were made in
2088
+ * @param {int} [since] the earliest time in ms to fetch orders for
2089
+ * @param {int} [limit] the maximum number of order structures to retrieve
2090
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2091
+ * @param {int} [params.until] timestamp in ms of the latest entry
2092
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2093
+ */
2094
+ await this.loadMarkets();
2095
+ let request = {};
2096
+ if (since !== undefined) {
2097
+ request['start'] = this.parseToInt(since / 1000);
2098
+ }
2099
+ let query = params;
2100
+ const clientOrderId = this.safeValue2(params, 'userref', 'clientOrderId');
2101
+ if (clientOrderId !== undefined) {
2102
+ request['userref'] = clientOrderId;
2103
+ query = this.omit(params, ['userref', 'clientOrderId']);
2104
+ }
2105
+ [request, params] = this.handleUntilOption('end', request, params);
2106
+ const response = await this.privatePostClosedOrders(this.extend(request, query));
2107
+ //
2108
+ // {
2109
+ // "error":[],
2110
+ // "result":{
2111
+ // "closed":{
2112
+ // "OETZYO-UL524-QJMXCT":{
2113
+ // "refid":null,
2114
+ // "userref":null,
2115
+ // "status":"canceled",
2116
+ // "reason":"User requested",
2117
+ // "opentm":1601489313.3898,
2118
+ // "closetm":1601489346.5507,
2119
+ // "starttm":0,
2120
+ // "expiretm":0,
2121
+ // "descr":{
2122
+ // "pair":"ETHUSDT",
2123
+ // "type":"buy",
2124
+ // "ordertype":"limit",
2125
+ // "price":"330.00",
2126
+ // "price2":"0",
2127
+ // "leverage":"none",
2128
+ // "order":"buy 0.02100000 ETHUSDT @ limit 330.00",
2129
+ // "close":""
2130
+ // },
2131
+ // "vol":"0.02100000",
2132
+ // "vol_exec":"0.00000000",
2133
+ // "cost":"0.00000",
2134
+ // "fee":"0.00000",
2135
+ // "price":"0.00000",
2136
+ // "stopprice":"0.00000",
2137
+ // "limitprice":"0.00000",
2138
+ // "misc":"",
2139
+ // "oflags":"fciq"
2140
+ // },
2141
+ // },
2142
+ // "count":16
2143
+ // }
2144
+ // }
2145
+ //
2146
+ let market = undefined;
2147
+ if (symbol !== undefined) {
2148
+ market = this.market(symbol);
2149
+ }
2150
+ const result = this.safeValue(response, 'result', {});
2151
+ const orders = this.safeValue(result, 'closed', []);
2152
+ return this.parseOrders(orders, market, since, limit);
2153
+ }
2154
+ parseTransactionStatus(status) {
2155
+ // IFEX transaction states
2156
+ const statuses = {
2157
+ 'Initial': 'pending',
2158
+ 'Pending': 'pending',
2159
+ 'Success': 'ok',
2160
+ 'Settled': 'pending',
2161
+ 'Failure': 'failed',
2162
+ 'Partial': 'ok',
2163
+ };
2164
+ return this.safeString(statuses, status, status);
2165
+ }
2166
+ parseNetwork(network) {
2167
+ const withdrawMethods = this.safeValue(this.options, 'withdrawMethods', {});
2168
+ return this.safeString(withdrawMethods, network, network);
2169
+ }
2170
+ parseTransaction(transaction, currency = undefined) {
2171
+ //
2172
+ // fetchDeposits
2173
+ //
2174
+ // {
2175
+ // "method": "Ether (Hex)",
2176
+ // "aclass": "currency",
2177
+ // "asset": "XETH",
2178
+ // "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
2179
+ // "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
2180
+ // "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
2181
+ // "amount": "7.9999257900",
2182
+ // "fee": "0.0000000000",
2183
+ // "time": 1529223212,
2184
+ // "status": "Success"
2185
+ // }
2186
+ //
2187
+ // there can be an additional 'status-prop' field present
2188
+ // deposit pending review by exchange => 'on-hold'
2189
+ // the deposit is initiated by the exchange => 'return'
2190
+ //
2191
+ // {
2192
+ // "type": 'deposit',
2193
+ // "method": 'Fidor Bank AG (Wire Transfer)',
2194
+ // "aclass": 'currency',
2195
+ // "asset": 'ZEUR',
2196
+ // "refid": 'xxx-xxx-xxx',
2197
+ // "txid": '12341234',
2198
+ // "info": 'BANKCODEXXX',
2199
+ // "amount": '38769.08',
2200
+ // "fee": '0.0000',
2201
+ // "time": 1644306552,
2202
+ // "status": 'Success',
2203
+ // status-prop: 'on-hold'
2204
+ // }
2205
+ //
2206
+ //
2207
+ // fetchWithdrawals
2208
+ //
2209
+ // {
2210
+ // "method": "Ether",
2211
+ // "aclass": "currency",
2212
+ // "asset": "XETH",
2213
+ // "refid": "A2BF34S-O7LBNQ-UE4Y4O",
2214
+ // "txid": "0x288b83c6b0904d8400ef44e1c9e2187b5c8f7ea3d838222d53f701a15b5c274d",
2215
+ // "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
2216
+ // "amount": "9.9950000000",
2217
+ // "fee": "0.0050000000",
2218
+ // "time": 1530481750,
2219
+ // "status": "Success"
2220
+ // "key":"Huobi wallet",
2221
+ // "network":"Tron"
2222
+ // status-prop: 'on-hold' // this field might not be present in some cases
2223
+ // }
2224
+ //
2225
+ // withdraw
2226
+ //
2227
+ // {
2228
+ // "refid": "AGBSO6T-UFMTTQ-I7KGS6"
2229
+ // }
2230
+ //
2231
+ const id = this.safeString(transaction, 'refid');
2232
+ const txid = this.safeString(transaction, 'txid');
2233
+ const timestamp = this.safeTimestamp(transaction, 'time');
2234
+ const currencyId = this.safeString(transaction, 'asset');
2235
+ const code = this.safeCurrencyCode(currencyId, currency);
2236
+ const address = this.safeString(transaction, 'info');
2237
+ const amount = this.safeNumber(transaction, 'amount');
2238
+ let status = this.parseTransactionStatus(this.safeString(transaction, 'status'));
2239
+ const statusProp = this.safeString(transaction, 'status-prop');
2240
+ const isOnHoldDeposit = statusProp === 'on-hold';
2241
+ const isCancellationRequest = statusProp === 'cancel-pending';
2242
+ const isOnHoldWithdrawal = statusProp === 'onhold';
2243
+ if (isOnHoldDeposit || isCancellationRequest || isOnHoldWithdrawal) {
2244
+ status = 'pending';
2245
+ }
2246
+ const type = this.safeString(transaction, 'type'); // injected from the outside
2247
+ let feeCost = this.safeNumber(transaction, 'fee');
2248
+ if (feeCost === undefined) {
2249
+ if (type === 'deposit') {
2250
+ feeCost = 0;
2251
+ }
2252
+ }
2253
+ return {
2254
+ 'info': transaction,
2255
+ 'id': id,
2256
+ 'currency': code,
2257
+ 'amount': amount,
2258
+ 'network': this.parseNetwork(this.safeString(transaction, 'network')),
2259
+ 'address': address,
2260
+ 'addressTo': undefined,
2261
+ 'addressFrom': undefined,
2262
+ 'tag': undefined,
2263
+ 'tagTo': undefined,
2264
+ 'tagFrom': undefined,
2265
+ 'status': status,
2266
+ 'type': type,
2267
+ 'updated': undefined,
2268
+ 'txid': txid,
2269
+ 'timestamp': timestamp,
2270
+ 'datetime': this.iso8601(timestamp),
2271
+ 'comment': undefined,
2272
+ 'internal': undefined,
2273
+ 'fee': {
2274
+ 'currency': code,
2275
+ 'cost': feeCost,
2276
+ },
2277
+ };
2278
+ }
2279
+ parseTransactionsByType(type, transactions, code = undefined, since = undefined, limit = undefined) {
2280
+ const result = [];
2281
+ for (let i = 0; i < transactions.length; i++) {
2282
+ const transaction = this.parseTransaction(this.extend({
2283
+ 'type': type,
2284
+ }, transactions[i]));
2285
+ result.push(transaction);
2286
+ }
2287
+ return this.filterByCurrencySinceLimit(result, code, since, limit);
2288
+ }
2289
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
2290
+ /**
2291
+ * @method
2292
+ * @name kraken#fetchDeposits
2293
+ * @description fetch all deposits made to an account
2294
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentDeposits
2295
+ * @param {string} code unified currency code
2296
+ * @param {int} [since] the earliest time in ms to fetch deposits for
2297
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
2298
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2299
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2300
+ */
2301
+ // https://www.kraken.com/en-us/help/api#deposit-status
2302
+ if (code === undefined) {
2303
+ throw new errors.ArgumentsRequired(this.id + ' fetchDeposits() requires a currency code argument');
2304
+ }
2305
+ await this.loadMarkets();
2306
+ const currency = this.currency(code);
2307
+ const request = {
2308
+ 'asset': currency['id'],
2309
+ };
2310
+ if (since !== undefined) {
2311
+ request['start'] = since;
2312
+ }
2313
+ const response = await this.privatePostDepositStatus(this.extend(request, params));
2314
+ //
2315
+ // { error: [],
2316
+ // "result": [ { "method": "Ether (Hex)",
2317
+ // "aclass": "currency",
2318
+ // "asset": "XETH",
2319
+ // "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
2320
+ // "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
2321
+ // "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
2322
+ // "amount": "7.9999257900",
2323
+ // "fee": "0.0000000000",
2324
+ // "time": 1529223212,
2325
+ // "status": "Success" } ] }
2326
+ //
2327
+ return this.parseTransactionsByType('deposit', response['result'], code, since, limit);
2328
+ }
2329
+ async fetchTime(params = {}) {
2330
+ /**
2331
+ * @method
2332
+ * @name kraken#fetchTime
2333
+ * @description fetches the current integer timestamp in milliseconds from the exchange server
2334
+ * @see https://docs.kraken.com/rest/#tag/Market-Data/operation/getServerTime
2335
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2336
+ * @returns {int} the current integer timestamp in milliseconds from the exchange server
2337
+ */
2338
+ // https://www.kraken.com/en-us/features/api#get-server-time
2339
+ const response = await this.publicGetTime(params);
2340
+ //
2341
+ // {
2342
+ // "error": [],
2343
+ // "result": {
2344
+ // "unixtime": 1591502873,
2345
+ // "rfc1123": "Sun, 7 Jun 20 04:07:53 +0000"
2346
+ // }
2347
+ // }
2348
+ //
2349
+ const result = this.safeValue(response, 'result', {});
2350
+ return this.safeTimestamp(result, 'unixtime');
2351
+ }
2352
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
2353
+ /**
2354
+ * @method
2355
+ * @name kraken#fetchWithdrawals
2356
+ * @description fetch all withdrawals made from an account
2357
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentWithdrawals
2358
+ * @param {string} code unified currency code
2359
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
2360
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
2361
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2362
+ * @param {object} [params.end] End timestamp, withdrawals created strictly after will be not be included in the response
2363
+ * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times
2364
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2365
+ */
2366
+ await this.loadMarkets();
2367
+ let paginate = false;
2368
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchWithdrawals', 'paginate');
2369
+ if (paginate) {
2370
+ params['cursor'] = true;
2371
+ return await this.fetchPaginatedCallCursor('fetchWithdrawals', code, since, limit, params, 'next_cursor', 'cursor');
2372
+ }
2373
+ const request = {};
2374
+ if (code !== undefined) {
2375
+ const currency = this.currency(code);
2376
+ request['asset'] = currency['id'];
2377
+ }
2378
+ if (since !== undefined) {
2379
+ request['since'] = since.toString();
2380
+ }
2381
+ const response = await this.privatePostWithdrawStatus(this.extend(request, params));
2382
+ //
2383
+ // with no pagination
2384
+ // { error: [],
2385
+ // "result": [ { "method": "Ether",
2386
+ // "aclass": "currency",
2387
+ // "asset": "XETH",
2388
+ // "refid": "A2BF34S-O7LBNQ-UE4Y4O",
2389
+ // "txid": "0x298c83c7b0904d8400ef43e1c9e2287b518f7ea3d838822d53f704a1565c274d",
2390
+ // "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
2391
+ // "amount": "9.9950000000",
2392
+ // "fee": "0.0050000000",
2393
+ // "time": 1530481750,
2394
+ // "status": "Success" } ] }
2395
+ // with pagination
2396
+ // {
2397
+ // "error":[],
2398
+ // "result":{
2399
+ // "withdrawals":[
2400
+ // {
2401
+ // "method":"Tether USD (TRC20)",
2402
+ // "aclass":"currency",
2403
+ // "asset":"USDT",
2404
+ // "refid":"BSNFZU2-MEFN4G-J3NEZV",
2405
+ // "txid":"1c7a642fb7387bbc2c6a2c509fd1ae146937f4cf793b4079a4f0715e3a02615a",
2406
+ // "info":"TQmdxSuC16EhFg8FZWtYgrfFRosoRF7bCp",
2407
+ // "amount":"1996.50000000",
2408
+ // "fee":"2.50000000",
2409
+ // "time":1669126657,
2410
+ // "status":"Success",
2411
+ // "key":"poloniex",
2412
+ // "network":"Tron"
2413
+ // },
2414
+ // ...
2415
+ // ],
2416
+ // "next_cursor":"HgAAAAAAAABGVFRSd3k1LVF4Y0JQY05Gd0xRY0NxenFndHpybkwBAQH2AwEBAAAAAQAAAAAAAAABAAAAAAAZAAAAAAAAAA=="
2417
+ // }
2418
+ // }
2419
+ //
2420
+ let rawWithdrawals = undefined;
2421
+ const result = this.safeValue(response, 'result');
2422
+ if (!Array.isArray(result)) {
2423
+ rawWithdrawals = this.addPaginationCursorToResult(result);
2424
+ }
2425
+ else {
2426
+ rawWithdrawals = result;
2427
+ }
2428
+ return this.parseTransactionsByType('withdrawal', rawWithdrawals, code, since, limit);
2429
+ }
2430
+ addPaginationCursorToResult(result) {
2431
+ const cursor = this.safeString(result, 'next_cursor');
2432
+ const data = this.safeValue(result, 'withdrawals');
2433
+ const dataLength = data.length;
2434
+ if (cursor !== undefined && dataLength > 0) {
2435
+ const last = data[dataLength - 1];
2436
+ last['next_cursor'] = cursor;
2437
+ data[dataLength - 1] = last;
2438
+ }
2439
+ return data;
2440
+ }
2441
+ async createDepositAddress(code, params = {}) {
2442
+ /**
2443
+ * @method
2444
+ * @name kraken#createDepositAddress
2445
+ * @description create a currency deposit address
2446
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
2447
+ * @param {string} code unified currency code of the currency for the deposit address
2448
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2449
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2450
+ */
2451
+ const request = {
2452
+ 'new': 'true',
2453
+ };
2454
+ return await this.fetchDepositAddress(code, this.extend(request, params));
2455
+ }
2456
+ async fetchDepositMethods(code, params = {}) {
2457
+ /**
2458
+ * @method
2459
+ * @name kraken#fetchDepositMethods
2460
+ * @description fetch deposit methods for a currency associated with this account
2461
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositMethods
2462
+ * @param {string} code unified currency code
2463
+ * @param {object} [params] extra parameters specific to the kraken api endpoint
2464
+ * @returns {object} of deposit methods
2465
+ */
2466
+ await this.loadMarkets();
2467
+ const currency = this.currency(code);
2468
+ const request = {
2469
+ 'asset': currency['id'],
2470
+ };
2471
+ const response = await this.privatePostDepositMethods(this.extend(request, params));
2472
+ //
2473
+ // {
2474
+ // "error":[],
2475
+ // "result":[
2476
+ // {"method":"Ether (Hex)","limit":false,"gen-address":true}
2477
+ // ]
2478
+ // }
2479
+ //
2480
+ // {
2481
+ // "error":[],
2482
+ // "result":[
2483
+ // {"method":"Tether USD (ERC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true},
2484
+ // {"method":"Tether USD (TRC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true}
2485
+ // ]
2486
+ // }
2487
+ //
2488
+ // {
2489
+ // "error":[],
2490
+ // "result":[
2491
+ // {"method":"Bitcoin","limit":false,"fee":"0.0000000000","gen-address":true}
2492
+ // ]
2493
+ // }
2494
+ //
2495
+ return this.safeValue(response, 'result');
2496
+ }
2497
+ async fetchDepositAddress(code, params = {}) {
2498
+ /**
2499
+ * @method
2500
+ * @name kraken#fetchDepositAddress
2501
+ * @description fetch the deposit address for a currency associated with this account
2502
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
2503
+ * @param {string} code unified currency code
2504
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2505
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
2506
+ */
2507
+ await this.loadMarkets();
2508
+ const currency = this.currency(code);
2509
+ let network = this.safeStringUpper(params, 'network');
2510
+ const networks = this.safeValue(this.options, 'networks', {});
2511
+ network = this.safeString(networks, network, network); // support ETH > ERC20 aliases
2512
+ params = this.omit(params, 'network');
2513
+ if ((code === 'USDT') && (network === 'TRC20')) {
2514
+ code = code + '-' + network;
2515
+ }
2516
+ const defaultDepositMethods = this.safeValue(this.options, 'depositMethods', {});
2517
+ const defaultDepositMethod = this.safeString(defaultDepositMethods, code);
2518
+ let depositMethod = this.safeString(params, 'method', defaultDepositMethod);
2519
+ // if the user has specified an exchange-specific method in params
2520
+ // we pass it as is, otherwise we take the 'network' unified param
2521
+ if (depositMethod === undefined) {
2522
+ const depositMethods = await this.fetchDepositMethods(code);
2523
+ if (network !== undefined) {
2524
+ // find best matching deposit method, or fallback to the first one
2525
+ for (let i = 0; i < depositMethods.length; i++) {
2526
+ const entry = this.safeString(depositMethods[i], 'method');
2527
+ if (entry.indexOf(network) >= 0) {
2528
+ depositMethod = entry;
2529
+ break;
2530
+ }
2531
+ }
2532
+ }
2533
+ // if depositMethod was not specified, fallback to the first available deposit method
2534
+ if (depositMethod === undefined) {
2535
+ const firstDepositMethod = this.safeValue(depositMethods, 0, {});
2536
+ depositMethod = this.safeString(firstDepositMethod, 'method');
2537
+ }
2538
+ }
2539
+ const request = {
2540
+ 'asset': currency['id'],
2541
+ 'method': depositMethod,
2542
+ };
2543
+ const response = await this.privatePostDepositAddresses(this.extend(request, params));
2544
+ //
2545
+ // {
2546
+ // "error":[],
2547
+ // "result":[
2548
+ // {"address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3","expiretm":"0"}
2549
+ // ]
2550
+ // }
2551
+ //
2552
+ const result = this.safeValue(response, 'result', []);
2553
+ const firstResult = this.safeValue(result, 0, {});
2554
+ if (firstResult === undefined) {
2555
+ throw new errors.InvalidAddress(this.id + ' privatePostDepositAddresses() returned no addresses for ' + code);
2556
+ }
2557
+ return this.parseDepositAddress(firstResult, currency);
2558
+ }
2559
+ parseDepositAddress(depositAddress, currency = undefined) {
2560
+ //
2561
+ // {
2562
+ // "address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3",
2563
+ // "expiretm":"0"
2564
+ // }
2565
+ //
2566
+ const address = this.safeString(depositAddress, 'address');
2567
+ const tag = this.safeString(depositAddress, 'tag');
2568
+ currency = this.safeCurrency(undefined, currency);
2569
+ const code = currency['code'];
2570
+ this.checkAddress(address);
2571
+ return {
2572
+ 'currency': code,
2573
+ 'address': address,
2574
+ 'tag': tag,
2575
+ 'network': undefined,
2576
+ 'info': depositAddress,
2577
+ };
2578
+ }
2579
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
2580
+ /**
2581
+ * @method
2582
+ * @name kraken#withdraw
2583
+ * @description make a withdrawal
2584
+ * @see https://docs.kraken.com/rest/#tag/Funding/operation/withdrawFunds
2585
+ * @param {string} code unified currency code
2586
+ * @param {float} amount the amount to withdraw
2587
+ * @param {string} address the address to withdraw to
2588
+ * @param {string} tag
2589
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2590
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
2591
+ */
2592
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
2593
+ this.checkAddress(address);
2594
+ if ('key' in params) {
2595
+ await this.loadMarkets();
2596
+ const currency = this.currency(code);
2597
+ const request = {
2598
+ 'asset': currency['id'],
2599
+ 'amount': amount,
2600
+ 'address': address,
2601
+ };
2602
+ const response = await this.privatePostWithdraw(this.extend(request, params));
2603
+ //
2604
+ // {
2605
+ // "error": [],
2606
+ // "result": {
2607
+ // "refid": "AGBSO6T-UFMTTQ-I7KGS6"
2608
+ // }
2609
+ // }
2610
+ //
2611
+ const result = this.safeValue(response, 'result', {});
2612
+ return this.parseTransaction(result, currency);
2613
+ }
2614
+ throw new errors.ExchangeError(this.id + " withdraw() requires a 'key' parameter (withdrawal key name, as set up on your account)");
2615
+ }
2616
+ async fetchPositions(symbols = undefined, params = {}) {
2617
+ /**
2618
+ * @method
2619
+ * @name kraken#fetchPositions
2620
+ * @description fetch all open positions
2621
+ * @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
2622
+ * @param {string[]|undefined} symbols not used by kraken fetchPositions ()
2623
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
2624
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
2625
+ */
2626
+ await this.loadMarkets();
2627
+ const request = {
2628
+ // 'txid': 'comma delimited list of transaction ids to restrict output to',
2629
+ // 'docalcs': false, // whether or not to include profit/loss calculations
2630
+ // 'consolidation': 'market', // what to consolidate the positions data around, market will consolidate positions based on market pair
2631
+ };
2632
+ const response = await this.privatePostOpenPositions(this.extend(request, params));
2633
+ //
2634
+ // no consolidation
2635
+ //
2636
+ // {
2637
+ // "error": [],
2638
+ // "result": {
2639
+ // 'TGUFMY-FLESJ-VYIX3J': {
2640
+ // "ordertxid": "O3LRNU-ZKDG5-XNCDFR",
2641
+ // "posstatus": "open",
2642
+ // "pair": "ETHUSDT",
2643
+ // "time": 1611557231.4584,
2644
+ // "type": "buy",
2645
+ // "ordertype": "market",
2646
+ // "cost": "28.49800",
2647
+ // "fee": "0.07979",
2648
+ // "vol": "0.02000000",
2649
+ // "vol_closed": "0.00000000",
2650
+ // "margin": "14.24900",
2651
+ // "terms": "0.0200% per 4 hours",
2652
+ // "rollovertm": "1611571631",
2653
+ // "misc": "",
2654
+ // "oflags": ""
2655
+ // }
2656
+ // }
2657
+ // }
2658
+ //
2659
+ // consolidation by market
2660
+ //
2661
+ // {
2662
+ // "error": [],
2663
+ // "result": [
2664
+ // {
2665
+ // "pair": "ETHUSDT",
2666
+ // "positions": "1",
2667
+ // "type": "buy",
2668
+ // "leverage": "2.00000",
2669
+ // "cost": "28.49800",
2670
+ // "fee": "0.07979",
2671
+ // "vol": "0.02000000",
2672
+ // "vol_closed": "0.00000000",
2673
+ // "margin": "14.24900"
2674
+ // }
2675
+ // ]
2676
+ // }
2677
+ //
2678
+ const result = this.safeValue(response, 'result');
2679
+ // todo unify parsePosition/parsePositions
2680
+ return result;
2681
+ }
2682
+ parseAccount(account) {
2683
+ const accountByType = {
2684
+ 'spot': 'Spot Wallet',
2685
+ 'swap': 'Futures Wallet',
2686
+ 'future': 'Futures Wallet',
2687
+ };
2688
+ return this.safeString(accountByType, account, account);
2689
+ }
2690
+ async transferOut(code, amount, params = {}) {
2691
+ /**
2692
+ * @description transfer from spot wallet to futures wallet
2693
+ * @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
2694
+ * @param {str} code Unified currency code
2695
+ * @param {float} amount Size of the transfer
2696
+ * @param {dict} [params] Exchange specific parameters
2697
+ * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2698
+ */
2699
+ return await this.transfer(code, amount, 'spot', 'swap', params);
2700
+ }
2701
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
2702
+ /**
2703
+ * @method
2704
+ * @name kraken#transfer
2705
+ * @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
2706
+ * @description transfers currencies between sub-accounts (only spot->swap direction is supported)
2707
+ * @param {string} code Unified currency code
2708
+ * @param {float} amount Size of the transfer
2709
+ * @param {string} fromAccount 'spot' or 'Spot Wallet'
2710
+ * @param {string} toAccount 'swap' or 'Futures Wallet'
2711
+ * @param {object} [params] Exchange specific parameters
2712
+ * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
2713
+ */
2714
+ await this.loadMarkets();
2715
+ const currency = this.currency(code);
2716
+ fromAccount = this.parseAccount(fromAccount);
2717
+ toAccount = this.parseAccount(toAccount);
2718
+ const request = {
2719
+ 'amount': this.currencyToPrecision(code, amount),
2720
+ 'from': fromAccount,
2721
+ 'to': toAccount,
2722
+ 'asset': currency['id'],
2723
+ };
2724
+ if (fromAccount !== 'Spot Wallet') {
2725
+ throw new errors.BadRequest(this.id + ' transfer cannot transfer from ' + fromAccount + ' to ' + toAccount + '. Use krakenfutures instead to transfer from the futures account.');
2726
+ }
2727
+ const response = await this.privatePostWalletTransfer(this.extend(request, params));
2728
+ //
2729
+ // {
2730
+ // "error":[
2731
+ // ],
2732
+ // "result":{
2733
+ // "refid":"BOIUSIF-M7DLMN-UXZ3P5"
2734
+ // }
2735
+ // }
2736
+ //
2737
+ const transfer = this.parseTransfer(response, currency);
2738
+ return this.extend(transfer, {
2739
+ 'amount': amount,
2740
+ 'fromAccount': fromAccount,
2741
+ 'toAccount': toAccount,
2742
+ });
2743
+ }
2744
+ parseTransfer(transfer, currency = undefined) {
2745
+ //
2746
+ // transfer
2747
+ //
2748
+ // {
2749
+ // "error":[
2750
+ // ],
2751
+ // "result":{
2752
+ // "refid":"BOIUSIF-M7DLMN-UXZ3P5"
2753
+ // }
2754
+ // }
2755
+ //
2756
+ const result = this.safeValue(transfer, 'result', {});
2757
+ const refid = this.safeString(result, 'refid');
2758
+ return {
2759
+ 'info': transfer,
2760
+ 'id': refid,
2761
+ 'timestamp': undefined,
2762
+ 'datetime': undefined,
2763
+ 'currency': this.safeString(currency, 'code'),
2764
+ 'amount': undefined,
2765
+ 'fromAccount': undefined,
2766
+ 'toAccount': undefined,
2767
+ 'status': 'sucess',
2768
+ };
2769
+ }
2770
+ sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
2771
+ let url = '/' + this.version + '/' + api + '/' + path;
2772
+ if (api === 'public') {
2773
+ if (Object.keys(params).length) {
2774
+ // urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2775
+ url += '?' + this.urlencodeNested(params);
2776
+ }
2777
+ }
2778
+ else if (api === 'private') {
2779
+ const isCancelOrderBatch = (path === 'CancelOrderBatch');
2780
+ this.checkRequiredCredentials();
2781
+ const nonce = this.nonce().toString();
2782
+ // urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
2783
+ if (isCancelOrderBatch) {
2784
+ body = this.json(this.extend({ 'nonce': nonce }, params));
2785
+ }
2786
+ else {
2787
+ body = this.urlencodeNested(this.extend({ 'nonce': nonce }, params));
2788
+ }
2789
+ const auth = this.encode(nonce + body);
2790
+ const hash = this.hash(auth, sha256.sha256, 'binary');
2791
+ const binary = this.encode(url);
2792
+ const binhash = this.binaryConcat(binary, hash);
2793
+ const secret = this.base64ToBinary(this.secret);
2794
+ const signature = this.hmac(binhash, secret, sha512.sha512, 'base64');
2795
+ headers = {
2796
+ 'API-Key': this.apiKey,
2797
+ 'API-Sign': signature,
2798
+ // 'Content-Type': 'application/x-www-form-urlencoded',
2799
+ };
2800
+ if (isCancelOrderBatch) {
2801
+ headers['Content-Type'] = 'application/json';
2802
+ }
2803
+ else {
2804
+ headers['Content-Type'] = 'application/x-www-form-urlencoded';
2805
+ }
2806
+ }
2807
+ else {
2808
+ url = '/' + path;
2809
+ }
2810
+ url = this.urls['api'][api] + url;
2811
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
2812
+ }
2813
+ nonce() {
2814
+ return this.milliseconds();
2815
+ }
2816
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2817
+ if (code === 520) {
2818
+ throw new errors.ExchangeNotAvailable(this.id + ' ' + code.toString() + ' ' + reason);
2819
+ }
2820
+ // todo: rewrite this for "broad" exceptions matching
2821
+ if (body.indexOf('Invalid order') >= 0) {
2822
+ throw new errors.InvalidOrder(this.id + ' ' + body);
2823
+ }
2824
+ if (body.indexOf('Invalid nonce') >= 0) {
2825
+ throw new errors.InvalidNonce(this.id + ' ' + body);
2826
+ }
2827
+ if (body.indexOf('Insufficient funds') >= 0) {
2828
+ throw new errors.InsufficientFunds(this.id + ' ' + body);
2829
+ }
2830
+ if (body.indexOf('Cancel pending') >= 0) {
2831
+ throw new errors.CancelPending(this.id + ' ' + body);
2832
+ }
2833
+ if (body.indexOf('Invalid arguments:volume') >= 0) {
2834
+ throw new errors.InvalidOrder(this.id + ' ' + body);
2835
+ }
2836
+ if (body.indexOf('Rate limit exceeded') >= 0) {
2837
+ throw new errors.RateLimitExceeded(this.id + ' ' + body);
2838
+ }
2839
+ if (response === undefined) {
2840
+ return undefined;
2841
+ }
2842
+ if (body[0] === '{') {
2843
+ if (typeof response !== 'string') {
2844
+ if ('error' in response) {
2845
+ const numErrors = response['error'].length;
2846
+ if (numErrors) {
2847
+ const message = this.id + ' ' + body;
2848
+ for (let i = 0; i < response['error'].length; i++) {
2849
+ const error = response['error'][i];
2850
+ this.throwExactlyMatchedException(this.exceptions, error, message);
2851
+ }
2852
+ throw new errors.ExchangeError(message);
2853
+ }
2854
+ }
2855
+ }
2856
+ }
2857
+ return undefined;
2858
+ }
2859
+ }
2860
+
2861
+ module.exports = kraken;