ccxt 4.2.17 → 4.2.19

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 (439) hide show
  1. package/README.md +9 -9
  2. package/dist/ccxt.browser.js +48992 -47725
  3. package/dist/ccxt.browser.min.js +3 -3
  4. package/dist/cjs/ccxt.js +12 -1
  5. package/dist/cjs/src/alpaca.js +18 -18
  6. package/dist/cjs/src/ascendex.js +13 -6
  7. package/dist/cjs/src/base/Exchange.js +266 -27
  8. package/dist/cjs/src/bigone.js +434 -168
  9. package/dist/cjs/src/binance.js +163 -34
  10. package/dist/cjs/src/binanceus.js +8 -0
  11. package/dist/cjs/src/bingx.js +183 -41
  12. package/dist/cjs/src/bitfinex.js +2 -3
  13. package/dist/cjs/src/bitget.js +59 -16
  14. package/dist/cjs/src/bitmart.js +5 -5
  15. package/dist/cjs/src/bitmex.js +4 -6
  16. package/dist/cjs/src/bitpanda.js +5 -1991
  17. package/dist/cjs/src/bitstamp.js +8 -0
  18. package/dist/cjs/src/bybit.js +27 -47
  19. package/dist/cjs/src/coinbase.js +176 -26
  20. package/dist/cjs/src/coincheck.js +1 -0
  21. package/dist/cjs/src/coinex.js +3 -0
  22. package/dist/cjs/src/coinlist.js +13 -6
  23. package/dist/cjs/src/coinone.js +2 -2
  24. package/dist/cjs/src/coinsph.js +4 -5
  25. package/dist/cjs/src/delta.js +7 -1
  26. package/dist/cjs/src/deribit.js +17 -4
  27. package/dist/cjs/src/gate.js +151 -169
  28. package/dist/cjs/src/gemini.js +1 -1
  29. package/dist/cjs/src/hitbtc.js +2 -3
  30. package/dist/cjs/src/htx.js +157 -7
  31. package/dist/cjs/src/huobijp.js +2 -3
  32. package/dist/cjs/src/independentreserve.js +7 -5
  33. package/dist/cjs/src/kraken.js +86 -54
  34. package/dist/cjs/src/kucoin.js +5 -0
  35. package/dist/cjs/src/kucoinfutures.js +131 -77
  36. package/dist/cjs/src/lbank.js +60 -33
  37. package/dist/cjs/src/luno.js +84 -2
  38. package/dist/cjs/src/mexc.js +3 -3
  39. package/dist/cjs/src/oceanex.js +1 -1
  40. package/dist/cjs/src/okx.js +23 -11
  41. package/dist/cjs/{js/src/bitpanda.js → src/onetrading.js} +39 -39
  42. package/dist/cjs/src/phemex.js +37 -27
  43. package/dist/cjs/src/poloniexfutures.js +1 -0
  44. package/dist/cjs/src/pro/binance.js +66 -25
  45. package/dist/cjs/src/pro/bitget.js +1 -1
  46. package/dist/cjs/src/pro/bitpanda.js +5 -1330
  47. package/dist/cjs/src/pro/coinbase.js +4 -1
  48. package/dist/cjs/src/pro/coincheck.js +208 -0
  49. package/dist/cjs/src/pro/hitbtc.js +5 -4
  50. package/dist/cjs/src/pro/htx.js +6 -1
  51. package/dist/cjs/src/pro/kraken.js +1 -1
  52. package/dist/cjs/src/pro/krakenfutures.js +7 -1
  53. package/dist/cjs/src/pro/kucoin.js +46 -36
  54. package/dist/cjs/src/pro/kucoinfutures.js +45 -37
  55. package/dist/cjs/src/pro/lbank.js +881 -0
  56. package/dist/cjs/src/pro/okx.js +52 -2
  57. package/dist/cjs/{js/src/pro/bitpanda.js → src/pro/onetrading.js} +4 -7
  58. package/dist/cjs/src/pro/poloniex.js +2 -2
  59. package/dist/cjs/src/pro/poloniexfutures.js +43 -35
  60. package/dist/cjs/src/pro/woo.js +126 -0
  61. package/dist/cjs/src/probit.js +4 -2
  62. package/dist/cjs/src/upbit.js +12 -12
  63. package/dist/cjs/src/wavesexchange.js +1 -1
  64. package/dist/cjs/src/whitebit.js +1 -0
  65. package/dist/cjs/src/woo.js +56 -0
  66. package/js/ccxt.d.ts +14 -2
  67. package/js/ccxt.js +10 -2
  68. package/js/src/abstract/bitpanda.d.ts +4 -4
  69. package/js/src/abstract/bitstamp.d.ts +8 -0
  70. package/js/src/abstract/gate.d.ts +1 -0
  71. package/js/src/abstract/gateio.d.ts +1 -0
  72. package/js/src/abstract/htx.d.ts +3 -0
  73. package/js/src/abstract/huobi.d.ts +3 -0
  74. package/js/src/abstract/luno.d.ts +1 -0
  75. package/js/src/abstract/onetrading.d.ts +38 -0
  76. package/js/src/ascendex.js +2 -0
  77. package/js/src/base/Exchange.d.ts +2 -3
  78. package/js/src/base/Exchange.js +5 -2
  79. package/js/src/binance.js +7 -1
  80. package/js/src/bingx.d.ts +1 -0
  81. package/js/src/bingx.js +26 -0
  82. package/js/src/bitget.js +22 -3
  83. package/js/src/bitpanda.d.ts +2 -72
  84. package/js/src/bitpanda.js +5 -1991
  85. package/js/src/bitstamp.js +8 -0
  86. package/js/src/bybit.js +21 -47
  87. package/js/src/coincheck.js +1 -0
  88. package/js/src/deribit.js +16 -4
  89. package/js/src/gate.d.ts +1 -0
  90. package/js/src/gate.js +50 -110
  91. package/js/src/htx.js +3 -0
  92. package/js/src/kraken.d.ts +1 -0
  93. package/js/src/kraken.js +40 -39
  94. package/js/src/lbank.js +1 -0
  95. package/js/src/luno.d.ts +3 -1
  96. package/js/src/luno.js +84 -2
  97. package/js/src/mexc.js +1 -2
  98. package/js/src/onetrading.d.ts +74 -0
  99. package/js/src/onetrading.js +2003 -0
  100. package/js/src/poloniexfutures.js +1 -0
  101. package/js/src/pro/binance.js +7 -2
  102. package/js/src/pro/bitget.js +1 -1
  103. package/js/src/pro/bitpanda.d.ts +2 -34
  104. package/js/src/pro/bitpanda.js +5 -1330
  105. package/js/src/pro/coincheck.d.ts +12 -0
  106. package/js/src/pro/coincheck.js +209 -0
  107. package/js/src/pro/kucoin.js +43 -35
  108. package/js/src/pro/kucoinfutures.js +45 -37
  109. package/js/src/pro/lbank.d.ts +29 -0
  110. package/js/src/pro/lbank.js +882 -0
  111. package/js/src/pro/onetrading.d.ts +36 -0
  112. package/js/src/pro/onetrading.js +1339 -0
  113. package/js/src/pro/poloniexfutures.js +43 -35
  114. package/js/src/whitebit.js +1 -0
  115. package/package.json +2 -2
  116. package/rollup.config.js +2 -0
  117. package/skip-tests.json +14 -2
  118. package/test-commonjs.cjs +25 -1
  119. package/dist/cjs/js/ccxt.js +0 -476
  120. package/dist/cjs/js/src/abstract/alpaca.js +0 -9
  121. package/dist/cjs/js/src/abstract/ascendex.js +0 -9
  122. package/dist/cjs/js/src/abstract/bigone.js +0 -9
  123. package/dist/cjs/js/src/abstract/binance.js +0 -9
  124. package/dist/cjs/js/src/abstract/bingx.js +0 -9
  125. package/dist/cjs/js/src/abstract/bit2c.js +0 -9
  126. package/dist/cjs/js/src/abstract/bitbank.js +0 -9
  127. package/dist/cjs/js/src/abstract/bitbns.js +0 -9
  128. package/dist/cjs/js/src/abstract/bitfinex.js +0 -9
  129. package/dist/cjs/js/src/abstract/bitfinex2.js +0 -9
  130. package/dist/cjs/js/src/abstract/bitflyer.js +0 -9
  131. package/dist/cjs/js/src/abstract/bitforex.js +0 -9
  132. package/dist/cjs/js/src/abstract/bitget.js +0 -9
  133. package/dist/cjs/js/src/abstract/bithumb.js +0 -9
  134. package/dist/cjs/js/src/abstract/bitmart.js +0 -9
  135. package/dist/cjs/js/src/abstract/bitmex.js +0 -9
  136. package/dist/cjs/js/src/abstract/bitopro.js +0 -9
  137. package/dist/cjs/js/src/abstract/bitpanda.js +0 -9
  138. package/dist/cjs/js/src/abstract/bitrue.js +0 -9
  139. package/dist/cjs/js/src/abstract/bitso.js +0 -9
  140. package/dist/cjs/js/src/abstract/bitstamp.js +0 -9
  141. package/dist/cjs/js/src/abstract/bitteam.js +0 -9
  142. package/dist/cjs/js/src/abstract/bitvavo.js +0 -9
  143. package/dist/cjs/js/src/abstract/bl3p.js +0 -9
  144. package/dist/cjs/js/src/abstract/blockchaincom.js +0 -9
  145. package/dist/cjs/js/src/abstract/btcalpha.js +0 -9
  146. package/dist/cjs/js/src/abstract/btcbox.js +0 -9
  147. package/dist/cjs/js/src/abstract/btcmarkets.js +0 -9
  148. package/dist/cjs/js/src/abstract/btcturk.js +0 -9
  149. package/dist/cjs/js/src/abstract/bybit.js +0 -9
  150. package/dist/cjs/js/src/abstract/cex.js +0 -9
  151. package/dist/cjs/js/src/abstract/coinbase.js +0 -9
  152. package/dist/cjs/js/src/abstract/coinbasepro.js +0 -9
  153. package/dist/cjs/js/src/abstract/coincheck.js +0 -9
  154. package/dist/cjs/js/src/abstract/coinex.js +0 -9
  155. package/dist/cjs/js/src/abstract/coinlist.js +0 -9
  156. package/dist/cjs/js/src/abstract/coinmate.js +0 -9
  157. package/dist/cjs/js/src/abstract/coinone.js +0 -9
  158. package/dist/cjs/js/src/abstract/coinsph.js +0 -9
  159. package/dist/cjs/js/src/abstract/coinspot.js +0 -9
  160. package/dist/cjs/js/src/abstract/cryptocom.js +0 -9
  161. package/dist/cjs/js/src/abstract/currencycom.js +0 -9
  162. package/dist/cjs/js/src/abstract/delta.js +0 -9
  163. package/dist/cjs/js/src/abstract/deribit.js +0 -9
  164. package/dist/cjs/js/src/abstract/digifinex.js +0 -9
  165. package/dist/cjs/js/src/abstract/exmo.js +0 -9
  166. package/dist/cjs/js/src/abstract/gate.js +0 -9
  167. package/dist/cjs/js/src/abstract/gemini.js +0 -9
  168. package/dist/cjs/js/src/abstract/hitbtc.js +0 -9
  169. package/dist/cjs/js/src/abstract/hollaex.js +0 -9
  170. package/dist/cjs/js/src/abstract/htx.js +0 -9
  171. package/dist/cjs/js/src/abstract/huobijp.js +0 -9
  172. package/dist/cjs/js/src/abstract/idex.js +0 -9
  173. package/dist/cjs/js/src/abstract/independentreserve.js +0 -9
  174. package/dist/cjs/js/src/abstract/indodax.js +0 -9
  175. package/dist/cjs/js/src/abstract/kraken.js +0 -9
  176. package/dist/cjs/js/src/abstract/krakenfutures.js +0 -9
  177. package/dist/cjs/js/src/abstract/kucoin.js +0 -9
  178. package/dist/cjs/js/src/abstract/kucoinfutures.js +0 -9
  179. package/dist/cjs/js/src/abstract/kuna.js +0 -9
  180. package/dist/cjs/js/src/abstract/latoken.js +0 -9
  181. package/dist/cjs/js/src/abstract/lbank.js +0 -9
  182. package/dist/cjs/js/src/abstract/luno.js +0 -9
  183. package/dist/cjs/js/src/abstract/lykke.js +0 -9
  184. package/dist/cjs/js/src/abstract/mercado.js +0 -9
  185. package/dist/cjs/js/src/abstract/mexc.js +0 -9
  186. package/dist/cjs/js/src/abstract/ndax.js +0 -9
  187. package/dist/cjs/js/src/abstract/novadax.js +0 -9
  188. package/dist/cjs/js/src/abstract/oceanex.js +0 -9
  189. package/dist/cjs/js/src/abstract/okcoin.js +0 -9
  190. package/dist/cjs/js/src/abstract/okx.js +0 -9
  191. package/dist/cjs/js/src/abstract/p2b.js +0 -9
  192. package/dist/cjs/js/src/abstract/paymium.js +0 -9
  193. package/dist/cjs/js/src/abstract/phemex.js +0 -9
  194. package/dist/cjs/js/src/abstract/poloniex.js +0 -9
  195. package/dist/cjs/js/src/abstract/poloniexfutures.js +0 -9
  196. package/dist/cjs/js/src/abstract/probit.js +0 -9
  197. package/dist/cjs/js/src/abstract/timex.js +0 -9
  198. package/dist/cjs/js/src/abstract/tokocrypto.js +0 -9
  199. package/dist/cjs/js/src/abstract/upbit.js +0 -9
  200. package/dist/cjs/js/src/abstract/wavesexchange.js +0 -9
  201. package/dist/cjs/js/src/abstract/wazirx.js +0 -9
  202. package/dist/cjs/js/src/abstract/whitebit.js +0 -9
  203. package/dist/cjs/js/src/abstract/woo.js +0 -9
  204. package/dist/cjs/js/src/abstract/yobit.js +0 -9
  205. package/dist/cjs/js/src/abstract/zaif.js +0 -9
  206. package/dist/cjs/js/src/abstract/zonda.js +0 -9
  207. package/dist/cjs/js/src/ace.js +0 -1058
  208. package/dist/cjs/js/src/alpaca.js +0 -1125
  209. package/dist/cjs/js/src/ascendex.js +0 -3365
  210. package/dist/cjs/js/src/base/Exchange.js +0 -5257
  211. package/dist/cjs/js/src/base/Precise.js +0 -263
  212. package/dist/cjs/js/src/base/errors.js +0 -299
  213. package/dist/cjs/js/src/base/functions/crypto.js +0 -78
  214. package/dist/cjs/js/src/base/functions/encode.js +0 -44
  215. package/dist/cjs/js/src/base/functions/generic.js +0 -193
  216. package/dist/cjs/js/src/base/functions/misc.js +0 -96
  217. package/dist/cjs/js/src/base/functions/number.js +0 -297
  218. package/dist/cjs/js/src/base/functions/platform.js +0 -28
  219. package/dist/cjs/js/src/base/functions/rsa.js +0 -34
  220. package/dist/cjs/js/src/base/functions/string.js +0 -48
  221. package/dist/cjs/js/src/base/functions/throttle.js +0 -66
  222. package/dist/cjs/js/src/base/functions/time.js +0 -187
  223. package/dist/cjs/js/src/base/functions/totp.js +0 -24
  224. package/dist/cjs/js/src/base/functions/type.js +0 -162
  225. package/dist/cjs/js/src/base/functions.js +0 -157
  226. package/dist/cjs/js/src/base/ws/Cache.js +0 -254
  227. package/dist/cjs/js/src/base/ws/Client.js +0 -299
  228. package/dist/cjs/js/src/base/ws/Future.js +0 -34
  229. package/dist/cjs/js/src/base/ws/OrderBook.js +0 -107
  230. package/dist/cjs/js/src/base/ws/OrderBookSide.js +0 -281
  231. package/dist/cjs/js/src/base/ws/WsClient.js +0 -69
  232. package/dist/cjs/js/src/bequant.js +0 -33
  233. package/dist/cjs/js/src/bigone.js +0 -2213
  234. package/dist/cjs/js/src/binance.js +0 -9845
  235. package/dist/cjs/js/src/binancecoinm.js +0 -45
  236. package/dist/cjs/js/src/binanceus.js +0 -92
  237. package/dist/cjs/js/src/binanceusdm.js +0 -58
  238. package/dist/cjs/js/src/bingx.js +0 -3846
  239. package/dist/cjs/js/src/bit2c.js +0 -916
  240. package/dist/cjs/js/src/bitbank.js +0 -1000
  241. package/dist/cjs/js/src/bitbay.js +0 -17
  242. package/dist/cjs/js/src/bitbns.js +0 -1220
  243. package/dist/cjs/js/src/bitcoincom.js +0 -17
  244. package/dist/cjs/js/src/bitfinex.js +0 -1670
  245. package/dist/cjs/js/src/bitfinex2.js +0 -2990
  246. package/dist/cjs/js/src/bitflyer.js +0 -1045
  247. package/dist/cjs/js/src/bitforex.js +0 -852
  248. package/dist/cjs/js/src/bitget.js +0 -8295
  249. package/dist/cjs/js/src/bithumb.js +0 -1090
  250. package/dist/cjs/js/src/bitmart.js +0 -4454
  251. package/dist/cjs/js/src/bitmex.js +0 -2881
  252. package/dist/cjs/js/src/bitopro.js +0 -1724
  253. package/dist/cjs/js/src/bitrue.js +0 -3253
  254. package/dist/cjs/js/src/bitso.js +0 -1753
  255. package/dist/cjs/js/src/bitstamp.js +0 -2188
  256. package/dist/cjs/js/src/bitteam.js +0 -2309
  257. package/dist/cjs/js/src/bitvavo.js +0 -1968
  258. package/dist/cjs/js/src/bl3p.js +0 -447
  259. package/dist/cjs/js/src/blockchaincom.js +0 -1160
  260. package/dist/cjs/js/src/btcalpha.js +0 -929
  261. package/dist/cjs/js/src/btcbox.js +0 -565
  262. package/dist/cjs/js/src/btcmarkets.js +0 -1237
  263. package/dist/cjs/js/src/btcturk.js +0 -929
  264. package/dist/cjs/js/src/bybit.js +0 -7650
  265. package/dist/cjs/js/src/cex.js +0 -1693
  266. package/dist/cjs/js/src/coinbase.js +0 -3424
  267. package/dist/cjs/js/src/coinbasepro.js +0 -1866
  268. package/dist/cjs/js/src/coincheck.js +0 -843
  269. package/dist/cjs/js/src/coinex.js +0 -5417
  270. package/dist/cjs/js/src/coinlist.js +0 -2337
  271. package/dist/cjs/js/src/coinmate.js +0 -989
  272. package/dist/cjs/js/src/coinone.js +0 -1185
  273. package/dist/cjs/js/src/coinsph.js +0 -1933
  274. package/dist/cjs/js/src/coinspot.js +0 -548
  275. package/dist/cjs/js/src/cryptocom.js +0 -3007
  276. package/dist/cjs/js/src/currencycom.js +0 -2015
  277. package/dist/cjs/js/src/delta.js +0 -3262
  278. package/dist/cjs/js/src/deribit.js +0 -3306
  279. package/dist/cjs/js/src/digifinex.js +0 -4307
  280. package/dist/cjs/js/src/exmo.js +0 -2645
  281. package/dist/cjs/js/src/fmfwio.js +0 -34
  282. package/dist/cjs/js/src/gate.js +0 -7077
  283. package/dist/cjs/js/src/gateio.js +0 -16
  284. package/dist/cjs/js/src/gemini.js +0 -1801
  285. package/dist/cjs/js/src/hitbtc.js +0 -3660
  286. package/dist/cjs/js/src/hitbtc3.js +0 -19
  287. package/dist/cjs/js/src/hollaex.js +0 -1882
  288. package/dist/cjs/js/src/htx.js +0 -9174
  289. package/dist/cjs/js/src/huobi.js +0 -16
  290. package/dist/cjs/js/src/huobijp.js +0 -1918
  291. package/dist/cjs/js/src/idex.js +0 -1770
  292. package/dist/cjs/js/src/independentreserve.js +0 -761
  293. package/dist/cjs/js/src/indodax.js +0 -1069
  294. package/dist/cjs/js/src/kraken.js +0 -2891
  295. package/dist/cjs/js/src/krakenfutures.js +0 -2407
  296. package/dist/cjs/js/src/kucoin.js +0 -4494
  297. package/dist/cjs/js/src/kucoinfutures.js +0 -2529
  298. package/dist/cjs/js/src/kuna.js +0 -1949
  299. package/dist/cjs/js/src/latoken.js +0 -1729
  300. package/dist/cjs/js/src/lbank.js +0 -2851
  301. package/dist/cjs/js/src/luno.js +0 -1044
  302. package/dist/cjs/js/src/lykke.js +0 -1303
  303. package/dist/cjs/js/src/mercado.js +0 -897
  304. package/dist/cjs/js/src/mexc.js +0 -5407
  305. package/dist/cjs/js/src/ndax.js +0 -2450
  306. package/dist/cjs/js/src/novadax.js +0 -1556
  307. package/dist/cjs/js/src/oceanex.js +0 -964
  308. package/dist/cjs/js/src/okcoin.js +0 -3115
  309. package/dist/cjs/js/src/okx.js +0 -7331
  310. package/dist/cjs/js/src/p2b.js +0 -1243
  311. package/dist/cjs/js/src/paymium.js +0 -597
  312. package/dist/cjs/js/src/phemex.js +0 -4725
  313. package/dist/cjs/js/src/poloniex.js +0 -2356
  314. package/dist/cjs/js/src/poloniexfutures.js +0 -1794
  315. package/dist/cjs/js/src/pro/alpaca.js +0 -714
  316. package/dist/cjs/js/src/pro/ascendex.js +0 -957
  317. package/dist/cjs/js/src/pro/bequant.js +0 -33
  318. package/dist/cjs/js/src/pro/binance.js +0 -2796
  319. package/dist/cjs/js/src/pro/binancecoinm.js +0 -23
  320. package/dist/cjs/js/src/pro/binanceus.js +0 -51
  321. package/dist/cjs/js/src/pro/binanceusdm.js +0 -32
  322. package/dist/cjs/js/src/pro/bingx.js +0 -944
  323. package/dist/cjs/js/src/pro/bitcoincom.js +0 -29
  324. package/dist/cjs/js/src/pro/bitfinex.js +0 -672
  325. package/dist/cjs/js/src/pro/bitfinex2.js +0 -1159
  326. package/dist/cjs/js/src/pro/bitget.js +0 -1733
  327. package/dist/cjs/js/src/pro/bitmart.js +0 -1486
  328. package/dist/cjs/js/src/pro/bitmex.js +0 -1576
  329. package/dist/cjs/js/src/pro/bitopro.js +0 -327
  330. package/dist/cjs/js/src/pro/bitrue.js +0 -462
  331. package/dist/cjs/js/src/pro/bitstamp.js +0 -547
  332. package/dist/cjs/js/src/pro/bitvavo.js +0 -704
  333. package/dist/cjs/js/src/pro/blockchaincom.js +0 -794
  334. package/dist/cjs/js/src/pro/bybit.js +0 -1843
  335. package/dist/cjs/js/src/pro/cex.js +0 -1510
  336. package/dist/cjs/js/src/pro/coinbase.js +0 -561
  337. package/dist/cjs/js/src/pro/coinbasepro.js +0 -968
  338. package/dist/cjs/js/src/pro/coinex.js +0 -1095
  339. package/dist/cjs/js/src/pro/cryptocom.js +0 -1020
  340. package/dist/cjs/js/src/pro/currencycom.js +0 -563
  341. package/dist/cjs/js/src/pro/deribit.js +0 -825
  342. package/dist/cjs/js/src/pro/exmo.js +0 -658
  343. package/dist/cjs/js/src/pro/gate.js +0 -1316
  344. package/dist/cjs/js/src/pro/gateio.js +0 -16
  345. package/dist/cjs/js/src/pro/gemini.js +0 -649
  346. package/dist/cjs/js/src/pro/hitbtc.js +0 -1294
  347. package/dist/cjs/js/src/pro/hollaex.js +0 -597
  348. package/dist/cjs/js/src/pro/htx.js +0 -2388
  349. package/dist/cjs/js/src/pro/huobi.js +0 -16
  350. package/dist/cjs/js/src/pro/huobijp.js +0 -606
  351. package/dist/cjs/js/src/pro/idex.js +0 -714
  352. package/dist/cjs/js/src/pro/independentreserve.js +0 -280
  353. package/dist/cjs/js/src/pro/kraken.js +0 -1364
  354. package/dist/cjs/js/src/pro/krakenfutures.js +0 -1506
  355. package/dist/cjs/js/src/pro/kucoin.js +0 -1054
  356. package/dist/cjs/js/src/pro/kucoinfutures.js +0 -981
  357. package/dist/cjs/js/src/pro/luno.js +0 -322
  358. package/dist/cjs/js/src/pro/mexc.js +0 -1170
  359. package/dist/cjs/js/src/pro/ndax.js +0 -545
  360. package/dist/cjs/js/src/pro/okcoin.js +0 -760
  361. package/dist/cjs/js/src/pro/okx.js +0 -1608
  362. package/dist/cjs/js/src/pro/phemex.js +0 -1511
  363. package/dist/cjs/js/src/pro/poloniex.js +0 -1253
  364. package/dist/cjs/js/src/pro/poloniexfutures.js +0 -1014
  365. package/dist/cjs/js/src/pro/probit.js +0 -586
  366. package/dist/cjs/js/src/pro/upbit.js +0 -234
  367. package/dist/cjs/js/src/pro/wazirx.js +0 -776
  368. package/dist/cjs/js/src/pro/whitebit.js +0 -927
  369. package/dist/cjs/js/src/pro/woo.js +0 -895
  370. package/dist/cjs/js/src/probit.js +0 -1867
  371. package/dist/cjs/js/src/static_dependencies/fflake/browser.js +0 -401
  372. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncrypt.js +0 -195
  373. package/dist/cjs/js/src/static_dependencies/jsencrypt/JSEncryptRSAKey.js +0 -308
  374. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/asn1.js +0 -554
  375. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/base64.js +0 -94
  376. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/hex.js +0 -70
  377. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/asn1js/int10.js +0 -91
  378. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/base64.js +0 -16
  379. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/jsbn.js +0 -1760
  380. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/prng4.js +0 -52
  381. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rng.js +0 -81
  382. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/rsa.js +0 -376
  383. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsbn/util.js +0 -70
  384. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/asn1-1.0.js +0 -1580
  385. package/dist/cjs/js/src/static_dependencies/jsencrypt/lib/jsrsasign/yahoo.js +0 -74
  386. package/dist/cjs/js/src/static_dependencies/noble-curves/_shortw_utils.js +0 -24
  387. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/curve.js +0 -158
  388. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/edwards.js +0 -429
  389. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/hash-to-curve.js +0 -176
  390. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/modular.js +0 -324
  391. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/montgomery.js +0 -163
  392. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/utils.js +0 -245
  393. package/dist/cjs/js/src/static_dependencies/noble-curves/abstract/weierstrass.js +0 -1018
  394. package/dist/cjs/js/src/static_dependencies/noble-curves/ed25519.js +0 -383
  395. package/dist/cjs/js/src/static_dependencies/noble-curves/secp256k1.js +0 -258
  396. package/dist/cjs/js/src/static_dependencies/noble-hashes/_assert.js +0 -53
  397. package/dist/cjs/js/src/static_dependencies/noble-hashes/_sha2.js +0 -120
  398. package/dist/cjs/js/src/static_dependencies/noble-hashes/_u64.js +0 -69
  399. package/dist/cjs/js/src/static_dependencies/noble-hashes/crypto.js +0 -7
  400. package/dist/cjs/js/src/static_dependencies/noble-hashes/hmac.js +0 -83
  401. package/dist/cjs/js/src/static_dependencies/noble-hashes/md5.js +0 -240
  402. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha1.js +0 -91
  403. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha256.js +0 -130
  404. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha3.js +0 -214
  405. package/dist/cjs/js/src/static_dependencies/noble-hashes/sha512.js +0 -239
  406. package/dist/cjs/js/src/static_dependencies/noble-hashes/utils.js +0 -93
  407. package/dist/cjs/js/src/static_dependencies/node-fetch/body.js +0 -354
  408. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/abort-error.js +0 -16
  409. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/base.js +0 -20
  410. package/dist/cjs/js/src/static_dependencies/node-fetch/errors/fetch-error.js +0 -30
  411. package/dist/cjs/js/src/static_dependencies/node-fetch/headers.js +0 -239
  412. package/dist/cjs/js/src/static_dependencies/node-fetch/index.js +0 -372
  413. package/dist/cjs/js/src/static_dependencies/node-fetch/request.js +0 -273
  414. package/dist/cjs/js/src/static_dependencies/node-fetch/response.js +0 -139
  415. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/get-search.js +0 -14
  416. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is-redirect.js +0 -16
  417. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/is.js +0 -81
  418. package/dist/cjs/js/src/static_dependencies/node-fetch/utils/referrer.js +0 -292
  419. package/dist/cjs/js/src/static_dependencies/proxies/agent-base/index.js +0 -103
  420. package/dist/cjs/js/src/static_dependencies/proxies/http-proxy-agent/index.js +0 -140
  421. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/index.js +0 -175
  422. package/dist/cjs/js/src/static_dependencies/proxies/https-proxy-agent/parse-proxy-response.js +0 -95
  423. package/dist/cjs/js/src/static_dependencies/qs/index.cjs.js +0 -7
  424. package/dist/cjs/js/src/static_dependencies/scure-base/index.js +0 -383
  425. package/dist/cjs/js/src/timex.js +0 -1562
  426. package/dist/cjs/js/src/tokocrypto.js +0 -2542
  427. package/dist/cjs/js/src/upbit.js +0 -1844
  428. package/dist/cjs/js/src/wavesexchange.js +0 -2607
  429. package/dist/cjs/js/src/wazirx.js +0 -953
  430. package/dist/cjs/js/src/whitebit.js +0 -2309
  431. package/dist/cjs/js/src/woo.js +0 -2769
  432. package/dist/cjs/js/src/yobit.js +0 -1314
  433. package/dist/cjs/js/src/zaif.js +0 -736
  434. package/dist/cjs/js/src/zonda.js +0 -1883
  435. package/dist/cjs/src/abstract/bitpanda.js +0 -9
  436. package/test.ts +0 -0
  437. /package/dist/cjs/{js/src/abstract/ace.js → src/abstract/onetrading.js} +0 -0
  438. /package/dist/cjs/{js/src → src}/pro/coinone.js +0 -0
  439. /package/js/src/abstract/{bitpanda.js → onetrading.js} +0 -0
@@ -1,3424 +0,0 @@
1
- 'use strict';
2
-
3
- var coinbase$1 = require('./abstract/coinbase.js');
4
- var errors = require('./base/errors.js');
5
- var Precise = require('./base/Precise.js');
6
- var number = require('./base/functions/number.js');
7
- var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
8
-
9
- // ----------------------------------------------------------------------------
10
- // ----------------------------------------------------------------------------
11
- /**
12
- * @class coinbase
13
- * @augments Exchange
14
- */
15
- class coinbase extends coinbase$1 {
16
- describe() {
17
- return this.deepExtend(super.describe(), {
18
- 'id': 'coinbase',
19
- 'name': 'Coinbase',
20
- 'countries': ['US'],
21
- 'pro': true,
22
- 'rateLimit': 400,
23
- 'version': 'v2',
24
- 'userAgent': this.userAgents['chrome'],
25
- 'headers': {
26
- 'CB-VERSION': '2018-05-30',
27
- },
28
- 'has': {
29
- 'CORS': true,
30
- 'spot': true,
31
- 'margin': false,
32
- 'swap': false,
33
- 'future': false,
34
- 'option': false,
35
- 'addMargin': false,
36
- 'cancelOrder': true,
37
- 'cancelOrders': true,
38
- 'closeAllPositions': false,
39
- 'closePosition': false,
40
- 'createDepositAddress': true,
41
- 'createLimitBuyOrder': true,
42
- 'createLimitSellOrder': true,
43
- 'createMarketBuyOrder': true,
44
- 'createMarketBuyOrderWithCost': true,
45
- 'createMarketOrderWithCost': false,
46
- 'createMarketSellOrder': true,
47
- 'createMarketSellOrderWithCost': false,
48
- 'createOrder': true,
49
- 'createPostOnlyOrder': true,
50
- 'createReduceOnlyOrder': false,
51
- 'createStopLimitOrder': true,
52
- 'createStopMarketOrder': false,
53
- 'createStopOrder': true,
54
- 'editOrder': true,
55
- 'fetchAccounts': true,
56
- 'fetchBalance': true,
57
- 'fetchBidsAsks': true,
58
- 'fetchBorrowRateHistories': false,
59
- 'fetchBorrowRateHistory': false,
60
- 'fetchCanceledOrders': true,
61
- 'fetchClosedOrders': true,
62
- 'fetchCrossBorrowRate': false,
63
- 'fetchCrossBorrowRates': false,
64
- 'fetchCurrencies': true,
65
- 'fetchDeposits': true,
66
- 'fetchFundingHistory': false,
67
- 'fetchFundingRate': false,
68
- 'fetchFundingRateHistory': false,
69
- 'fetchFundingRates': false,
70
- 'fetchIndexOHLCV': false,
71
- 'fetchIsolatedBorrowRate': false,
72
- 'fetchIsolatedBorrowRates': false,
73
- 'fetchL2OrderBook': false,
74
- 'fetchLedger': true,
75
- 'fetchLeverage': false,
76
- 'fetchLeverageTiers': false,
77
- 'fetchMarginMode': false,
78
- 'fetchMarkets': true,
79
- 'fetchMarkOHLCV': false,
80
- 'fetchMyBuys': true,
81
- 'fetchMySells': true,
82
- 'fetchMyTrades': true,
83
- 'fetchOHLCV': true,
84
- 'fetchOpenInterestHistory': false,
85
- 'fetchOpenOrders': true,
86
- 'fetchOrder': true,
87
- 'fetchOrderBook': true,
88
- 'fetchOrders': true,
89
- 'fetchPosition': false,
90
- 'fetchPositionMode': false,
91
- 'fetchPositions': false,
92
- 'fetchPositionsRisk': false,
93
- 'fetchPremiumIndexOHLCV': false,
94
- 'fetchTicker': true,
95
- 'fetchTickers': true,
96
- 'fetchTime': true,
97
- 'fetchTrades': true,
98
- 'fetchTradingFee': false,
99
- 'fetchTradingFees': false,
100
- 'fetchWithdrawals': true,
101
- 'reduceMargin': false,
102
- 'setLeverage': false,
103
- 'setMarginMode': false,
104
- 'setPositionMode': false,
105
- 'withdraw': true,
106
- },
107
- 'urls': {
108
- 'logo': 'https://user-images.githubusercontent.com/1294454/40811661-b6eceae2-653a-11e8-829e-10bfadb078cf.jpg',
109
- 'api': {
110
- 'rest': 'https://api.coinbase.com',
111
- },
112
- 'www': 'https://www.coinbase.com',
113
- 'doc': [
114
- 'https://developers.coinbase.com/api/v2',
115
- 'https://docs.cloud.coinbase.com/advanced-trade-api/docs/welcome',
116
- ],
117
- 'fees': [
118
- 'https://support.coinbase.com/customer/portal/articles/2109597-buy-sell-bank-transfer-fees',
119
- 'https://www.coinbase.com/advanced-fees',
120
- ],
121
- 'referral': 'https://www.coinbase.com/join/58cbe25a355148797479dbd2',
122
- },
123
- 'requiredCredentials': {
124
- 'apiKey': true,
125
- 'secret': true,
126
- },
127
- 'api': {
128
- 'v2': {
129
- 'public': {
130
- 'get': [
131
- 'currencies',
132
- 'time',
133
- 'exchange-rates',
134
- 'users/{user_id}',
135
- 'prices/{symbol}/buy',
136
- 'prices/{symbol}/sell',
137
- 'prices/{symbol}/spot',
138
- ],
139
- },
140
- 'private': {
141
- 'get': [
142
- 'accounts',
143
- 'accounts/{account_id}',
144
- 'accounts/{account_id}/addresses',
145
- 'accounts/{account_id}/addresses/{address_id}',
146
- 'accounts/{account_id}/addresses/{address_id}/transactions',
147
- 'accounts/{account_id}/transactions',
148
- 'accounts/{account_id}/transactions/{transaction_id}',
149
- 'accounts/{account_id}/buys',
150
- 'accounts/{account_id}/buys/{buy_id}',
151
- 'accounts/{account_id}/sells',
152
- 'accounts/{account_id}/sells/{sell_id}',
153
- 'accounts/{account_id}/deposits',
154
- 'accounts/{account_id}/deposits/{deposit_id}',
155
- 'accounts/{account_id}/withdrawals',
156
- 'accounts/{account_id}/withdrawals/{withdrawal_id}',
157
- 'payment-methods',
158
- 'payment-methods/{payment_method_id}',
159
- 'user',
160
- 'user/auth',
161
- ],
162
- 'post': [
163
- 'accounts',
164
- 'accounts/{account_id}/primary',
165
- 'accounts/{account_id}/addresses',
166
- 'accounts/{account_id}/transactions',
167
- 'accounts/{account_id}/transactions/{transaction_id}/complete',
168
- 'accounts/{account_id}/transactions/{transaction_id}/resend',
169
- 'accounts/{account_id}/buys',
170
- 'accounts/{account_id}/buys/{buy_id}/commit',
171
- 'accounts/{account_id}/sells',
172
- 'accounts/{account_id}/sells/{sell_id}/commit',
173
- 'accounts/{account_id}/deposits',
174
- 'accounts/{account_id}/deposits/{deposit_id}/commit',
175
- 'accounts/{account_id}/withdrawals',
176
- 'accounts/{account_id}/withdrawals/{withdrawal_id}/commit',
177
- ],
178
- 'put': [
179
- 'accounts/{account_id}',
180
- 'user',
181
- ],
182
- 'delete': [
183
- 'accounts/{id}',
184
- 'accounts/{account_id}/transactions/{transaction_id}',
185
- ],
186
- },
187
- },
188
- 'v3': {
189
- 'private': {
190
- 'get': [
191
- 'brokerage/accounts',
192
- 'brokerage/accounts/{account_uuid}',
193
- 'brokerage/orders/historical/batch',
194
- 'brokerage/orders/historical/fills',
195
- 'brokerage/orders/historical/{order_id}',
196
- 'brokerage/products',
197
- 'brokerage/products/{product_id}',
198
- 'brokerage/products/{product_id}/candles',
199
- 'brokerage/products/{product_id}/ticker',
200
- 'brokerage/portfolios',
201
- 'brokerage/portfolios/{portfolio_uuid}',
202
- 'brokerage/transaction_summary',
203
- 'brokerage/product_book',
204
- 'brokerage/best_bid_ask',
205
- 'brokerage/convert/trade/{trade_id}',
206
- 'brokerage/time',
207
- ],
208
- 'post': [
209
- 'brokerage/orders',
210
- 'brokerage/orders/batch_cancel',
211
- 'brokerage/orders/edit',
212
- 'brokerage/orders/edit_preview',
213
- 'brokerage/portfolios',
214
- 'brokerage/portfolios/move_funds',
215
- 'brokerage/convert/quote',
216
- 'brokerage/convert/trade/{trade_id}',
217
- ],
218
- 'put': [
219
- 'brokerage/portfolios/{portfolio_uuid}',
220
- ],
221
- 'delete': [
222
- 'brokerage/portfolios/{portfolio_uuid}',
223
- ],
224
- },
225
- },
226
- },
227
- 'fees': {
228
- 'trading': {
229
- 'taker': this.parseNumber('0.006'),
230
- 'maker': this.parseNumber('0.004'),
231
- 'tierBased': true,
232
- 'percentage': true,
233
- 'tiers': {
234
- 'taker': [
235
- [this.parseNumber('0'), this.parseNumber('0.006')],
236
- [this.parseNumber('10000'), this.parseNumber('0.004')],
237
- [this.parseNumber('50000'), this.parseNumber('0.0025')],
238
- [this.parseNumber('100000'), this.parseNumber('0.002')],
239
- [this.parseNumber('1000000'), this.parseNumber('0.0018')],
240
- [this.parseNumber('15000000'), this.parseNumber('0.0016')],
241
- [this.parseNumber('75000000'), this.parseNumber('0.0012')],
242
- [this.parseNumber('250000000'), this.parseNumber('0.0008')],
243
- [this.parseNumber('400000000'), this.parseNumber('0.0005')],
244
- ],
245
- 'maker': [
246
- [this.parseNumber('0'), this.parseNumber('0.004')],
247
- [this.parseNumber('10000'), this.parseNumber('0.0025')],
248
- [this.parseNumber('50000'), this.parseNumber('0.0015')],
249
- [this.parseNumber('100000'), this.parseNumber('0.001')],
250
- [this.parseNumber('1000000'), this.parseNumber('0.0008')],
251
- [this.parseNumber('15000000'), this.parseNumber('0.0006')],
252
- [this.parseNumber('75000000'), this.parseNumber('0.0003')],
253
- [this.parseNumber('250000000'), this.parseNumber('0.0')],
254
- [this.parseNumber('400000000'), this.parseNumber('0.0')],
255
- ],
256
- },
257
- },
258
- },
259
- 'precisionMode': number.TICK_SIZE,
260
- 'exceptions': {
261
- 'exact': {
262
- 'two_factor_required': errors.AuthenticationError,
263
- 'param_required': errors.ExchangeError,
264
- 'validation_error': errors.ExchangeError,
265
- 'invalid_request': errors.ExchangeError,
266
- 'personal_details_required': errors.AuthenticationError,
267
- 'identity_verification_required': errors.AuthenticationError,
268
- 'jumio_verification_required': errors.AuthenticationError,
269
- 'jumio_face_match_verification_required': errors.AuthenticationError,
270
- 'unverified_email': errors.AuthenticationError,
271
- 'authentication_error': errors.AuthenticationError,
272
- 'invalid_authentication_method': errors.AuthenticationError,
273
- 'invalid_token': errors.AuthenticationError,
274
- 'revoked_token': errors.AuthenticationError,
275
- 'expired_token': errors.AuthenticationError,
276
- 'invalid_scope': errors.AuthenticationError,
277
- 'not_found': errors.ExchangeError,
278
- 'rate_limit_exceeded': errors.RateLimitExceeded,
279
- 'internal_server_error': errors.ExchangeError,
280
- 'UNSUPPORTED_ORDER_CONFIGURATION': errors.BadRequest,
281
- 'INSUFFICIENT_FUND': errors.BadRequest,
282
- },
283
- 'broad': {
284
- 'request timestamp expired': errors.InvalidNonce,
285
- 'order with this orderID was not found': errors.OrderNotFound, // {"error":"unknown","error_details":"order with this orderID was not found","message":"order with this orderID was not found"}
286
- },
287
- },
288
- 'timeframes': {
289
- '1m': 'ONE_MINUTE',
290
- '5m': 'FIVE_MINUTE',
291
- '15m': 'FIFTEEN_MINUTE',
292
- '30m': 'THIRTY_MINUTE',
293
- '1h': 'ONE_HOUR',
294
- '2h': 'TWO_HOUR',
295
- '6h': 'SIX_HOUR',
296
- '1d': 'ONE_DAY',
297
- },
298
- 'commonCurrencies': {
299
- 'CGLD': 'CELO',
300
- },
301
- 'options': {
302
- 'stablePairs': ['BUSD-USD', 'CBETH-ETH', 'DAI-USD', 'GUSD-USD', 'GYEN-USD', 'PAX-USD', 'PAX-USDT', 'USDC-EUR', 'USDC-GBP', 'USDT-EUR', 'USDT-GBP', 'USDT-USD', 'USDT-USDC', 'WBTC-BTC'],
303
- 'fetchCurrencies': {
304
- 'expires': 5000,
305
- },
306
- 'accounts': [
307
- 'wallet',
308
- 'fiat',
309
- // 'vault',
310
- ],
311
- 'v3Accounts': [
312
- 'ACCOUNT_TYPE_CRYPTO',
313
- 'ACCOUNT_TYPE_FIAT',
314
- ],
315
- 'createMarketBuyOrderRequiresPrice': true,
316
- 'advanced': true,
317
- 'fetchMarkets': 'fetchMarketsV3',
318
- 'fetchTicker': 'fetchTickerV3',
319
- 'fetchTickers': 'fetchTickersV3',
320
- 'fetchAccounts': 'fetchAccountsV3',
321
- 'fetchBalance': 'v2PrivateGetAccounts',
322
- 'user_native_currency': 'USD', // needed to get fees for v3
323
- },
324
- });
325
- }
326
- async fetchTime(params = {}) {
327
- /**
328
- * @method
329
- * @name coinbase#fetchTime
330
- * @description fetches the current integer timestamp in milliseconds from the exchange server
331
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request
332
- * @param {object} [params] extra parameters specific to the exchange API endpoint
333
- * @returns {int} the current integer timestamp in milliseconds from the exchange server
334
- */
335
- const response = await this.v2PublicGetTime(params);
336
- //
337
- // {
338
- // "data": {
339
- // "epoch": 1589295679,
340
- // "iso": "2020-05-12T15:01:19Z"
341
- // }
342
- // }
343
- //
344
- const data = this.safeValue(response, 'data', {});
345
- return this.safeTimestamp(data, 'epoch');
346
- }
347
- async fetchAccounts(params = {}) {
348
- /**
349
- * @method
350
- * @name coinbase#fetchAccounts
351
- * @description fetch all the accounts associated with a profile
352
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getaccounts
353
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
354
- * @param {object} [params] extra parameters specific to the exchange API endpoint
355
- * @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)
356
- * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
357
- */
358
- const method = this.safeString(this.options, 'fetchAccounts', 'fetchAccountsV3');
359
- if (method === 'fetchAccountsV3') {
360
- return await this.fetchAccountsV3(params);
361
- }
362
- return await this.fetchAccountsV2(params);
363
- }
364
- async fetchAccountsV2(params = {}) {
365
- await this.loadMarkets();
366
- let paginate = false;
367
- [paginate, params] = this.handleOptionAndParams(params, 'fetchAccounts', 'paginate');
368
- if (paginate) {
369
- return await this.fetchPaginatedCallCursor('fetchAccounts', undefined, undefined, undefined, params, 'next_starting_after', 'starting_after', undefined, 100);
370
- }
371
- const request = {
372
- 'limit': 100,
373
- };
374
- const response = await this.v2PrivateGetAccounts(this.extend(request, params));
375
- //
376
- // {
377
- // "pagination": {
378
- // "ending_before": null,
379
- // "starting_after": null,
380
- // "previous_ending_before": null,
381
- // "next_starting_after": null,
382
- // "limit": 244,
383
- // "order": "desc",
384
- // "previous_uri": null,
385
- // "next_uri": null
386
- // },
387
- // "data": [
388
- // {
389
- // "id": "XLM",
390
- // "name": "XLM Wallet",
391
- // "primary": false,
392
- // "type": "wallet",
393
- // "currency": {
394
- // "code": "XLM",
395
- // "name": "Stellar Lumens",
396
- // "color": "#000000",
397
- // "sort_index": 127,
398
- // "exponent": 7,
399
- // "type": "crypto",
400
- // "address_regex": "^G[A-Z2-7]{55}$",
401
- // "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f",
402
- // "destination_tag_name": "XLM Memo ID",
403
- // "destination_tag_regex": "^[ -~]{1,28}$"
404
- // },
405
- // "balance": {
406
- // "amount": "0.0000000",
407
- // "currency": "XLM"
408
- // },
409
- // "created_at": null,
410
- // "updated_at": null,
411
- // "resource": "account",
412
- // "resource_path": "/v2/accounts/XLM",
413
- // "allow_deposits": true,
414
- // "allow_withdrawals": true
415
- // },
416
- // ]
417
- // }
418
- //
419
- const data = this.safeValue(response, 'data', []);
420
- const pagination = this.safeValue(response, 'pagination', {});
421
- const cursor = this.safeString(pagination, 'next_starting_after');
422
- const accounts = this.safeValue(response, 'data', []);
423
- const lastIndex = accounts.length - 1;
424
- const last = this.safeValue(accounts, lastIndex);
425
- if ((cursor !== undefined) && (cursor !== '')) {
426
- last['next_starting_after'] = cursor;
427
- accounts[lastIndex] = last;
428
- }
429
- return this.parseAccounts(data, params);
430
- }
431
- async fetchAccountsV3(params = {}) {
432
- await this.loadMarkets();
433
- let paginate = false;
434
- [paginate, params] = this.handleOptionAndParams(params, 'fetchAccounts', 'paginate');
435
- if (paginate) {
436
- return await this.fetchPaginatedCallCursor('fetchAccounts', undefined, undefined, undefined, params, 'cursor', 'cursor', undefined, 100);
437
- }
438
- const request = {
439
- 'limit': 100,
440
- };
441
- const response = await this.v3PrivateGetBrokerageAccounts(this.extend(request, params));
442
- //
443
- // {
444
- // "accounts": [
445
- // {
446
- // "uuid": "11111111-1111-1111-1111-111111111111",
447
- // "name": "USDC Wallet",
448
- // "currency": "USDC",
449
- // "available_balance": {
450
- // "value": "0.0000000000000000",
451
- // "currency": "USDC"
452
- // },
453
- // "default": true,
454
- // "active": true,
455
- // "created_at": "2023-01-04T06:20:06.456Z",
456
- // "updated_at": "2023-01-04T06:20:07.181Z",
457
- // "deleted_at": null,
458
- // "type": "ACCOUNT_TYPE_CRYPTO",
459
- // "ready": false,
460
- // "hold": {
461
- // "value": "0.0000000000000000",
462
- // "currency": "USDC"
463
- // }
464
- // },
465
- // ...
466
- // ],
467
- // "has_next": false,
468
- // "cursor": "",
469
- // "size": 9
470
- // }
471
- //
472
- const accounts = this.safeValue(response, 'accounts', []);
473
- const lastIndex = accounts.length - 1;
474
- const last = this.safeValue(accounts, lastIndex);
475
- const cursor = this.safeString(response, 'cursor');
476
- if ((cursor !== undefined) && (cursor !== '')) {
477
- last['cursor'] = cursor;
478
- accounts[lastIndex] = last;
479
- }
480
- return this.parseAccounts(accounts, params);
481
- }
482
- parseAccount(account) {
483
- //
484
- // fetchAccountsV2
485
- //
486
- // {
487
- // "id": "XLM",
488
- // "name": "XLM Wallet",
489
- // "primary": false,
490
- // "type": "wallet",
491
- // "currency": {
492
- // "code": "XLM",
493
- // "name": "Stellar Lumens",
494
- // "color": "#000000",
495
- // "sort_index": 127,
496
- // "exponent": 7,
497
- // "type": "crypto",
498
- // "address_regex": "^G[A-Z2-7]{55}$",
499
- // "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f",
500
- // "destination_tag_name": "XLM Memo ID",
501
- // "destination_tag_regex": "^[ -~]{1,28}$"
502
- // },
503
- // "balance": {
504
- // "amount": "0.0000000",
505
- // "currency": "XLM"
506
- // },
507
- // "created_at": null,
508
- // "updated_at": null,
509
- // "resource": "account",
510
- // "resource_path": "/v2/accounts/XLM",
511
- // "allow_deposits": true,
512
- // "allow_withdrawals": true
513
- // }
514
- //
515
- // fetchAccountsV3
516
- //
517
- // {
518
- // "uuid": "11111111-1111-1111-1111-111111111111",
519
- // "name": "USDC Wallet",
520
- // "currency": "USDC",
521
- // "available_balance": {
522
- // "value": "0.0000000000000000",
523
- // "currency": "USDC"
524
- // },
525
- // "default": true,
526
- // "active": true,
527
- // "created_at": "2023-01-04T06:20:06.456Z",
528
- // "updated_at": "2023-01-04T06:20:07.181Z",
529
- // "deleted_at": null,
530
- // "type": "ACCOUNT_TYPE_CRYPTO",
531
- // "ready": false,
532
- // "hold": {
533
- // "value": "0.0000000000000000",
534
- // "currency": "USDC"
535
- // }
536
- // }
537
- //
538
- const active = this.safeValue(account, 'active');
539
- const currencyIdV3 = this.safeString(account, 'currency');
540
- const currency = this.safeValue(account, 'currency', {});
541
- const currencyId = this.safeString(currency, 'code', currencyIdV3);
542
- const typeV3 = this.safeString(account, 'name');
543
- const typeV2 = this.safeString(account, 'type');
544
- const parts = typeV3.split(' ');
545
- return {
546
- 'id': this.safeString2(account, 'id', 'uuid'),
547
- 'type': (active !== undefined) ? this.safeStringLower(parts, 1) : typeV2,
548
- 'code': this.safeCurrencyCode(currencyId),
549
- 'info': account,
550
- };
551
- }
552
- async createDepositAddress(code, params = {}) {
553
- /**
554
- * @method
555
- * @name coinbase#createDepositAddress
556
- * @description create a currency deposit address
557
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-addresses#create-address
558
- * @param {string} code unified currency code of the currency for the deposit address
559
- * @param {object} [params] extra parameters specific to the exchange API endpoint
560
- * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
561
- */
562
- let accountId = this.safeString(params, 'account_id');
563
- params = this.omit(params, 'account_id');
564
- if (accountId === undefined) {
565
- await this.loadAccounts();
566
- for (let i = 0; i < this.accounts.length; i++) {
567
- const account = this.accounts[i];
568
- if (account['code'] === code && account['type'] === 'wallet') {
569
- accountId = account['id'];
570
- break;
571
- }
572
- }
573
- }
574
- if (accountId === undefined) {
575
- throw new errors.ExchangeError(this.id + ' createDepositAddress() could not find the account with matching currency code, specify an `account_id` extra param');
576
- }
577
- const request = {
578
- 'account_id': accountId,
579
- };
580
- const response = await this.v2PrivatePostAccountsAccountIdAddresses(this.extend(request, params));
581
- //
582
- // {
583
- // "data": {
584
- // "id": "05b1ebbf-9438-5dd4-b297-2ddedc98d0e4",
585
- // "address": "coinbasebase",
586
- // "address_info": {
587
- // "address": "coinbasebase",
588
- // "destination_tag": "287594668"
589
- // },
590
- // "name": null,
591
- // "created_at": "2019-07-01T14:39:29Z",
592
- // "updated_at": "2019-07-01T14:39:29Z",
593
- // "network": "eosio",
594
- // "uri_scheme": "eosio",
595
- // "resource": "address",
596
- // "resource_path": "/v2/accounts/14cfc769-e852-52f3-b831-711c104d194c/addresses/05b1ebbf-9438-5dd4-b297-2ddedc98d0e4",
597
- // "warnings": [
598
- // {
599
- // "title": "Only send EOS (EOS) to this address",
600
- // "details": "Sending any other cryptocurrency will result in permanent loss.",
601
- // "image_url": "https://dynamic-assets.coinbase.com/deaca3d47b10ed4a91a872e9618706eec34081127762d88f2476ac8e99ada4b48525a9565cf2206d18c04053f278f693434af4d4629ca084a9d01b7a286a7e26/asset_icons/1f8489bb280fb0a0fd643c1161312ba49655040e9aaaced5f9ad3eeaf868eadc.png"
602
- // },
603
- // {
604
- // "title": "Both an address and EOS memo are required to receive EOS",
605
- // "details": "If you send funds without an EOS memo or with an incorrect EOS memo, your funds cannot be credited to your account.",
606
- // "image_url": "https://www.coinbase.com/assets/receive-warning-2f3269d83547a7748fb39d6e0c1c393aee26669bfea6b9f12718094a1abff155.png"
607
- // }
608
- // ],
609
- // "warning_title": "Only send EOS (EOS) to this address",
610
- // "warning_details": "Sending any other cryptocurrency will result in permanent loss.",
611
- // "destination_tag": "287594668",
612
- // "deposit_uri": "eosio:coinbasebase?dt=287594668",
613
- // "callback_url": null
614
- // }
615
- // }
616
- //
617
- const data = this.safeValue(response, 'data', {});
618
- const tag = this.safeString(data, 'destination_tag');
619
- const address = this.safeString(data, 'address');
620
- return {
621
- 'currency': code,
622
- 'tag': tag,
623
- 'address': address,
624
- 'info': response,
625
- };
626
- }
627
- async fetchMySells(symbol = undefined, since = undefined, limit = undefined, params = {}) {
628
- /**
629
- * @method
630
- * @name coinbase#fetchMySells
631
- * @ignore
632
- * @description fetch sells
633
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-sells#list-sells
634
- * @param {string} symbol not used by coinbase fetchMySells ()
635
- * @param {int} [since] timestamp in ms of the earliest sell, default is undefined
636
- * @param {int} [limit] max number of sells to return, default is undefined
637
- * @param {object} [params] extra parameters specific to the exchange API endpoint
638
- * @returns {object} a [list of order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
639
- */
640
- // v2 did't have an endpoint for all historical trades
641
- const request = this.prepareAccountRequest(limit, params);
642
- await this.loadMarkets();
643
- const query = this.omit(params, ['account_id', 'accountId']);
644
- const sells = await this.v2PrivateGetAccountsAccountIdSells(this.extend(request, query));
645
- return this.parseTrades(sells['data'], undefined, since, limit);
646
- }
647
- async fetchMyBuys(symbol = undefined, since = undefined, limit = undefined, params = {}) {
648
- /**
649
- * @method
650
- * @name coinbase#fetchMyBuys
651
- * @ignore
652
- * @description fetch buys
653
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-buys#list-buys
654
- * @param {string} symbol not used by coinbase fetchMyBuys ()
655
- * @param {int} [since] timestamp in ms of the earliest buy, default is undefined
656
- * @param {int} [limit] max number of buys to return, default is undefined
657
- * @param {object} [params] extra parameters specific to the exchange API endpoint
658
- * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
659
- */
660
- // v2 did't have an endpoint for all historical trades
661
- const request = this.prepareAccountRequest(limit, params);
662
- await this.loadMarkets();
663
- const query = this.omit(params, ['account_id', 'accountId']);
664
- const buys = await this.v2PrivateGetAccountsAccountIdBuys(this.extend(request, query));
665
- return this.parseTrades(buys['data'], undefined, since, limit);
666
- }
667
- async fetchTransactionsWithMethod(method, code = undefined, since = undefined, limit = undefined, params = {}) {
668
- const request = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
669
- await this.loadMarkets();
670
- const query = this.omit(params, ['account_id', 'accountId']);
671
- const response = await this[method](this.extend(request, query));
672
- return this.parseTransactions(response['data'], undefined, since, limit);
673
- }
674
- async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
675
- /**
676
- * @method
677
- * @name coinbase#fetchWithdrawals
678
- * @description fetch all withdrawals made from an account
679
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-withdrawals#list-withdrawals
680
- * @param {string} code unified currency code
681
- * @param {int} [since] the earliest time in ms to fetch withdrawals for
682
- * @param {int} [limit] the maximum number of withdrawals structures to retrieve
683
- * @param {object} [params] extra parameters specific to the exchange API endpoint
684
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
685
- */
686
- // fiat only, for crypto transactions use fetchLedger
687
- return await this.fetchTransactionsWithMethod('v2PrivateGetAccountsAccountIdWithdrawals', code, since, limit, params);
688
- }
689
- async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
690
- /**
691
- * @method
692
- * @name coinbase#fetchDeposits
693
- * @description fetch all deposits made to an account
694
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#list-deposits
695
- * @param {string} code unified currency code
696
- * @param {int} [since] the earliest time in ms to fetch deposits for
697
- * @param {int} [limit] the maximum number of deposits structures to retrieve
698
- * @param {object} [params] extra parameters specific to the exchange API endpoint
699
- * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
700
- */
701
- // fiat only, for crypto transactions use fetchLedger
702
- return await this.fetchTransactionsWithMethod('v2PrivateGetAccountsAccountIdDeposits', code, since, limit, params);
703
- }
704
- parseTransactionStatus(status) {
705
- const statuses = {
706
- 'created': 'pending',
707
- 'completed': 'ok',
708
- 'canceled': 'canceled',
709
- };
710
- return this.safeString(statuses, status, status);
711
- }
712
- parseTransaction(transaction, currency = undefined) {
713
- //
714
- // fiat deposit
715
- //
716
- // {
717
- // "id": "f34c19f3-b730-5e3d-9f72",
718
- // "status": "completed",
719
- // "payment_method": {
720
- // "id": "a022b31d-f9c7-5043-98f2",
721
- // "resource": "payment_method",
722
- // "resource_path": "/v2/payment-methods/a022b31d-f9c7-5043-98f2"
723
- // },
724
- // "transaction": {
725
- // "id": "04ed4113-3732-5b0c-af86-b1d2146977d0",
726
- // "resource": "transaction",
727
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86"
728
- // },
729
- // "user_reference": "2VTYTH",
730
- // "created_at": "2017-02-09T07:01:18Z",
731
- // "updated_at": "2017-02-09T07:01:26Z",
732
- // "resource": "deposit",
733
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72",
734
- // "committed": true,
735
- // "payout_at": "2017-02-12T07:01:17Z",
736
- // "instant": false,
737
- // "fee": { "amount": "0.00", "currency": "EUR" },
738
- // "amount": { "amount": "114.02", "currency": "EUR" },
739
- // "subtotal": { "amount": "114.02", "currency": "EUR" },
740
- // "hold_until": null,
741
- // "hold_days": 0,
742
- // "hold_business_days": 0,
743
- // "next_step": null
744
- // }
745
- //
746
- // fiat_withdrawal
747
- //
748
- // {
749
- // "id": "cfcc3b4a-eeb6-5e8c-8058",
750
- // "status": "completed",
751
- // "payment_method": {
752
- // "id": "8b94cfa4-f7fd-5a12-a76a",
753
- // "resource": "payment_method",
754
- // "resource_path": "/v2/payment-methods/8b94cfa4-f7fd-5a12-a76a"
755
- // },
756
- // "transaction": {
757
- // "id": "fcc2550b-5104-5f83-a444",
758
- // "resource": "transaction",
759
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/fcc2550b-5104-5f83-a444"
760
- // },
761
- // "user_reference": "MEUGK",
762
- // "created_at": "2018-07-26T08:55:12Z",
763
- // "updated_at": "2018-07-26T08:58:18Z",
764
- // "resource": "withdrawal",
765
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/cfcc3b4a-eeb6-5e8c-8058",
766
- // "committed": true,
767
- // "payout_at": "2018-07-31T08:55:12Z",
768
- // "instant": false,
769
- // "fee": { "amount": "0.15", "currency": "EUR" },
770
- // "amount": { "amount": "13130.69", "currency": "EUR" },
771
- // "subtotal": { "amount": "13130.84", "currency": "EUR" },
772
- // "idem": "e549dee5-63ed-4e79-8a96",
773
- // "next_step": null
774
- // }
775
- //
776
- // withdraw
777
- //
778
- // {
779
- // "id": "a1794ecf-5693-55fa-70cf-ef731748ed82",
780
- // "type": "send",
781
- // "status": "pending",
782
- // "amount": {
783
- // "amount": "-14.008308",
784
- // "currency": "USDC"
785
- // },
786
- // "native_amount": {
787
- // "amount": "-18.74",
788
- // "currency": "CAD"
789
- // },
790
- // "description": null,
791
- // "created_at": "2024-01-12T01:27:31Z",
792
- // "updated_at": "2024-01-12T01:27:31Z",
793
- // "resource": "transaction",
794
- // "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82",
795
- // "instant_exchange": false,
796
- // "network": {
797
- // "status": "pending",
798
- // "status_description": "Pending (est. less than 10 minutes)",
799
- // "transaction_fee": {
800
- // "amount": "4.008308",
801
- // "currency": "USDC"
802
- // },
803
- // "transaction_amount": {
804
- // "amount": "10.000000",
805
- // "currency": "USDC"
806
- // },
807
- // "confirmations": 0
808
- // },
809
- // "to": {
810
- // "resource": "ethereum_address",
811
- // "address": "0x9...",
812
- // "currency": "USDC",
813
- // "address_info": {
814
- // "address": "0x9..."
815
- // }
816
- // },
817
- // "idem": "748d8591-dg9a-7831-a45b-crd61dg78762",
818
- // "details": {
819
- // "title": "Sent USDC",
820
- // "subtitle": "To USDC address on Ethereum network",
821
- // "header": "Sent 14.008308 USDC ($18.74)",
822
- // "health": "warning"
823
- // },
824
- // "hide_native_amount": false
825
- // }
826
- //
827
- const transactionType = this.safeString(transaction, 'type');
828
- let amountAndCurrencyObject = undefined;
829
- let feeObject = undefined;
830
- if (transactionType === 'send') {
831
- const network = this.safeValue(transaction, 'network', {});
832
- amountAndCurrencyObject = this.safeValue(network, 'transaction_amount', {});
833
- feeObject = this.safeValue(network, 'transaction_fee', {});
834
- }
835
- else {
836
- amountAndCurrencyObject = this.safeValue(transaction, 'subtotal', {});
837
- feeObject = this.safeValue(transaction, 'fee', {});
838
- }
839
- let status = this.parseTransactionStatus(this.safeString(transaction, 'status'));
840
- if (status === undefined) {
841
- const committed = this.safeValue(transaction, 'committed');
842
- status = committed ? 'ok' : 'pending';
843
- }
844
- const id = this.safeString(transaction, 'id');
845
- const currencyId = this.safeString(amountAndCurrencyObject, 'currency');
846
- const feeCurrencyId = this.safeString(feeObject, 'currency');
847
- const datetime = this.safeValue(transaction, 'created_at');
848
- const toObject = this.safeValue(transaction, 'to', {});
849
- const toAddress = this.safeString(toObject, 'address');
850
- return {
851
- 'info': transaction,
852
- 'id': id,
853
- 'txid': id,
854
- 'timestamp': this.parse8601(datetime),
855
- 'datetime': datetime,
856
- 'network': undefined,
857
- 'address': toAddress,
858
- 'addressTo': toAddress,
859
- 'addressFrom': undefined,
860
- 'tag': undefined,
861
- 'tagTo': undefined,
862
- 'tagFrom': undefined,
863
- 'type': this.safeString(transaction, 'resource'),
864
- 'amount': this.safeNumber(amountAndCurrencyObject, 'amount'),
865
- 'currency': this.safeCurrencyCode(currencyId, currency),
866
- 'status': status,
867
- 'updated': this.parse8601(this.safeValue(transaction, 'updated_at')),
868
- 'fee': {
869
- 'cost': this.safeNumber(feeObject, 'amount'),
870
- 'currency': this.safeCurrencyCode(feeCurrencyId),
871
- },
872
- };
873
- }
874
- parseTrade(trade, market = undefined) {
875
- //
876
- // fetchMyBuys, fetchMySells
877
- //
878
- // {
879
- // "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
880
- // "status": "completed",
881
- // "payment_method": {
882
- // "id": "83562370-3e5c-51db-87da-752af5ab9559",
883
- // "resource": "payment_method",
884
- // "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
885
- // },
886
- // "transaction": {
887
- // "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
888
- // "resource": "transaction",
889
- // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
890
- // },
891
- // "amount": { "amount": "1.00000000", "currency": "BTC" },
892
- // "total": { "amount": "10.25", "currency": "USD" },
893
- // "subtotal": { "amount": "10.10", "currency": "USD" },
894
- // "created_at": "2015-01-31T20:49:02Z",
895
- // "updated_at": "2015-02-11T16:54:02-08:00",
896
- // "resource": "buy",
897
- // "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/buys/67e0eaec-07d7-54c4-a72c-2e92826897df",
898
- // "committed": true,
899
- // "instant": false,
900
- // "fee": { "amount": "0.15", "currency": "USD" },
901
- // "payout_at": "2015-02-18T16:54:00-08:00"
902
- // }
903
- //
904
- // fetchTrades
905
- //
906
- // {
907
- // "trade_id": "10092327",
908
- // "product_id": "BTC-USDT",
909
- // "price": "17488.12",
910
- // "size": "0.0000623",
911
- // "time": "2023-01-11T00:52:37.557001Z",
912
- // "side": "BUY",
913
- // "bid": "",
914
- // "ask": ""
915
- // }
916
- //
917
- // fetchMyTrades
918
- //
919
- // {
920
- // "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010",
921
- // "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1",
922
- // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
923
- // "trade_time": "2023-01-18T01:37:38.091377090Z",
924
- // "trade_type": "FILL",
925
- // "price": "21220.64",
926
- // "size": "0.0046830664333996",
927
- // "commission": "0.0000280983986004",
928
- // "product_id": "BTC-USDT",
929
- // "sequence_timestamp": "2023-01-18T01:37:38.092520Z",
930
- // "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR",
931
- // "size_in_quote": true,
932
- // "user_id": "1111111-1111-1111-1111-111111111111",
933
- // "side": "BUY"
934
- // }
935
- //
936
- let symbol = undefined;
937
- const totalObject = this.safeValue(trade, 'total', {});
938
- const amountObject = this.safeValue(trade, 'amount', {});
939
- const subtotalObject = this.safeValue(trade, 'subtotal', {});
940
- const feeObject = this.safeValue(trade, 'fee', {});
941
- const marketId = this.safeString(trade, 'product_id');
942
- market = this.safeMarket(marketId, market, '-');
943
- if (market !== undefined) {
944
- symbol = market['symbol'];
945
- }
946
- else {
947
- const baseId = this.safeString(amountObject, 'currency');
948
- const quoteId = this.safeString(totalObject, 'currency');
949
- if ((baseId !== undefined) && (quoteId !== undefined)) {
950
- const base = this.safeCurrencyCode(baseId);
951
- const quote = this.safeCurrencyCode(quoteId);
952
- symbol = base + '/' + quote;
953
- }
954
- }
955
- const sizeInQuote = this.safeValue(trade, 'size_in_quote');
956
- const v3Price = this.safeString(trade, 'price');
957
- let v3Cost = undefined;
958
- let v3Amount = this.safeString(trade, 'size');
959
- if (sizeInQuote) {
960
- // calculate base size
961
- v3Cost = v3Amount;
962
- v3Amount = Precise["default"].stringDiv(v3Amount, v3Price);
963
- }
964
- const v3FeeCost = this.safeString(trade, 'commission');
965
- const amountString = this.safeString(amountObject, 'amount', v3Amount);
966
- const costString = this.safeString(subtotalObject, 'amount', v3Cost);
967
- let priceString = undefined;
968
- let cost = undefined;
969
- if ((costString !== undefined) && (amountString !== undefined)) {
970
- priceString = Precise["default"].stringDiv(costString, amountString);
971
- }
972
- else {
973
- priceString = v3Price;
974
- }
975
- if ((priceString !== undefined) && (amountString !== undefined)) {
976
- cost = Precise["default"].stringMul(priceString, amountString);
977
- }
978
- else {
979
- cost = costString;
980
- }
981
- let feeCurrencyId = this.safeString(feeObject, 'currency');
982
- const feeCost = this.safeNumber(feeObject, 'amount', this.parseNumber(v3FeeCost));
983
- if ((feeCurrencyId === undefined) && (market !== undefined) && (feeCost !== undefined)) {
984
- feeCurrencyId = market['quote'];
985
- }
986
- const datetime = this.safeStringN(trade, ['created_at', 'trade_time', 'time']);
987
- const side = this.safeStringLower2(trade, 'resource', 'side');
988
- const takerOrMaker = this.safeStringLower(trade, 'liquidity_indicator');
989
- return this.safeTrade({
990
- 'info': trade,
991
- 'id': this.safeString2(trade, 'id', 'trade_id'),
992
- 'order': this.safeString(trade, 'order_id'),
993
- 'timestamp': this.parse8601(datetime),
994
- 'datetime': datetime,
995
- 'symbol': symbol,
996
- 'type': undefined,
997
- 'side': (side === 'unknown_order_side') ? undefined : side,
998
- 'takerOrMaker': (takerOrMaker === 'unknown_liquidity_indicator') ? undefined : takerOrMaker,
999
- 'price': priceString,
1000
- 'amount': amountString,
1001
- 'cost': cost,
1002
- 'fee': {
1003
- 'cost': feeCost,
1004
- 'currency': this.safeCurrencyCode(feeCurrencyId),
1005
- },
1006
- });
1007
- }
1008
- async fetchMarkets(params = {}) {
1009
- /**
1010
- * @method
1011
- * @name coinbase#fetchMarkets
1012
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getproducts
1013
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1014
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1015
- * @description retrieves data on all markets for coinbase
1016
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1017
- * @returns {object[]} an array of objects representing market data
1018
- */
1019
- const method = this.safeString(this.options, 'fetchMarkets', 'fetchMarketsV3');
1020
- return await this[method](params);
1021
- }
1022
- async fetchMarketsV2(params = {}) {
1023
- const response = await this.fetchCurrenciesFromCache(params);
1024
- const currencies = this.safeValue(response, 'currencies', {});
1025
- const exchangeRates = this.safeValue(response, 'exchangeRates', {});
1026
- const data = this.safeValue(currencies, 'data', []);
1027
- const dataById = this.indexBy(data, 'id');
1028
- const rates = this.safeValue(this.safeValue(exchangeRates, 'data', {}), 'rates', {});
1029
- const baseIds = Object.keys(rates);
1030
- const result = [];
1031
- for (let i = 0; i < baseIds.length; i++) {
1032
- const baseId = baseIds[i];
1033
- const base = this.safeCurrencyCode(baseId);
1034
- const type = (baseId in dataById) ? 'fiat' : 'crypto';
1035
- // https://github.com/ccxt/ccxt/issues/6066
1036
- if (type === 'crypto') {
1037
- for (let j = 0; j < data.length; j++) {
1038
- const quoteCurrency = data[j];
1039
- const quoteId = this.safeString(quoteCurrency, 'id');
1040
- const quote = this.safeCurrencyCode(quoteId);
1041
- result.push({
1042
- 'id': baseId + '-' + quoteId,
1043
- 'symbol': base + '/' + quote,
1044
- 'base': base,
1045
- 'quote': quote,
1046
- 'settle': undefined,
1047
- 'baseId': baseId,
1048
- 'quoteId': quoteId,
1049
- 'settleId': undefined,
1050
- 'type': 'spot',
1051
- 'spot': true,
1052
- 'margin': false,
1053
- 'swap': false,
1054
- 'future': false,
1055
- 'option': false,
1056
- 'active': undefined,
1057
- 'contract': false,
1058
- 'linear': undefined,
1059
- 'inverse': undefined,
1060
- 'contractSize': undefined,
1061
- 'expiry': undefined,
1062
- 'expiryDatetime': undefined,
1063
- 'strike': undefined,
1064
- 'optionType': undefined,
1065
- 'precision': {
1066
- 'amount': undefined,
1067
- 'price': undefined,
1068
- },
1069
- 'limits': {
1070
- 'leverage': {
1071
- 'min': undefined,
1072
- 'max': undefined,
1073
- },
1074
- 'amount': {
1075
- 'min': undefined,
1076
- 'max': undefined,
1077
- },
1078
- 'price': {
1079
- 'min': undefined,
1080
- 'max': undefined,
1081
- },
1082
- 'cost': {
1083
- 'min': this.safeNumber(quoteCurrency, 'min_size'),
1084
- 'max': undefined,
1085
- },
1086
- },
1087
- 'info': quoteCurrency,
1088
- });
1089
- }
1090
- }
1091
- }
1092
- return result;
1093
- }
1094
- async fetchMarketsV3(params = {}) {
1095
- const response = await this.v3PrivateGetBrokerageProducts(params);
1096
- //
1097
- // [
1098
- // {
1099
- // "product_id": "TONE-USD",
1100
- // "price": "0.01523",
1101
- // "price_percentage_change_24h": "1.94109772423025",
1102
- // "volume_24h": "19773129",
1103
- // "volume_percentage_change_24h": "437.0170530929949",
1104
- // "base_increment": "1",
1105
- // "quote_increment": "0.00001",
1106
- // "quote_min_size": "1",
1107
- // "quote_max_size": "10000000",
1108
- // "base_min_size": "26.7187147229469674",
1109
- // "base_max_size": "267187147.2294696735908216",
1110
- // "base_name": "TE-FOOD",
1111
- // "quote_name": "US Dollar",
1112
- // "watched": false,
1113
- // "is_disabled": false,
1114
- // "new": false,
1115
- // "status": "online",
1116
- // "cancel_only": false,
1117
- // "limit_only": false,
1118
- // "post_only": false,
1119
- // "trading_disabled": false,
1120
- // "auction_mode": false,
1121
- // "product_type": "SPOT",
1122
- // "quote_currency_id": "USD",
1123
- // "base_currency_id": "TONE",
1124
- // "fcm_trading_session_details": null,
1125
- // "mid_market_price": ""
1126
- // },
1127
- // ...
1128
- // ]
1129
- //
1130
- const fees = await this.v3PrivateGetBrokerageTransactionSummary(params);
1131
- //
1132
- // {
1133
- // "total_volume": 0,
1134
- // "total_fees": 0,
1135
- // "fee_tier": {
1136
- // "pricing_tier": "",
1137
- // "usd_from": "0",
1138
- // "usd_to": "10000",
1139
- // "taker_fee_rate": "0.006",
1140
- // "maker_fee_rate": "0.004"
1141
- // },
1142
- // "margin_rate": null,
1143
- // "goods_and_services_tax": null,
1144
- // "advanced_trade_only_volume": 0,
1145
- // "advanced_trade_only_fees": 0,
1146
- // "coinbase_pro_volume": 0,
1147
- // "coinbase_pro_fees": 0
1148
- // }
1149
- //
1150
- const feeTier = this.safeValue(fees, 'fee_tier', {});
1151
- const data = this.safeValue(response, 'products', []);
1152
- const result = [];
1153
- for (let i = 0; i < data.length; i++) {
1154
- const market = data[i];
1155
- const id = this.safeString(market, 'product_id');
1156
- const baseId = this.safeString(market, 'base_currency_id');
1157
- const quoteId = this.safeString(market, 'quote_currency_id');
1158
- const base = this.safeCurrencyCode(baseId);
1159
- const quote = this.safeCurrencyCode(quoteId);
1160
- const marketType = this.safeStringLower(market, 'product_type');
1161
- const tradingDisabled = this.safeValue(market, 'trading_disabled');
1162
- const stablePairs = this.safeValue(this.options, 'stablePairs', []);
1163
- result.push({
1164
- 'id': id,
1165
- 'symbol': base + '/' + quote,
1166
- 'base': base,
1167
- 'quote': quote,
1168
- 'settle': undefined,
1169
- 'baseId': baseId,
1170
- 'quoteId': quoteId,
1171
- 'settleId': undefined,
1172
- 'type': marketType,
1173
- 'spot': (marketType === 'spot'),
1174
- 'margin': undefined,
1175
- 'swap': false,
1176
- 'future': false,
1177
- 'option': false,
1178
- 'active': !tradingDisabled,
1179
- 'contract': false,
1180
- 'linear': undefined,
1181
- 'inverse': undefined,
1182
- 'taker': this.inArray(id, stablePairs) ? 0.00001 : this.safeNumber(feeTier, 'taker_fee_rate'),
1183
- 'maker': this.inArray(id, stablePairs) ? 0.0 : this.safeNumber(feeTier, 'maker_fee_rate'),
1184
- 'contractSize': undefined,
1185
- 'expiry': undefined,
1186
- 'expiryDatetime': undefined,
1187
- 'strike': undefined,
1188
- 'optionType': undefined,
1189
- 'precision': {
1190
- 'amount': this.safeNumber(market, 'base_increment'),
1191
- 'price': this.safeNumber2(market, 'price_increment', 'quote_increment'),
1192
- },
1193
- 'limits': {
1194
- 'leverage': {
1195
- 'min': undefined,
1196
- 'max': undefined,
1197
- },
1198
- 'amount': {
1199
- 'min': this.safeNumber(market, 'base_min_size'),
1200
- 'max': this.safeNumber(market, 'base_max_size'),
1201
- },
1202
- 'price': {
1203
- 'min': undefined,
1204
- 'max': undefined,
1205
- },
1206
- 'cost': {
1207
- 'min': this.safeNumber(market, 'quote_min_size'),
1208
- 'max': this.safeNumber(market, 'quote_max_size'),
1209
- },
1210
- },
1211
- 'created': undefined,
1212
- 'info': market,
1213
- });
1214
- }
1215
- return result;
1216
- }
1217
- async fetchCurrenciesFromCache(params = {}) {
1218
- const options = this.safeValue(this.options, 'fetchCurrencies', {});
1219
- const timestamp = this.safeInteger(options, 'timestamp');
1220
- const expires = this.safeInteger(options, 'expires', 1000);
1221
- const now = this.milliseconds();
1222
- if ((timestamp === undefined) || ((now - timestamp) > expires)) {
1223
- const currencies = await this.v2PublicGetCurrencies(params);
1224
- const exchangeRates = await this.v2PublicGetExchangeRates(params);
1225
- this.options['fetchCurrencies'] = this.extend(options, {
1226
- 'currencies': currencies,
1227
- 'exchangeRates': exchangeRates,
1228
- 'timestamp': now,
1229
- });
1230
- }
1231
- return this.safeValue(this.options, 'fetchCurrencies', {});
1232
- }
1233
- async fetchCurrencies(params = {}) {
1234
- /**
1235
- * @method
1236
- * @name coinbase#fetchCurrencies
1237
- * @description fetches all available currencies on an exchange
1238
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
1239
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1240
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1241
- * @returns {object} an associative dictionary of currencies
1242
- */
1243
- const response = await this.fetchCurrenciesFromCache(params);
1244
- const currencies = this.safeValue(response, 'currencies', {});
1245
- //
1246
- // {
1247
- // "data":[
1248
- // {"id":"AED","name":"United Arab Emirates Dirham","min_size":"0.01000000"},
1249
- // {"id":"AFN","name":"Afghan Afghani","min_size":"0.01000000"},
1250
- // {"id":"ALL","name":"Albanian Lek","min_size":"0.01000000"},
1251
- // {"id":"AMD","name":"Armenian Dram","min_size":"0.01000000"},
1252
- // {"id":"ANG","name":"Netherlands Antillean Gulden","min_size":"0.01000000"},
1253
- // ...
1254
- // ],
1255
- // }
1256
- //
1257
- const exchangeRates = this.safeValue(response, 'exchangeRates', {});
1258
- //
1259
- // {
1260
- // "data":{
1261
- // "currency":"USD",
1262
- // "rates":{
1263
- // "AED":"3.67",
1264
- // "AFN":"78.21",
1265
- // "ALL":"110.42",
1266
- // "AMD":"474.18",
1267
- // "ANG":"1.75",
1268
- // ...
1269
- // },
1270
- // }
1271
- // }
1272
- //
1273
- const data = this.safeValue(currencies, 'data', []);
1274
- const dataById = this.indexBy(data, 'id');
1275
- const rates = this.safeValue(this.safeValue(exchangeRates, 'data', {}), 'rates', {});
1276
- const keys = Object.keys(rates);
1277
- const result = {};
1278
- for (let i = 0; i < keys.length; i++) {
1279
- const key = keys[i];
1280
- const type = (key in dataById) ? 'fiat' : 'crypto';
1281
- const currency = this.safeValue(dataById, key, {});
1282
- const id = this.safeString(currency, 'id', key);
1283
- const name = this.safeString(currency, 'name');
1284
- const code = this.safeCurrencyCode(id);
1285
- result[code] = {
1286
- 'id': id,
1287
- 'code': code,
1288
- 'info': currency,
1289
- 'type': type,
1290
- 'name': name,
1291
- 'active': true,
1292
- 'deposit': undefined,
1293
- 'withdraw': undefined,
1294
- 'fee': undefined,
1295
- 'precision': undefined,
1296
- 'limits': {
1297
- 'amount': {
1298
- 'min': this.safeNumber(currency, 'min_size'),
1299
- 'max': undefined,
1300
- },
1301
- 'withdraw': {
1302
- 'min': undefined,
1303
- 'max': undefined,
1304
- },
1305
- },
1306
- };
1307
- }
1308
- return result;
1309
- }
1310
- async fetchTickers(symbols = undefined, params = {}) {
1311
- /**
1312
- * @method
1313
- * @name coinbase#fetchTickers
1314
- * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1315
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getproducts
1316
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
1317
- * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1318
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1319
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1320
- */
1321
- const method = this.safeString(this.options, 'fetchTickers', 'fetchTickersV3');
1322
- if (method === 'fetchTickersV3') {
1323
- return await this.fetchTickersV3(symbols, params);
1324
- }
1325
- return await this.fetchTickersV2(symbols, params);
1326
- }
1327
- async fetchTickersV2(symbols = undefined, params = {}) {
1328
- await this.loadMarkets();
1329
- symbols = this.marketSymbols(symbols);
1330
- const request = {
1331
- // 'currency': 'USD',
1332
- };
1333
- const response = await this.v2PublicGetExchangeRates(this.extend(request, params));
1334
- //
1335
- // {
1336
- // "data":{
1337
- // "currency":"USD",
1338
- // "rates":{
1339
- // "AED":"3.6731",
1340
- // "AFN":"103.163942",
1341
- // "ALL":"106.973038",
1342
- // }
1343
- // }
1344
- // }
1345
- //
1346
- const data = this.safeValue(response, 'data', {});
1347
- const rates = this.safeValue(data, 'rates', {});
1348
- const quoteId = this.safeString(data, 'currency');
1349
- const result = {};
1350
- const baseIds = Object.keys(rates);
1351
- const delimiter = '-';
1352
- for (let i = 0; i < baseIds.length; i++) {
1353
- const baseId = baseIds[i];
1354
- const marketId = baseId + delimiter + quoteId;
1355
- const market = this.safeMarket(marketId, undefined, delimiter);
1356
- const symbol = market['symbol'];
1357
- result[symbol] = this.parseTicker(rates[baseId], market);
1358
- }
1359
- return this.filterByArrayTickers(result, 'symbol', symbols);
1360
- }
1361
- async fetchTickersV3(symbols = undefined, params = {}) {
1362
- await this.loadMarkets();
1363
- symbols = this.marketSymbols(symbols);
1364
- const response = await this.v3PrivateGetBrokerageProducts(params);
1365
- //
1366
- // {
1367
- // "products": [
1368
- // {
1369
- // "product_id": "TONE-USD",
1370
- // "price": "0.01523",
1371
- // "price_percentage_change_24h": "1.94109772423025",
1372
- // "volume_24h": "19773129",
1373
- // "volume_percentage_change_24h": "437.0170530929949",
1374
- // "base_increment": "1",
1375
- // "quote_increment": "0.00001",
1376
- // "quote_min_size": "1",
1377
- // "quote_max_size": "10000000",
1378
- // "base_min_size": "26.7187147229469674",
1379
- // "base_max_size": "267187147.2294696735908216",
1380
- // "base_name": "TE-FOOD",
1381
- // "quote_name": "US Dollar",
1382
- // "watched": false,
1383
- // "is_disabled": false,
1384
- // "new": false,
1385
- // "status": "online",
1386
- // "cancel_only": false,
1387
- // "limit_only": false,
1388
- // "post_only": false,
1389
- // "trading_disabled": false,
1390
- // "auction_mode": false,
1391
- // "product_type": "SPOT",
1392
- // "quote_currency_id": "USD",
1393
- // "base_currency_id": "TONE",
1394
- // "fcm_trading_session_details": null,
1395
- // "mid_market_price": ""
1396
- // },
1397
- // ...
1398
- // ],
1399
- // "num_products": 549
1400
- // }
1401
- //
1402
- const data = this.safeValue(response, 'products', []);
1403
- const result = {};
1404
- for (let i = 0; i < data.length; i++) {
1405
- const entry = data[i];
1406
- const marketId = this.safeString(entry, 'product_id');
1407
- const market = this.safeMarket(marketId, undefined, '-');
1408
- const symbol = market['symbol'];
1409
- result[symbol] = this.parseTicker(entry, market);
1410
- }
1411
- return this.filterByArrayTickers(result, 'symbol', symbols);
1412
- }
1413
- async fetchTicker(symbol, params = {}) {
1414
- /**
1415
- * @method
1416
- * @name coinbase#fetchTicker
1417
- * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1418
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getmarkettrades
1419
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price
1420
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-buy-price
1421
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-sell-price
1422
- * @param {string} symbol unified symbol of the market to fetch the ticker for
1423
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1424
- * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1425
- */
1426
- const method = this.safeString(this.options, 'fetchTicker', 'fetchTickerV3');
1427
- if (method === 'fetchTickerV3') {
1428
- return await this.fetchTickerV3(symbol, params);
1429
- }
1430
- return await this.fetchTickerV2(symbol, params);
1431
- }
1432
- async fetchTickerV2(symbol, params = {}) {
1433
- await this.loadMarkets();
1434
- const market = this.market(symbol);
1435
- const request = this.extend({
1436
- 'symbol': market['id'],
1437
- }, params);
1438
- const spot = await this.v2PublicGetPricesSymbolSpot(request);
1439
- //
1440
- // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
1441
- //
1442
- const ask = await this.v2PublicGetPricesSymbolBuy(request);
1443
- //
1444
- // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
1445
- //
1446
- const bid = await this.v2PublicGetPricesSymbolSell(request);
1447
- //
1448
- // {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
1449
- //
1450
- const spotData = this.safeValue(spot, 'data', {});
1451
- const askData = this.safeValue(ask, 'data', {});
1452
- const bidData = this.safeValue(bid, 'data', {});
1453
- const bidAskLast = {
1454
- 'bid': this.safeNumber(bidData, 'amount'),
1455
- 'ask': this.safeNumber(askData, 'amount'),
1456
- 'price': this.safeNumber(spotData, 'amount'),
1457
- };
1458
- return this.parseTicker(bidAskLast, market);
1459
- }
1460
- async fetchTickerV3(symbol, params = {}) {
1461
- await this.loadMarkets();
1462
- const market = this.market(symbol);
1463
- const request = {
1464
- 'product_id': market['id'],
1465
- 'limit': 1,
1466
- };
1467
- const response = await this.v3PrivateGetBrokerageProductsProductIdTicker(this.extend(request, params));
1468
- //
1469
- // {
1470
- // "trades": [
1471
- // {
1472
- // "trade_id": "518078013",
1473
- // "product_id": "BTC-USD",
1474
- // "price": "28208.1",
1475
- // "size": "0.00659179",
1476
- // "time": "2023-04-04T23:05:34.492746Z",
1477
- // "side": "BUY",
1478
- // "bid": "",
1479
- // "ask": ""
1480
- // }
1481
- // ],
1482
- // "best_bid": "28208.61",
1483
- // "best_ask": "28208.62"
1484
- // }
1485
- //
1486
- const data = this.safeValue(response, 'trades', []);
1487
- const ticker = this.parseTicker(data[0], market);
1488
- ticker['bid'] = this.safeNumber(response, 'best_bid');
1489
- ticker['ask'] = this.safeNumber(response, 'best_ask');
1490
- return ticker;
1491
- }
1492
- parseTicker(ticker, market = undefined) {
1493
- //
1494
- // fetchTickerV2
1495
- //
1496
- // {
1497
- // "bid": 20713.37,
1498
- // "ask": 20924.65,
1499
- // "price": 20809.83
1500
- // }
1501
- //
1502
- // fetchTickerV3
1503
- //
1504
- // {
1505
- // "trade_id": "10209805",
1506
- // "product_id": "BTC-USDT",
1507
- // "price": "19381.27",
1508
- // "size": "0.1",
1509
- // "time": "2023-01-13T20:35:41.865970Z",
1510
- // "side": "BUY",
1511
- // "bid": "",
1512
- // "ask": ""
1513
- // }
1514
- //
1515
- // fetchTickersV2
1516
- //
1517
- // "48691.23"
1518
- //
1519
- // fetchTickersV3
1520
- //
1521
- // [
1522
- // {
1523
- // "product_id": "TONE-USD",
1524
- // "price": "0.01523",
1525
- // "price_percentage_change_24h": "1.94109772423025",
1526
- // "volume_24h": "19773129",
1527
- // "volume_percentage_change_24h": "437.0170530929949",
1528
- // "base_increment": "1",
1529
- // "quote_increment": "0.00001",
1530
- // "quote_min_size": "1",
1531
- // "quote_max_size": "10000000",
1532
- // "base_min_size": "26.7187147229469674",
1533
- // "base_max_size": "267187147.2294696735908216",
1534
- // "base_name": "TE-FOOD",
1535
- // "quote_name": "US Dollar",
1536
- // "watched": false,
1537
- // "is_disabled": false,
1538
- // "new": false,
1539
- // "status": "online",
1540
- // "cancel_only": false,
1541
- // "limit_only": false,
1542
- // "post_only": false,
1543
- // "trading_disabled": false,
1544
- // "auction_mode": false,
1545
- // "product_type": "SPOT",
1546
- // "quote_currency_id": "USD",
1547
- // "base_currency_id": "TONE",
1548
- // "fcm_trading_session_details": null,
1549
- // "mid_market_price": ""
1550
- // },
1551
- // ...
1552
- // ]
1553
- //
1554
- // fetchBidsAsks
1555
- //
1556
- // {
1557
- // "product_id": "TRAC-EUR",
1558
- // "bids": [
1559
- // {
1560
- // "price": "0.2384",
1561
- // "size": "386.1"
1562
- // }
1563
- // ],
1564
- // "asks": [
1565
- // {
1566
- // "price": "0.2406",
1567
- // "size": "672"
1568
- // }
1569
- // ],
1570
- // "time": "2023-06-30T07:15:24.656044Z"
1571
- // }
1572
- //
1573
- let bid = this.safeNumber(ticker, 'bid');
1574
- let ask = this.safeNumber(ticker, 'ask');
1575
- let bidVolume = undefined;
1576
- let askVolume = undefined;
1577
- if (('bids' in ticker)) {
1578
- const bids = this.safeValue(ticker, 'bids', []);
1579
- const asks = this.safeValue(ticker, 'asks', []);
1580
- bid = this.safeNumber(bids[0], 'price');
1581
- bidVolume = this.safeNumber(bids[0], 'size');
1582
- ask = this.safeNumber(asks[0], 'price');
1583
- askVolume = this.safeNumber(asks[0], 'size');
1584
- }
1585
- const marketId = this.safeString(ticker, 'product_id');
1586
- const last = this.safeNumber(ticker, 'price');
1587
- const datetime = this.safeString(ticker, 'time');
1588
- return this.safeTicker({
1589
- 'symbol': this.safeSymbol(marketId, market),
1590
- 'timestamp': this.parse8601(datetime),
1591
- 'datetime': datetime,
1592
- 'bid': bid,
1593
- 'ask': ask,
1594
- 'last': last,
1595
- 'high': undefined,
1596
- 'low': undefined,
1597
- 'bidVolume': bidVolume,
1598
- 'askVolume': askVolume,
1599
- 'vwap': undefined,
1600
- 'open': undefined,
1601
- 'close': last,
1602
- 'previousClose': undefined,
1603
- 'change': undefined,
1604
- 'percentage': this.safeNumber(ticker, 'price_percentage_change_24h'),
1605
- 'average': undefined,
1606
- 'baseVolume': undefined,
1607
- 'quoteVolume': undefined,
1608
- 'info': ticker,
1609
- }, market);
1610
- }
1611
- parseBalance(response, params = {}) {
1612
- const balances = this.safeValue2(response, 'data', 'accounts', []);
1613
- const accounts = this.safeValue(params, 'type', this.options['accounts']);
1614
- const v3Accounts = this.safeValue(params, 'type', this.options['v3Accounts']);
1615
- const result = { 'info': response };
1616
- for (let b = 0; b < balances.length; b++) {
1617
- const balance = balances[b];
1618
- const type = this.safeString(balance, 'type');
1619
- if (this.inArray(type, accounts)) {
1620
- const value = this.safeValue(balance, 'balance');
1621
- if (value !== undefined) {
1622
- const currencyId = this.safeString(value, 'currency');
1623
- const code = this.safeCurrencyCode(currencyId);
1624
- const total = this.safeString(value, 'amount');
1625
- const free = total;
1626
- let account = this.safeValue(result, code);
1627
- if (account === undefined) {
1628
- account = this.account();
1629
- account['free'] = free;
1630
- account['total'] = total;
1631
- }
1632
- else {
1633
- account['free'] = Precise["default"].stringAdd(account['free'], total);
1634
- account['total'] = Precise["default"].stringAdd(account['total'], total);
1635
- }
1636
- result[code] = account;
1637
- }
1638
- }
1639
- else if (this.inArray(type, v3Accounts)) {
1640
- const available = this.safeValue(balance, 'available_balance');
1641
- const hold = this.safeValue(balance, 'hold');
1642
- if (available !== undefined && hold !== undefined) {
1643
- const currencyId = this.safeString(available, 'currency');
1644
- const code = this.safeCurrencyCode(currencyId);
1645
- const used = this.safeString(hold, 'value');
1646
- const free = this.safeString(available, 'value');
1647
- const total = Precise["default"].stringAdd(used, free);
1648
- let account = this.safeValue(result, code);
1649
- if (account === undefined) {
1650
- account = this.account();
1651
- account['free'] = free;
1652
- account['used'] = used;
1653
- account['total'] = total;
1654
- }
1655
- else {
1656
- account['free'] = Precise["default"].stringAdd(account['free'], free);
1657
- account['used'] = Precise["default"].stringAdd(account['used'], used);
1658
- account['total'] = Precise["default"].stringAdd(account['total'], total);
1659
- }
1660
- result[code] = account;
1661
- }
1662
- }
1663
- }
1664
- return this.safeBalance(result);
1665
- }
1666
- async fetchBalance(params = {}) {
1667
- /**
1668
- * @method
1669
- * @name coinbase#fetchBalance
1670
- * @description query for balance and get the amount of funds available for trading or funds locked in orders
1671
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getaccounts
1672
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
1673
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1674
- * @param {boolean} [params.v3] default false, set true to use v3 api endpoint
1675
- * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1676
- */
1677
- await this.loadMarkets();
1678
- const request = {
1679
- 'limit': 250,
1680
- };
1681
- let response = undefined;
1682
- const isV3 = this.safeValue(params, 'v3', false);
1683
- params = this.omit(params, 'v3');
1684
- const method = this.safeString(this.options, 'fetchBalance', 'v3PrivateGetBrokerageAccounts');
1685
- if ((isV3) || (method === 'v3PrivateGetBrokerageAccounts')) {
1686
- response = await this.v3PrivateGetBrokerageAccounts(this.extend(request, params));
1687
- }
1688
- else {
1689
- response = await this.v2PrivateGetAccounts(this.extend(request, params));
1690
- }
1691
- //
1692
- // v2PrivateGetAccounts
1693
- // {
1694
- // "pagination":{
1695
- // "ending_before":null,
1696
- // "starting_after":null,
1697
- // "previous_ending_before":null,
1698
- // "next_starting_after":"6b17acd6-2e68-5eb0-9f45-72d67cef578b",
1699
- // "limit":100,
1700
- // "order":"desc",
1701
- // "previous_uri":null,
1702
- // "next_uri":"/v2/accounts?limit=100\u0026starting_after=6b17acd6-2e68-5eb0-9f45-72d67cef578b"
1703
- // },
1704
- // "data":[
1705
- // {
1706
- // "id":"94ad58bc-0f15-5309-b35a-a4c86d7bad60",
1707
- // "name":"MINA Wallet",
1708
- // "primary":false,
1709
- // "type":"wallet",
1710
- // "currency":{
1711
- // "code":"MINA",
1712
- // "name":"Mina",
1713
- // "color":"#EA6B48",
1714
- // "sort_index":397,
1715
- // "exponent":9,
1716
- // "type":"crypto",
1717
- // "address_regex":"^(B62)[A-Za-z0-9]{52}$",
1718
- // "asset_id":"a4ffc575-942c-5e26-b70c-cb3befdd4229",
1719
- // "slug":"mina"
1720
- // },
1721
- // "balance":{"amount":"0.000000000","currency":"MINA"},
1722
- // "created_at":"2022-03-25T00:36:16Z",
1723
- // "updated_at":"2022-03-25T00:36:16Z",
1724
- // "resource":"account",
1725
- // "resource_path":"/v2/accounts/94ad58bc-0f15-5309-b35a-a4c86d7bad60",
1726
- // "allow_deposits":true,
1727
- // "allow_withdrawals":true
1728
- // },
1729
- // ]
1730
- // }
1731
- //
1732
- // v3PrivateGetBrokerageAccounts
1733
- // {
1734
- // "accounts": [
1735
- // {
1736
- // "uuid": "11111111-1111-1111-1111-111111111111",
1737
- // "name": "USDC Wallet",
1738
- // "currency": "USDC",
1739
- // "available_balance": {
1740
- // "value": "0.0000000000000000",
1741
- // "currency": "USDC"
1742
- // },
1743
- // "default": true,
1744
- // "active": true,
1745
- // "created_at": "2023-01-04T06:20:06.456Z",
1746
- // "updated_at": "2023-01-04T06:20:07.181Z",
1747
- // "deleted_at": null,
1748
- // "type": "ACCOUNT_TYPE_CRYPTO",
1749
- // "ready": false,
1750
- // "hold": {
1751
- // "value": "0.0000000000000000",
1752
- // "currency": "USDC"
1753
- // }
1754
- // },
1755
- // ...
1756
- // ],
1757
- // "has_next": false,
1758
- // "cursor": "",
1759
- // "size": 9
1760
- // }
1761
- //
1762
- return this.parseBalance(response, params);
1763
- }
1764
- async fetchLedger(code = undefined, since = undefined, limit = undefined, params = {}) {
1765
- /**
1766
- * @method
1767
- * @name coinbase#fetchLedger
1768
- * @description fetch the history of changes, actions done by the user or operations that altered balance of the user
1769
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#list-transactions
1770
- * @param {string} code unified currency code, default is undefined
1771
- * @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
1772
- * @param {int} [limit] max number of ledger entrys to return, default is undefined
1773
- * @param {object} [params] extra parameters specific to the exchange API endpoint
1774
- * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger-structure}
1775
- */
1776
- await this.loadMarkets();
1777
- let currency = undefined;
1778
- if (code !== undefined) {
1779
- currency = this.currency(code);
1780
- }
1781
- const request = await this.prepareAccountRequestWithCurrencyCode(code, limit, params);
1782
- const query = this.omit(params, ['account_id', 'accountId']);
1783
- // for pagination use parameter 'starting_after'
1784
- // the value for the next page can be obtained from the result of the previous call in the 'pagination' field
1785
- // eg: instance.last_json_response.pagination.next_starting_after
1786
- const response = await this.v2PrivateGetAccountsAccountIdTransactions(this.extend(request, query));
1787
- return this.parseLedger(response['data'], currency, since, limit);
1788
- }
1789
- parseLedgerEntryStatus(status) {
1790
- const types = {
1791
- 'completed': 'ok',
1792
- };
1793
- return this.safeString(types, status, status);
1794
- }
1795
- parseLedgerEntryType(type) {
1796
- const types = {
1797
- 'buy': 'trade',
1798
- 'sell': 'trade',
1799
- 'fiat_deposit': 'transaction',
1800
- 'fiat_withdrawal': 'transaction',
1801
- 'exchange_deposit': 'transaction',
1802
- 'exchange_withdrawal': 'transaction',
1803
- 'send': 'transaction',
1804
- 'pro_deposit': 'transaction',
1805
- 'pro_withdrawal': 'transaction', // crypto deposit (to coinbase from coinbasepro)
1806
- };
1807
- return this.safeString(types, type, type);
1808
- }
1809
- parseLedgerEntry(item, currency = undefined) {
1810
- //
1811
- // crypto deposit transaction
1812
- //
1813
- // {
1814
- // "id": "34e4816b-4c8c-5323-a01c-35a9fa26e490",
1815
- // "type": "send",
1816
- // "status": "completed",
1817
- // "amount": { amount: "28.31976528", currency: "BCH" },
1818
- // "native_amount": { amount: "2799.65", currency: "GBP" },
1819
- // "description": null,
1820
- // "created_at": "2019-02-28T12:35:20Z",
1821
- // "updated_at": "2019-02-28T12:43:24Z",
1822
- // "resource": "transaction",
1823
- // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/34e4816b-4c8c-5323-a01c-35a9fa26e490",
1824
- // "instant_exchange": false,
1825
- // "network": {
1826
- // "status": "confirmed",
1827
- // "hash": "56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701",
1828
- // "transaction_url": "https://bch.btc.com/56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701"
1829
- // },
1830
- // "from": { resource: "bitcoin_cash_network", currency: "BCH" },
1831
- // "details": { title: 'Received Bitcoin Cash', subtitle: "From Bitcoin Cash address" }
1832
- // }
1833
- //
1834
- // crypto withdrawal transaction
1835
- //
1836
- // {
1837
- // "id": "459aad99-2c41-5698-ac71-b6b81a05196c",
1838
- // "type": "send",
1839
- // "status": "completed",
1840
- // "amount": { amount: "-0.36775642", currency: "BTC" },
1841
- // "native_amount": { amount: "-1111.65", currency: "GBP" },
1842
- // "description": null,
1843
- // "created_at": "2019-03-20T08:37:07Z",
1844
- // "updated_at": "2019-03-20T08:49:33Z",
1845
- // "resource": "transaction",
1846
- // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/459aad99-2c41-5698-ac71-b6b81a05196c",
1847
- // "instant_exchange": false,
1848
- // "network": {
1849
- // "status": "confirmed",
1850
- // "hash": "2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b",
1851
- // "transaction_url": "https://blockchain.info/tx/2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b",
1852
- // "transaction_fee": { amount: "0.00000000", currency: "BTC" },
1853
- // "transaction_amount": { amount: "0.36775642", currency: "BTC" },
1854
- // "confirmations": 15682
1855
- // },
1856
- // "to": {
1857
- // "resource": "bitcoin_address",
1858
- // "address": "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX",
1859
- // "currency": "BTC",
1860
- // "address_info": { address: "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX" }
1861
- // },
1862
- // "idem": "da0a2f14-a2af-4c5a-a37e-d4484caf582bsend",
1863
- // "application": {
1864
- // "id": "5756ab6e-836b-553b-8950-5e389451225d",
1865
- // "resource": "application",
1866
- // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
1867
- // },
1868
- // "details": { title: 'Sent Bitcoin', subtitle: "To Bitcoin address" }
1869
- // }
1870
- //
1871
- // withdrawal transaction from coinbase to coinbasepro
1872
- //
1873
- // {
1874
- // "id": "5b1b9fb8-5007-5393-b923-02903b973fdc",
1875
- // "type": "pro_deposit",
1876
- // "status": "completed",
1877
- // "amount": { amount: "-0.00001111", currency: "BCH" },
1878
- // "native_amount": { amount: "0.00", currency: "GBP" },
1879
- // "description": null,
1880
- // "created_at": "2019-02-28T13:31:58Z",
1881
- // "updated_at": "2019-02-28T13:31:58Z",
1882
- // "resource": "transaction",
1883
- // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/5b1b9fb8-5007-5393-b923-02903b973fdc",
1884
- // "instant_exchange": false,
1885
- // "application": {
1886
- // "id": "5756ab6e-836b-553b-8950-5e389451225d",
1887
- // "resource": "application",
1888
- // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
1889
- // },
1890
- // "details": { title: 'Transferred Bitcoin Cash', subtitle: "To Coinbase Pro" }
1891
- // }
1892
- //
1893
- // withdrawal transaction from coinbase to gdax
1894
- //
1895
- // {
1896
- // "id": "badb7313-a9d3-5c07-abd0-00f8b44199b1",
1897
- // "type": "exchange_deposit",
1898
- // "status": "completed",
1899
- // "amount": { amount: "-0.43704149", currency: "BCH" },
1900
- // "native_amount": { amount: "-51.90", currency: "GBP" },
1901
- // "description": null,
1902
- // "created_at": "2019-03-19T10:30:40Z",
1903
- // "updated_at": "2019-03-19T10:30:40Z",
1904
- // "resource": "transaction",
1905
- // "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/badb7313-a9d3-5c07-abd0-00f8b44199b1",
1906
- // "instant_exchange": false,
1907
- // "details": { title: 'Transferred Bitcoin Cash', subtitle: "To GDAX" }
1908
- // }
1909
- //
1910
- // deposit transaction from gdax to coinbase
1911
- //
1912
- // {
1913
- // "id": "9c4b642c-8688-58bf-8962-13cef64097de",
1914
- // "type": "exchange_withdrawal",
1915
- // "status": "completed",
1916
- // "amount": { amount: "0.57729420", currency: "BTC" },
1917
- // "native_amount": { amount: "4418.72", currency: "GBP" },
1918
- // "description": null,
1919
- // "created_at": "2018-02-17T11:33:33Z",
1920
- // "updated_at": "2018-02-17T11:33:33Z",
1921
- // "resource": "transaction",
1922
- // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/9c4b642c-8688-58bf-8962-13cef64097de",
1923
- // "instant_exchange": false,
1924
- // "details": { title: 'Transferred Bitcoin', subtitle: "From GDAX" }
1925
- // }
1926
- //
1927
- // deposit transaction from coinbasepro to coinbase
1928
- //
1929
- // {
1930
- // "id": "8d6dd0b9-3416-568a-889d-8f112fae9e81",
1931
- // "type": "pro_withdrawal",
1932
- // "status": "completed",
1933
- // "amount": { amount: "0.40555386", currency: "BTC" },
1934
- // "native_amount": { amount: "1140.27", currency: "GBP" },
1935
- // "description": null,
1936
- // "created_at": "2019-03-04T19:41:58Z",
1937
- // "updated_at": "2019-03-04T19:41:58Z",
1938
- // "resource": "transaction",
1939
- // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/8d6dd0b9-3416-568a-889d-8f112fae9e81",
1940
- // "instant_exchange": false,
1941
- // "application": {
1942
- // "id": "5756ab6e-836b-553b-8950-5e389451225d",
1943
- // "resource": "application",
1944
- // "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
1945
- // },
1946
- // "details": { title: 'Transferred Bitcoin', subtitle: "From Coinbase Pro" }
1947
- // }
1948
- //
1949
- // sell trade
1950
- //
1951
- // {
1952
- // "id": "a9409207-df64-585b-97ab-a50780d2149e",
1953
- // "type": "sell",
1954
- // "status": "completed",
1955
- // "amount": { amount: "-9.09922880", currency: "BTC" },
1956
- // "native_amount": { amount: "-7285.73", currency: "GBP" },
1957
- // "description": null,
1958
- // "created_at": "2017-03-27T15:38:34Z",
1959
- // "updated_at": "2017-03-27T15:38:34Z",
1960
- // "resource": "transaction",
1961
- // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/a9409207-df64-585b-97ab-a50780d2149e",
1962
- // "instant_exchange": false,
1963
- // "sell": {
1964
- // "id": "e3550b4d-8ae6-5de3-95fe-1fb01ba83051",
1965
- // "resource": "sell",
1966
- // "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/sells/e3550b4d-8ae6-5de3-95fe-1fb01ba83051"
1967
- // },
1968
- // "details": {
1969
- // "title": "Sold Bitcoin",
1970
- // "subtitle": "Using EUR Wallet",
1971
- // "payment_method_name": "EUR Wallet"
1972
- // }
1973
- // }
1974
- //
1975
- // buy trade
1976
- //
1977
- // {
1978
- // "id": "63eeed67-9396-5912-86e9-73c4f10fe147",
1979
- // "type": "buy",
1980
- // "status": "completed",
1981
- // "amount": { amount: "2.39605772", currency: "ETH" },
1982
- // "native_amount": { amount: "98.31", currency: "GBP" },
1983
- // "description": null,
1984
- // "created_at": "2017-03-27T09:07:56Z",
1985
- // "updated_at": "2017-03-27T09:07:57Z",
1986
- // "resource": "transaction",
1987
- // "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/transactions/63eeed67-9396-5912-86e9-73c4f10fe147",
1988
- // "instant_exchange": false,
1989
- // "buy": {
1990
- // "id": "20b25b36-76c6-5353-aa57-b06a29a39d82",
1991
- // "resource": "buy",
1992
- // "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/buys/20b25b36-76c6-5353-aa57-b06a29a39d82"
1993
- // },
1994
- // "details": {
1995
- // "title": "Bought Ethereum",
1996
- // "subtitle": "Using EUR Wallet",
1997
- // "payment_method_name": "EUR Wallet"
1998
- // }
1999
- // }
2000
- //
2001
- // fiat deposit transaction
2002
- //
2003
- // {
2004
- // "id": "04ed4113-3732-5b0c-af86-b1d2146977d0",
2005
- // "type": "fiat_deposit",
2006
- // "status": "completed",
2007
- // "amount": { amount: "114.02", currency: "EUR" },
2008
- // "native_amount": { amount: "97.23", currency: "GBP" },
2009
- // "description": null,
2010
- // "created_at": "2017-02-09T07:01:21Z",
2011
- // "updated_at": "2017-02-09T07:01:22Z",
2012
- // "resource": "transaction",
2013
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86-b1d2146977d0",
2014
- // "instant_exchange": false,
2015
- // "fiat_deposit": {
2016
- // "id": "f34c19f3-b730-5e3d-9f72-96520448677a",
2017
- // "resource": "fiat_deposit",
2018
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72-96520448677a"
2019
- // },
2020
- // "details": {
2021
- // "title": "Deposited funds",
2022
- // "subtitle": "From SEPA Transfer (GB47 BARC 20..., reference CBADVI)",
2023
- // "payment_method_name": "SEPA Transfer (GB47 BARC 20..., reference CBADVI)"
2024
- // }
2025
- // }
2026
- //
2027
- // fiat withdrawal transaction
2028
- //
2029
- // {
2030
- // "id": "957d98e2-f80e-5e2f-a28e-02945aa93079",
2031
- // "type": "fiat_withdrawal",
2032
- // "status": "completed",
2033
- // "amount": { amount: "-11000.00", currency: "EUR" },
2034
- // "native_amount": { amount: "-9698.22", currency: "GBP" },
2035
- // "description": null,
2036
- // "created_at": "2017-12-06T13:19:19Z",
2037
- // "updated_at": "2017-12-06T13:19:19Z",
2038
- // "resource": "transaction",
2039
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/957d98e2-f80e-5e2f-a28e-02945aa93079",
2040
- // "instant_exchange": false,
2041
- // "fiat_withdrawal": {
2042
- // "id": "f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7",
2043
- // "resource": "fiat_withdrawal",
2044
- // "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7"
2045
- // },
2046
- // "details": {
2047
- // "title": "Withdrew funds",
2048
- // "subtitle": "To HSBC BANK PLC (GB74 MIDL...)",
2049
- // "payment_method_name": "HSBC BANK PLC (GB74 MIDL...)"
2050
- // }
2051
- // }
2052
- //
2053
- const amountInfo = this.safeValue(item, 'amount', {});
2054
- let amount = this.safeString(amountInfo, 'amount');
2055
- let direction = undefined;
2056
- if (Precise["default"].stringLt(amount, '0')) {
2057
- direction = 'out';
2058
- amount = Precise["default"].stringNeg(amount);
2059
- }
2060
- else {
2061
- direction = 'in';
2062
- }
2063
- const currencyId = this.safeString(amountInfo, 'currency');
2064
- const code = this.safeCurrencyCode(currencyId, currency);
2065
- //
2066
- // the address and txid do not belong to the unified ledger structure
2067
- //
2068
- // let address = undefined;
2069
- // if (item['to']) {
2070
- // address = this.safeString (item['to'], 'address');
2071
- // }
2072
- // let txid = undefined;
2073
- //
2074
- let fee = undefined;
2075
- const networkInfo = this.safeValue(item, 'network', {});
2076
- // txid = network['hash']; // txid does not belong to the unified ledger structure
2077
- const feeInfo = this.safeValue(networkInfo, 'transaction_fee');
2078
- if (feeInfo !== undefined) {
2079
- const feeCurrencyId = this.safeString(feeInfo, 'currency');
2080
- const feeCurrencyCode = this.safeCurrencyCode(feeCurrencyId, currency);
2081
- const feeAmount = this.safeNumber(feeInfo, 'amount');
2082
- fee = {
2083
- 'cost': feeAmount,
2084
- 'currency': feeCurrencyCode,
2085
- };
2086
- }
2087
- const timestamp = this.parse8601(this.safeValue(item, 'created_at'));
2088
- const id = this.safeString(item, 'id');
2089
- const type = this.parseLedgerEntryType(this.safeString(item, 'type'));
2090
- const status = this.parseLedgerEntryStatus(this.safeString(item, 'status'));
2091
- const path = this.safeString(item, 'resource_path');
2092
- let accountId = undefined;
2093
- if (path !== undefined) {
2094
- const parts = path.split('/');
2095
- const numParts = parts.length;
2096
- if (numParts > 3) {
2097
- accountId = parts[3];
2098
- }
2099
- }
2100
- return {
2101
- 'info': item,
2102
- 'id': id,
2103
- 'timestamp': timestamp,
2104
- 'datetime': this.iso8601(timestamp),
2105
- 'direction': direction,
2106
- 'account': accountId,
2107
- 'referenceId': undefined,
2108
- 'referenceAccount': undefined,
2109
- 'type': type,
2110
- 'currency': code,
2111
- 'amount': this.parseNumber(amount),
2112
- 'before': undefined,
2113
- 'after': undefined,
2114
- 'status': status,
2115
- 'fee': fee,
2116
- };
2117
- }
2118
- async findAccountId(code) {
2119
- await this.loadMarkets();
2120
- await this.loadAccounts();
2121
- for (let i = 0; i < this.accounts.length; i++) {
2122
- const account = this.accounts[i];
2123
- if (account['code'] === code) {
2124
- return account['id'];
2125
- }
2126
- }
2127
- return undefined;
2128
- }
2129
- prepareAccountRequest(limit = undefined, params = {}) {
2130
- const accountId = this.safeString2(params, 'account_id', 'accountId');
2131
- if (accountId === undefined) {
2132
- throw new errors.ArgumentsRequired(this.id + ' prepareAccountRequest() method requires an account_id (or accountId) parameter');
2133
- }
2134
- const request = {
2135
- 'account_id': accountId,
2136
- };
2137
- if (limit !== undefined) {
2138
- request['limit'] = limit;
2139
- }
2140
- return request;
2141
- }
2142
- async prepareAccountRequestWithCurrencyCode(code = undefined, limit = undefined, params = {}) {
2143
- let accountId = this.safeString2(params, 'account_id', 'accountId');
2144
- if (accountId === undefined) {
2145
- if (code === undefined) {
2146
- throw new errors.ArgumentsRequired(this.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id (or accountId) parameter OR a currency code argument');
2147
- }
2148
- accountId = await this.findAccountId(code);
2149
- if (accountId === undefined) {
2150
- throw new errors.ExchangeError(this.id + ' prepareAccountRequestWithCurrencyCode() could not find account id for ' + code);
2151
- }
2152
- }
2153
- const request = {
2154
- 'account_id': accountId,
2155
- };
2156
- if (limit !== undefined) {
2157
- request['limit'] = limit;
2158
- }
2159
- return request;
2160
- }
2161
- async createMarketBuyOrderWithCost(symbol, cost, params = {}) {
2162
- /**
2163
- * @method
2164
- * @name coinbase#createMarketBuyOrderWithCost
2165
- * @description create a market buy order by providing the symbol and cost
2166
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_postorder
2167
- * @param {string} symbol unified symbol of the market to create an order in
2168
- * @param {float} cost how much you want to trade in units of the quote currency
2169
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2170
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2171
- */
2172
- await this.loadMarkets();
2173
- const market = this.market(symbol);
2174
- if (!market['spot']) {
2175
- throw new errors.NotSupported(this.id + ' createMarketBuyOrderWithCost() supports spot orders only');
2176
- }
2177
- params['createMarketBuyOrderRequiresPrice'] = false;
2178
- return await this.createOrder(symbol, 'market', 'buy', cost, undefined, params);
2179
- }
2180
- async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
2181
- /**
2182
- * @method
2183
- * @name coinbase#createOrder
2184
- * @description create a trade order
2185
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_postorder
2186
- * @param {string} symbol unified symbol of the market to create an order in
2187
- * @param {string} type 'market' or 'limit'
2188
- * @param {string} side 'buy' or 'sell'
2189
- * @param {float} amount how much you want to trade in units of the base currency, quote currency for 'market' 'buy' orders
2190
- * @param {float} [price] the price to fulfill the order, in units of the quote currency, ignored in market orders
2191
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2192
- * @param {float} [params.stopPrice] price to trigger stop orders
2193
- * @param {float} [params.triggerPrice] price to trigger stop orders
2194
- * @param {float} [params.stopLossPrice] price to trigger stop-loss orders
2195
- * @param {float} [params.takeProfitPrice] price to trigger take-profit orders
2196
- * @param {bool} [params.postOnly] true or false
2197
- * @param {string} [params.timeInForce] 'GTC', 'IOC', 'GTD' or 'PO'
2198
- * @param {string} [params.stop_direction] 'UNKNOWN_STOP_DIRECTION', 'STOP_DIRECTION_STOP_UP', 'STOP_DIRECTION_STOP_DOWN' the direction the stopPrice is triggered from
2199
- * @param {string} [params.end_time] '2023-05-25T17:01:05.092Z' for 'GTD' orders
2200
- * @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
2201
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2202
- */
2203
- await this.loadMarkets();
2204
- const market = this.market(symbol);
2205
- const request = {
2206
- 'client_order_id': this.uuid(),
2207
- 'product_id': market['id'],
2208
- 'side': side.toUpperCase(),
2209
- };
2210
- const stopPrice = this.safeNumberN(params, ['stopPrice', 'stop_price', 'triggerPrice']);
2211
- const stopLossPrice = this.safeNumber(params, 'stopLossPrice');
2212
- const takeProfitPrice = this.safeNumber(params, 'takeProfitPrice');
2213
- const isStop = stopPrice !== undefined;
2214
- const isStopLoss = stopLossPrice !== undefined;
2215
- const isTakeProfit = takeProfitPrice !== undefined;
2216
- const timeInForce = this.safeString(params, 'timeInForce');
2217
- const postOnly = (timeInForce === 'PO') ? true : this.safeValue2(params, 'postOnly', 'post_only', false);
2218
- const endTime = this.safeString(params, 'end_time');
2219
- let stopDirection = this.safeString(params, 'stop_direction');
2220
- if (type === 'limit') {
2221
- if (isStop) {
2222
- if (stopDirection === undefined) {
2223
- stopDirection = (side === 'buy') ? 'STOP_DIRECTION_STOP_DOWN' : 'STOP_DIRECTION_STOP_UP';
2224
- }
2225
- if ((timeInForce === 'GTD') || (endTime !== undefined)) {
2226
- if (endTime === undefined) {
2227
- throw new errors.ExchangeError(this.id + ' createOrder() requires an end_time parameter for a GTD order');
2228
- }
2229
- request['order_configuration'] = {
2230
- 'stop_limit_stop_limit_gtd': {
2231
- 'base_size': this.amountToPrecision(symbol, amount),
2232
- 'limit_price': this.priceToPrecision(symbol, price),
2233
- 'stop_price': this.priceToPrecision(symbol, stopPrice),
2234
- 'stop_direction': stopDirection,
2235
- 'end_time': endTime,
2236
- },
2237
- };
2238
- }
2239
- else {
2240
- request['order_configuration'] = {
2241
- 'stop_limit_stop_limit_gtc': {
2242
- 'base_size': this.amountToPrecision(symbol, amount),
2243
- 'limit_price': this.priceToPrecision(symbol, price),
2244
- 'stop_price': this.priceToPrecision(symbol, stopPrice),
2245
- 'stop_direction': stopDirection,
2246
- },
2247
- };
2248
- }
2249
- }
2250
- else if (isStopLoss || isTakeProfit) {
2251
- let triggerPrice = undefined;
2252
- if (isStopLoss) {
2253
- if (stopDirection === undefined) {
2254
- stopDirection = (side === 'buy') ? 'STOP_DIRECTION_STOP_UP' : 'STOP_DIRECTION_STOP_DOWN';
2255
- }
2256
- triggerPrice = this.priceToPrecision(symbol, stopLossPrice);
2257
- }
2258
- else {
2259
- if (stopDirection === undefined) {
2260
- stopDirection = (side === 'buy') ? 'STOP_DIRECTION_STOP_DOWN' : 'STOP_DIRECTION_STOP_UP';
2261
- }
2262
- triggerPrice = this.priceToPrecision(symbol, takeProfitPrice);
2263
- }
2264
- request['order_configuration'] = {
2265
- 'stop_limit_stop_limit_gtc': {
2266
- 'base_size': this.amountToPrecision(symbol, amount),
2267
- 'limit_price': this.priceToPrecision(symbol, price),
2268
- 'stop_price': triggerPrice,
2269
- 'stop_direction': stopDirection,
2270
- },
2271
- };
2272
- }
2273
- else {
2274
- if ((timeInForce === 'GTD') || (endTime !== undefined)) {
2275
- if (endTime === undefined) {
2276
- throw new errors.ExchangeError(this.id + ' createOrder() requires an end_time parameter for a GTD order');
2277
- }
2278
- request['order_configuration'] = {
2279
- 'limit_limit_gtd': {
2280
- 'base_size': this.amountToPrecision(symbol, amount),
2281
- 'limit_price': this.priceToPrecision(symbol, price),
2282
- 'end_time': endTime,
2283
- 'post_only': postOnly,
2284
- },
2285
- };
2286
- }
2287
- else {
2288
- request['order_configuration'] = {
2289
- 'limit_limit_gtc': {
2290
- 'base_size': this.amountToPrecision(symbol, amount),
2291
- 'limit_price': this.priceToPrecision(symbol, price),
2292
- 'post_only': postOnly,
2293
- },
2294
- };
2295
- }
2296
- }
2297
- }
2298
- else {
2299
- if (isStop || isStopLoss || isTakeProfit) {
2300
- throw new errors.NotSupported(this.id + ' createOrder() only stop limit orders are supported');
2301
- }
2302
- if (side === 'buy') {
2303
- let total = undefined;
2304
- let createMarketBuyOrderRequiresPrice = true;
2305
- [createMarketBuyOrderRequiresPrice, params] = this.handleOptionAndParams(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', true);
2306
- const cost = this.safeNumber(params, 'cost');
2307
- params = this.omit(params, 'cost');
2308
- if (cost !== undefined) {
2309
- total = this.costToPrecision(symbol, cost);
2310
- }
2311
- else if (createMarketBuyOrderRequiresPrice) {
2312
- if (price === undefined) {
2313
- throw new errors.InvalidOrder(this.id + ' createOrder() requires a price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument');
2314
- }
2315
- else {
2316
- const amountString = this.numberToString(amount);
2317
- const priceString = this.numberToString(price);
2318
- const costRequest = Precise["default"].stringMul(amountString, priceString);
2319
- total = this.costToPrecision(symbol, costRequest);
2320
- }
2321
- }
2322
- else {
2323
- total = this.costToPrecision(symbol, amount);
2324
- }
2325
- request['order_configuration'] = {
2326
- 'market_market_ioc': {
2327
- 'quote_size': total,
2328
- },
2329
- };
2330
- }
2331
- else {
2332
- request['order_configuration'] = {
2333
- 'market_market_ioc': {
2334
- 'base_size': this.amountToPrecision(symbol, amount),
2335
- },
2336
- };
2337
- }
2338
- }
2339
- params = this.omit(params, ['timeInForce', 'triggerPrice', 'stopLossPrice', 'takeProfitPrice', 'stopPrice', 'stop_price', 'stopDirection', 'stop_direction', 'clientOrderId', 'postOnly', 'post_only', 'end_time']);
2340
- const response = await this.v3PrivatePostBrokerageOrders(this.extend(request, params));
2341
- //
2342
- // successful order
2343
- //
2344
- // {
2345
- // "success": true,
2346
- // "failure_reason": "UNKNOWN_FAILURE_REASON",
2347
- // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
2348
- // "success_response": {
2349
- // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
2350
- // "product_id": "LTC-BTC",
2351
- // "side": "SELL",
2352
- // "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288"
2353
- // },
2354
- // "order_configuration": null
2355
- // }
2356
- //
2357
- // failed order
2358
- //
2359
- // {
2360
- // "success": false,
2361
- // "failure_reason": "UNKNOWN_FAILURE_REASON",
2362
- // "order_id": "",
2363
- // "error_response": {
2364
- // "error": "UNSUPPORTED_ORDER_CONFIGURATION",
2365
- // "message": "source is not enabled for trading",
2366
- // "error_details": "",
2367
- // "new_order_failure_reason": "UNSUPPORTED_ORDER_CONFIGURATION"
2368
- // },
2369
- // "order_configuration": {
2370
- // "limit_limit_gtc": {
2371
- // "base_size": "100",
2372
- // "limit_price": "40000",
2373
- // "post_only": false
2374
- // }
2375
- // }
2376
- // }
2377
- //
2378
- const success = this.safeValue(response, 'success');
2379
- if (success !== true) {
2380
- const errorResponse = this.safeValue(response, 'error_response');
2381
- const errorTitle = this.safeString(errorResponse, 'error');
2382
- const errorMessage = this.safeString(errorResponse, 'message');
2383
- if (errorResponse !== undefined) {
2384
- this.throwExactlyMatchedException(this.exceptions['exact'], errorTitle, errorMessage);
2385
- this.throwBroadlyMatchedException(this.exceptions['broad'], errorTitle, errorMessage);
2386
- throw new errors.ExchangeError(errorMessage);
2387
- }
2388
- }
2389
- const data = this.safeValue(response, 'success_response', {});
2390
- return this.parseOrder(data, market);
2391
- }
2392
- parseOrder(order, market = undefined) {
2393
- //
2394
- // createOrder
2395
- //
2396
- // {
2397
- // "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
2398
- // "product_id": "LTC-BTC",
2399
- // "side": "SELL",
2400
- // "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288"
2401
- // }
2402
- //
2403
- // cancelOrder, cancelOrders
2404
- //
2405
- // {
2406
- // "success": true,
2407
- // "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON",
2408
- // "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d"
2409
- // }
2410
- //
2411
- // fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders
2412
- //
2413
- // {
2414
- // "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b",
2415
- // "product_id": "LTC-BTC",
2416
- // "user_id": "1111111-1111-1111-1111-111111111111",
2417
- // "order_configuration": {
2418
- // "limit_limit_gtc": {
2419
- // "base_size": "0.2",
2420
- // "limit_price": "0.006",
2421
- // "post_only": false
2422
- // },
2423
- // "stop_limit_stop_limit_gtc": {
2424
- // "base_size": "48.54",
2425
- // "limit_price": "6.998",
2426
- // "stop_price": "7.0687",
2427
- // "stop_direction": "STOP_DIRECTION_STOP_DOWN"
2428
- // }
2429
- // },
2430
- // "side": "SELL",
2431
- // "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c",
2432
- // "status": "OPEN",
2433
- // "time_in_force": "GOOD_UNTIL_CANCELLED",
2434
- // "created_time": "2023-01-16T23:37:23.947030Z",
2435
- // "completion_percentage": "0",
2436
- // "filled_size": "0",
2437
- // "average_filled_price": "0",
2438
- // "fee": "",
2439
- // "number_of_fills": "0",
2440
- // "filled_value": "0",
2441
- // "pending_cancel": false,
2442
- // "size_in_quote": false,
2443
- // "total_fees": "0",
2444
- // "size_inclusive_of_fees": false,
2445
- // "total_value_after_fees": "0",
2446
- // "trigger_status": "INVALID_ORDER_TYPE",
2447
- // "order_type": "LIMIT",
2448
- // "reject_reason": "REJECT_REASON_UNSPECIFIED",
2449
- // "settled": false,
2450
- // "product_type": "SPOT",
2451
- // "reject_message": "",
2452
- // "cancel_message": ""
2453
- // }
2454
- //
2455
- const marketId = this.safeString(order, 'product_id');
2456
- const symbol = this.safeSymbol(marketId, market, '-');
2457
- if (symbol !== undefined) {
2458
- market = this.market(symbol);
2459
- }
2460
- const orderConfiguration = this.safeValue(order, 'order_configuration', {});
2461
- const limitGTC = this.safeValue(orderConfiguration, 'limit_limit_gtc');
2462
- const limitGTD = this.safeValue(orderConfiguration, 'limit_limit_gtd');
2463
- const stopLimitGTC = this.safeValue(orderConfiguration, 'stop_limit_stop_limit_gtc');
2464
- const stopLimitGTD = this.safeValue(orderConfiguration, 'stop_limit_stop_limit_gtd');
2465
- const marketIOC = this.safeValue(orderConfiguration, 'market_market_ioc');
2466
- const isLimit = ((limitGTC !== undefined) || (limitGTD !== undefined));
2467
- const isStop = ((stopLimitGTC !== undefined) || (stopLimitGTD !== undefined));
2468
- let price = undefined;
2469
- let amount = undefined;
2470
- let postOnly = undefined;
2471
- let triggerPrice = undefined;
2472
- if (isLimit) {
2473
- const target = (limitGTC !== undefined) ? limitGTC : limitGTD;
2474
- price = this.safeString(target, 'limit_price');
2475
- amount = this.safeString(target, 'base_size');
2476
- postOnly = this.safeValue(target, 'post_only');
2477
- }
2478
- else if (isStop) {
2479
- const stopTarget = (stopLimitGTC !== undefined) ? stopLimitGTC : stopLimitGTD;
2480
- price = this.safeString(stopTarget, 'limit_price');
2481
- amount = this.safeString(stopTarget, 'base_size');
2482
- postOnly = this.safeValue(stopTarget, 'post_only');
2483
- triggerPrice = this.safeString(stopTarget, 'stop_price');
2484
- }
2485
- else {
2486
- amount = this.safeString(marketIOC, 'base_size');
2487
- }
2488
- const datetime = this.safeString(order, 'created_time');
2489
- const totalFees = this.safeString(order, 'total_fees');
2490
- let currencyFee = undefined;
2491
- if ((totalFees !== undefined) && (market !== undefined)) {
2492
- currencyFee = market['quote'];
2493
- }
2494
- return this.safeOrder({
2495
- 'info': order,
2496
- 'id': this.safeString(order, 'order_id'),
2497
- 'clientOrderId': this.safeString(order, 'client_order_id'),
2498
- 'timestamp': this.parse8601(datetime),
2499
- 'datetime': datetime,
2500
- 'lastTradeTimestamp': undefined,
2501
- 'symbol': symbol,
2502
- 'type': this.parseOrderType(this.safeString(order, 'order_type')),
2503
- 'timeInForce': this.parseTimeInForce(this.safeString(order, 'time_in_force')),
2504
- 'postOnly': postOnly,
2505
- 'side': this.safeStringLower(order, 'side'),
2506
- 'price': price,
2507
- 'stopPrice': triggerPrice,
2508
- 'triggerPrice': triggerPrice,
2509
- 'amount': amount,
2510
- 'filled': this.safeString(order, 'filled_size'),
2511
- 'remaining': undefined,
2512
- 'cost': undefined,
2513
- 'average': this.safeString(order, 'average_filled_price'),
2514
- 'status': this.parseOrderStatus(this.safeString(order, 'status')),
2515
- 'fee': {
2516
- 'cost': this.safeString(order, 'total_fees'),
2517
- 'currency': currencyFee,
2518
- },
2519
- 'trades': undefined,
2520
- }, market);
2521
- }
2522
- parseOrderStatus(status) {
2523
- const statuses = {
2524
- 'OPEN': 'open',
2525
- 'FILLED': 'closed',
2526
- 'CANCELLED': 'canceled',
2527
- 'EXPIRED': 'canceled',
2528
- 'FAILED': 'canceled',
2529
- 'UNKNOWN_ORDER_STATUS': undefined,
2530
- };
2531
- return this.safeString(statuses, status, status);
2532
- }
2533
- parseOrderType(type) {
2534
- if (type === 'UNKNOWN_ORDER_TYPE') {
2535
- return undefined;
2536
- }
2537
- const types = {
2538
- 'MARKET': 'market',
2539
- 'LIMIT': 'limit',
2540
- 'STOP': 'limit',
2541
- 'STOP_LIMIT': 'limit',
2542
- };
2543
- return this.safeString(types, type, type);
2544
- }
2545
- parseTimeInForce(timeInForce) {
2546
- const timeInForces = {
2547
- 'GOOD_UNTIL_CANCELLED': 'GTC',
2548
- 'GOOD_UNTIL_DATE_TIME': 'GTD',
2549
- 'IMMEDIATE_OR_CANCEL': 'IOC',
2550
- 'FILL_OR_KILL': 'FOK',
2551
- 'UNKNOWN_TIME_IN_FORCE': undefined,
2552
- };
2553
- return this.safeString(timeInForces, timeInForce, timeInForce);
2554
- }
2555
- async cancelOrder(id, symbol = undefined, params = {}) {
2556
- /**
2557
- * @method
2558
- * @name coinbase#cancelOrder
2559
- * @description cancels an open order
2560
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_cancelorders
2561
- * @param {string} id order id
2562
- * @param {string} symbol not used by coinbase cancelOrder()
2563
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2564
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2565
- */
2566
- await this.loadMarkets();
2567
- const orders = await this.cancelOrders([id], symbol, params);
2568
- return this.safeValue(orders, 0, {});
2569
- }
2570
- async cancelOrders(ids, symbol = undefined, params = {}) {
2571
- /**
2572
- * @method
2573
- * @name coinbase#cancelOrders
2574
- * @description cancel multiple orders
2575
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_cancelorders
2576
- * @param {string[]} ids order ids
2577
- * @param {string} symbol not used by coinbase cancelOrders()
2578
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2579
- * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2580
- */
2581
- await this.loadMarkets();
2582
- let market = undefined;
2583
- if (symbol !== undefined) {
2584
- market = this.market(symbol);
2585
- }
2586
- const request = {
2587
- 'order_ids': ids,
2588
- };
2589
- const response = await this.v3PrivatePostBrokerageOrdersBatchCancel(this.extend(request, params));
2590
- //
2591
- // {
2592
- // "results": [
2593
- // {
2594
- // "success": true,
2595
- // "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON",
2596
- // "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d"
2597
- // }
2598
- // ]
2599
- // }
2600
- //
2601
- const orders = this.safeValue(response, 'results', []);
2602
- for (let i = 0; i < orders.length; i++) {
2603
- const success = this.safeValue(orders[i], 'success');
2604
- if (success !== true) {
2605
- throw new errors.BadRequest(this.id + ' cancelOrders() has failed, check your arguments and parameters');
2606
- }
2607
- }
2608
- return this.parseOrders(orders, market);
2609
- }
2610
- async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
2611
- /**
2612
- * @method
2613
- * @name coinbase#editOrder
2614
- * @description edit a trade order
2615
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_editorder
2616
- * @param {string} id cancel order id
2617
- * @param {string} symbol unified symbol of the market to create an order in
2618
- * @param {string} type 'market' or 'limit'
2619
- * @param {string} side 'buy' or 'sell'
2620
- * @param {float} amount how much of currency you want to trade in units of base currency
2621
- * @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
2622
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2623
- * @param {boolean} [params.preview] default to false, wether to use the test/preview endpoint or not
2624
- * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2625
- */
2626
- await this.loadMarkets();
2627
- const market = this.market(symbol);
2628
- const request = {
2629
- 'order_id': id,
2630
- };
2631
- if (amount !== undefined) {
2632
- request['size'] = this.amountToPrecision(symbol, amount);
2633
- }
2634
- if (price !== undefined) {
2635
- request['price'] = this.priceToPrecision(symbol, price);
2636
- }
2637
- const preview = this.safeValue2(params, 'preview', 'test', false);
2638
- let response = undefined;
2639
- if (preview) {
2640
- params = this.omit(params, ['preview', 'test']);
2641
- response = await this.v3PrivatePostBrokerageOrdersEditPreview(this.extend(request, params));
2642
- }
2643
- else {
2644
- response = await this.v3PrivatePostBrokerageOrdersEdit(this.extend(request, params));
2645
- }
2646
- //
2647
- // {
2648
- // "success": true,
2649
- // "errors": {
2650
- // "edit_failure_reason": "UNKNOWN_EDIT_ORDER_FAILURE_REASON",
2651
- // "preview_failure_reason": "UNKNOWN_PREVIEW_FAILURE_REASON"
2652
- // }
2653
- // }
2654
- //
2655
- return this.parseOrder(response, market);
2656
- }
2657
- async fetchOrder(id, symbol = undefined, params = {}) {
2658
- /**
2659
- * @method
2660
- * @name coinbase#fetchOrder
2661
- * @description fetches information on an order made by the user
2662
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorder
2663
- * @param {string} id the order id
2664
- * @param {string} symbol unified market symbol that the order was made in
2665
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2666
- * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
2667
- */
2668
- await this.loadMarkets();
2669
- let market = undefined;
2670
- if (symbol !== undefined) {
2671
- market = this.market(symbol);
2672
- }
2673
- const request = {
2674
- 'order_id': id,
2675
- };
2676
- const response = await this.v3PrivateGetBrokerageOrdersHistoricalOrderId(this.extend(request, params));
2677
- //
2678
- // {
2679
- // "order": {
2680
- // "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b",
2681
- // "product_id": "LTC-BTC",
2682
- // "user_id": "1111111-1111-1111-1111-111111111111",
2683
- // "order_configuration": {
2684
- // "limit_limit_gtc": {
2685
- // "base_size": "0.2",
2686
- // "limit_price": "0.006",
2687
- // "post_only": false
2688
- // }
2689
- // },
2690
- // "side": "SELL",
2691
- // "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c",
2692
- // "status": "OPEN",
2693
- // "time_in_force": "GOOD_UNTIL_CANCELLED",
2694
- // "created_time": "2023-01-16T23:37:23.947030Z",
2695
- // "completion_percentage": "0",
2696
- // "filled_size": "0",
2697
- // "average_filled_price": "0",
2698
- // "fee": "",
2699
- // "number_of_fills": "0",
2700
- // "filled_value": "0",
2701
- // "pending_cancel": false,
2702
- // "size_in_quote": false,
2703
- // "total_fees": "0",
2704
- // "size_inclusive_of_fees": false,
2705
- // "total_value_after_fees": "0",
2706
- // "trigger_status": "INVALID_ORDER_TYPE",
2707
- // "order_type": "LIMIT",
2708
- // "reject_reason": "REJECT_REASON_UNSPECIFIED",
2709
- // "settled": false,
2710
- // "product_type": "SPOT",
2711
- // "reject_message": "",
2712
- // "cancel_message": ""
2713
- // }
2714
- // }
2715
- //
2716
- const order = this.safeValue(response, 'order', {});
2717
- return this.parseOrder(order, market);
2718
- }
2719
- async fetchOrders(symbol = undefined, since = undefined, limit = 100, params = {}) {
2720
- /**
2721
- * @method
2722
- * @name coinbase#fetchOrders
2723
- * @description fetches information on multiple orders made by the user
2724
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
2725
- * @param {string} symbol unified market symbol that the orders were made in
2726
- * @param {int} [since] the earliest time in ms to fetch orders
2727
- * @param {int} [limit] the maximum number of order structures to retrieve
2728
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2729
- * @param {int} [params.until] the latest time in ms to fetch trades for
2730
- * @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)
2731
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2732
- */
2733
- await this.loadMarkets();
2734
- let paginate = false;
2735
- [paginate, params] = this.handleOptionAndParams(params, 'fetchOrders', 'paginate');
2736
- if (paginate) {
2737
- return await this.fetchPaginatedCallCursor('fetchOrders', symbol, since, limit, params, 'cursor', 'cursor', undefined, 100);
2738
- }
2739
- let market = undefined;
2740
- if (symbol !== undefined) {
2741
- market = this.market(symbol);
2742
- }
2743
- const request = {};
2744
- if (market !== undefined) {
2745
- request['product_id'] = market['id'];
2746
- }
2747
- if (limit !== undefined) {
2748
- request['limit'] = limit;
2749
- }
2750
- if (since !== undefined) {
2751
- request['start_date'] = this.iso8601(since);
2752
- }
2753
- const until = this.safeValueN(params, ['until', 'till']);
2754
- if (until !== undefined) {
2755
- params = this.omit(params, ['until', 'till']);
2756
- request['end_date'] = this.iso8601(until);
2757
- }
2758
- const response = await this.v3PrivateGetBrokerageOrdersHistoricalBatch(this.extend(request, params));
2759
- //
2760
- // {
2761
- // "orders": [
2762
- // {
2763
- // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
2764
- // "product_id": "BTC-USDT",
2765
- // "user_id": "1111111-1111-1111-1111-111111111111",
2766
- // "order_configuration": {
2767
- // "market_market_ioc": {
2768
- // "quote_size": "6.36"
2769
- // }
2770
- // },
2771
- // "side": "BUY",
2772
- // "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317",
2773
- // "status": "FILLED",
2774
- // "time_in_force": "IMMEDIATE_OR_CANCEL",
2775
- // "created_time": "2023-01-18T01:37:37.975552Z",
2776
- // "completion_percentage": "100",
2777
- // "filled_size": "0.000297920684505",
2778
- // "average_filled_price": "21220.6399999973697697",
2779
- // "fee": "",
2780
- // "number_of_fills": "2",
2781
- // "filled_value": "6.3220675944333996",
2782
- // "pending_cancel": false,
2783
- // "size_in_quote": true,
2784
- // "total_fees": "0.0379324055666004",
2785
- // "size_inclusive_of_fees": true,
2786
- // "total_value_after_fees": "6.36",
2787
- // "trigger_status": "INVALID_ORDER_TYPE",
2788
- // "order_type": "MARKET",
2789
- // "reject_reason": "REJECT_REASON_UNSPECIFIED",
2790
- // "settled": true,
2791
- // "product_type": "SPOT",
2792
- // "reject_message": "",
2793
- // "cancel_message": "Internal error"
2794
- // },
2795
- // ],
2796
- // "sequence": "0",
2797
- // "has_next": false,
2798
- // "cursor": ""
2799
- // }
2800
- //
2801
- const orders = this.safeValue(response, 'orders', []);
2802
- const first = this.safeValue(orders, 0);
2803
- const cursor = this.safeString(response, 'cursor');
2804
- if ((cursor !== undefined) && (cursor !== '')) {
2805
- first['cursor'] = cursor;
2806
- orders[0] = first;
2807
- }
2808
- return this.parseOrders(orders, market, since, limit);
2809
- }
2810
- async fetchOrdersByStatus(status, symbol = undefined, since = undefined, limit = undefined, params = {}) {
2811
- await this.loadMarkets();
2812
- let market = undefined;
2813
- if (symbol !== undefined) {
2814
- market = this.market(symbol);
2815
- }
2816
- const request = {
2817
- 'order_status': status,
2818
- };
2819
- if (market !== undefined) {
2820
- request['product_id'] = market['id'];
2821
- }
2822
- if (limit === undefined) {
2823
- limit = 100;
2824
- }
2825
- request['limit'] = limit;
2826
- if (since !== undefined) {
2827
- request['start_date'] = this.iso8601(since);
2828
- }
2829
- const until = this.safeValueN(params, ['until', 'till']);
2830
- if (until !== undefined) {
2831
- params = this.omit(params, ['until', 'till']);
2832
- request['end_date'] = this.iso8601(until);
2833
- }
2834
- const response = await this.v3PrivateGetBrokerageOrdersHistoricalBatch(this.extend(request, params));
2835
- //
2836
- // {
2837
- // "orders": [
2838
- // {
2839
- // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
2840
- // "product_id": "BTC-USDT",
2841
- // "user_id": "1111111-1111-1111-1111-111111111111",
2842
- // "order_configuration": {
2843
- // "market_market_ioc": {
2844
- // "quote_size": "6.36"
2845
- // }
2846
- // },
2847
- // "side": "BUY",
2848
- // "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317",
2849
- // "status": "FILLED",
2850
- // "time_in_force": "IMMEDIATE_OR_CANCEL",
2851
- // "created_time": "2023-01-18T01:37:37.975552Z",
2852
- // "completion_percentage": "100",
2853
- // "filled_size": "0.000297920684505",
2854
- // "average_filled_price": "21220.6399999973697697",
2855
- // "fee": "",
2856
- // "number_of_fills": "2",
2857
- // "filled_value": "6.3220675944333996",
2858
- // "pending_cancel": false,
2859
- // "size_in_quote": true,
2860
- // "total_fees": "0.0379324055666004",
2861
- // "size_inclusive_of_fees": true,
2862
- // "total_value_after_fees": "6.36",
2863
- // "trigger_status": "INVALID_ORDER_TYPE",
2864
- // "order_type": "MARKET",
2865
- // "reject_reason": "REJECT_REASON_UNSPECIFIED",
2866
- // "settled": true,
2867
- // "product_type": "SPOT",
2868
- // "reject_message": "",
2869
- // "cancel_message": "Internal error"
2870
- // },
2871
- // ],
2872
- // "sequence": "0",
2873
- // "has_next": false,
2874
- // "cursor": ""
2875
- // }
2876
- //
2877
- const orders = this.safeValue(response, 'orders', []);
2878
- const first = this.safeValue(orders, 0);
2879
- const cursor = this.safeString(response, 'cursor');
2880
- if ((cursor !== undefined) && (cursor !== '')) {
2881
- first['cursor'] = cursor;
2882
- orders[0] = first;
2883
- }
2884
- return this.parseOrders(orders, market, since, limit);
2885
- }
2886
- async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2887
- /**
2888
- * @method
2889
- * @name coinbase#fetchOpenOrders
2890
- * @description fetches information on all currently open orders
2891
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
2892
- * @param {string} symbol unified market symbol of the orders
2893
- * @param {int} [since] timestamp in ms of the earliest order, default is undefined
2894
- * @param {int} [limit] the maximum number of open order structures to retrieve
2895
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2896
- * @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)
2897
- * @param {int} [params.until] the latest time in ms to fetch trades for
2898
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2899
- */
2900
- await this.loadMarkets();
2901
- let paginate = false;
2902
- [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'paginate');
2903
- if (paginate) {
2904
- return await this.fetchPaginatedCallCursor('fetchOpenOrders', symbol, since, limit, params, 'cursor', 'cursor', undefined, 100);
2905
- }
2906
- return await this.fetchOrdersByStatus('OPEN', symbol, since, limit, params);
2907
- }
2908
- async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2909
- /**
2910
- * @method
2911
- * @name coinbase#fetchClosedOrders
2912
- * @description fetches information on multiple closed orders made by the user
2913
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
2914
- * @param {string} symbol unified market symbol of the orders
2915
- * @param {int} [since] timestamp in ms of the earliest order, default is undefined
2916
- * @param {int} [limit] the maximum number of closed order structures to retrieve
2917
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2918
- * @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)
2919
- * @param {int} [params.until] the latest time in ms to fetch trades for
2920
- * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2921
- */
2922
- await this.loadMarkets();
2923
- let paginate = false;
2924
- [paginate, params] = this.handleOptionAndParams(params, 'fetchClosedOrders', 'paginate');
2925
- if (paginate) {
2926
- return await this.fetchPaginatedCallCursor('fetchClosedOrders', symbol, since, limit, params, 'cursor', 'cursor', undefined, 100);
2927
- }
2928
- return await this.fetchOrdersByStatus('FILLED', symbol, since, limit, params);
2929
- }
2930
- async fetchCanceledOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
2931
- /**
2932
- * @method
2933
- * @name coinbase#fetchCanceledOrders
2934
- * @description fetches information on multiple canceled orders made by the user
2935
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_gethistoricalorders
2936
- * @param {string} symbol unified market symbol of the orders
2937
- * @param {int} [since] timestamp in ms of the earliest order, default is undefined
2938
- * @param {int} [limit] the maximum number of canceled order structures to retrieve
2939
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2940
- * @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
2941
- */
2942
- return await this.fetchOrdersByStatus('CANCELLED', symbol, since, limit, params);
2943
- }
2944
- async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
2945
- /**
2946
- * @method
2947
- * @name coinbase#fetchOHLCV
2948
- * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
2949
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getcandles
2950
- * @param {string} symbol unified symbol of the market to fetch OHLCV data for
2951
- * @param {string} timeframe the length of time each candle represents
2952
- * @param {int} [since] timestamp in ms of the earliest candle to fetch
2953
- * @param {int} [limit] the maximum amount of candles to fetch, not used by coinbase
2954
- * @param {object} [params] extra parameters specific to the exchange API endpoint
2955
- * @param {int} [params.until] the latest time in ms to fetch trades for
2956
- * @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)
2957
- * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
2958
- */
2959
- await this.loadMarkets();
2960
- let paginate = false;
2961
- [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
2962
- if (paginate) {
2963
- return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 299);
2964
- }
2965
- const market = this.market(symbol);
2966
- const request = {
2967
- 'product_id': market['id'],
2968
- 'granularity': this.safeString(this.timeframes, timeframe, timeframe),
2969
- };
2970
- const until = this.safeValueN(params, ['until', 'till', 'end']);
2971
- params = this.omit(params, ['until', 'till']);
2972
- const duration = this.parseTimeframe(timeframe);
2973
- const candles300 = 300 * duration;
2974
- let sinceString = undefined;
2975
- if (since !== undefined) {
2976
- sinceString = this.numberToString(this.parseToInt(since / 1000));
2977
- }
2978
- else {
2979
- const now = this.seconds().toString();
2980
- sinceString = Precise["default"].stringSub(now, candles300.toString());
2981
- }
2982
- request['start'] = sinceString;
2983
- let endString = this.numberToString(until);
2984
- if (until === undefined) {
2985
- // 300 candles max
2986
- endString = Precise["default"].stringAdd(sinceString, candles300.toString());
2987
- }
2988
- request['end'] = endString;
2989
- const response = await this.v3PrivateGetBrokerageProductsProductIdCandles(this.extend(request, params));
2990
- //
2991
- // {
2992
- // "candles": [
2993
- // {
2994
- // "start": "1673391780",
2995
- // "low": "17414.36",
2996
- // "high": "17417.99",
2997
- // "open": "17417.74",
2998
- // "close": "17417.38",
2999
- // "volume": "1.87780853"
3000
- // },
3001
- // ]
3002
- // }
3003
- //
3004
- const candles = this.safeValue(response, 'candles', []);
3005
- return this.parseOHLCVs(candles, market, timeframe, since, limit);
3006
- }
3007
- parseOHLCV(ohlcv, market = undefined) {
3008
- //
3009
- // [
3010
- // {
3011
- // "start": "1673391780",
3012
- // "low": "17414.36",
3013
- // "high": "17417.99",
3014
- // "open": "17417.74",
3015
- // "close": "17417.38",
3016
- // "volume": "1.87780853"
3017
- // },
3018
- // ]
3019
- //
3020
- return [
3021
- this.safeTimestamp(ohlcv, 'start'),
3022
- this.safeNumber(ohlcv, 'open'),
3023
- this.safeNumber(ohlcv, 'high'),
3024
- this.safeNumber(ohlcv, 'low'),
3025
- this.safeNumber(ohlcv, 'close'),
3026
- this.safeNumber(ohlcv, 'volume'),
3027
- ];
3028
- }
3029
- async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
3030
- /**
3031
- * @method
3032
- * @name coinbase#fetchTrades
3033
- * @description get the list of most recent trades for a particular symbol
3034
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getmarkettrades
3035
- * @param {string} symbol unified market symbol of the trades
3036
- * @param {int} [since] not used by coinbase fetchTrades
3037
- * @param {int} [limit] the maximum number of trade structures to fetch
3038
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3039
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
3040
- */
3041
- await this.loadMarkets();
3042
- const market = this.market(symbol);
3043
- const request = {
3044
- 'product_id': market['id'],
3045
- };
3046
- if (limit !== undefined) {
3047
- request['limit'] = limit;
3048
- }
3049
- const response = await this.v3PrivateGetBrokerageProductsProductIdTicker(this.extend(request, params));
3050
- //
3051
- // {
3052
- // "trades": [
3053
- // {
3054
- // "trade_id": "10092327",
3055
- // "product_id": "BTC-USDT",
3056
- // "price": "17488.12",
3057
- // "size": "0.0000623",
3058
- // "time": "2023-01-11T00:52:37.557001Z",
3059
- // "side": "BUY",
3060
- // "bid": "",
3061
- // "ask": ""
3062
- // },
3063
- // ]
3064
- // }
3065
- //
3066
- const trades = this.safeValue(response, 'trades', []);
3067
- return this.parseTrades(trades, market, since, limit);
3068
- }
3069
- async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
3070
- /**
3071
- * @method
3072
- * @name coinbase#fetchMyTrades
3073
- * @description fetch all trades made by the user
3074
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getfills
3075
- * @param {string} symbol unified market symbol of the trades
3076
- * @param {int} [since] timestamp in ms of the earliest order, default is undefined
3077
- * @param {int} [limit] the maximum number of trade structures to fetch
3078
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3079
- * @param {int} [params.until] the latest time in ms to fetch trades for
3080
- * @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)
3081
- * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
3082
- */
3083
- await this.loadMarkets();
3084
- let paginate = false;
3085
- [paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
3086
- if (paginate) {
3087
- return await this.fetchPaginatedCallCursor('fetchMyTrades', symbol, since, limit, params, 'cursor', 'cursor', undefined, 100);
3088
- }
3089
- let market = undefined;
3090
- if (symbol !== undefined) {
3091
- market = this.market(symbol);
3092
- }
3093
- const request = {};
3094
- if (market !== undefined) {
3095
- request['product_id'] = market['id'];
3096
- }
3097
- if (limit !== undefined) {
3098
- request['limit'] = limit;
3099
- }
3100
- if (since !== undefined) {
3101
- request['start_sequence_timestamp'] = this.iso8601(since);
3102
- }
3103
- const until = this.safeValueN(params, ['until', 'till']);
3104
- if (until !== undefined) {
3105
- params = this.omit(params, ['until', 'till']);
3106
- request['end_sequence_timestamp'] = this.iso8601(until);
3107
- }
3108
- const response = await this.v3PrivateGetBrokerageOrdersHistoricalFills(this.extend(request, params));
3109
- //
3110
- // {
3111
- // "fills": [
3112
- // {
3113
- // "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010",
3114
- // "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1",
3115
- // "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
3116
- // "trade_time": "2023-01-18T01:37:38.091377090Z",
3117
- // "trade_type": "FILL",
3118
- // "price": "21220.64",
3119
- // "size": "0.0046830664333996",
3120
- // "commission": "0.0000280983986004",
3121
- // "product_id": "BTC-USDT",
3122
- // "sequence_timestamp": "2023-01-18T01:37:38.092520Z",
3123
- // "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR",
3124
- // "size_in_quote": true,
3125
- // "user_id": "1111111-1111-1111-1111-111111111111",
3126
- // "side": "BUY"
3127
- // },
3128
- // ],
3129
- // "cursor": ""
3130
- // }
3131
- //
3132
- const trades = this.safeValue(response, 'fills', []);
3133
- const first = this.safeValue(trades, 0);
3134
- const cursor = this.safeString(response, 'cursor');
3135
- if ((cursor !== undefined) && (cursor !== '')) {
3136
- first['cursor'] = cursor;
3137
- trades[0] = first;
3138
- }
3139
- return this.parseTrades(trades, market, since, limit);
3140
- }
3141
- async fetchOrderBook(symbol, limit = undefined, params = {}) {
3142
- /**
3143
- * @method
3144
- * @name coinbase#fetchOrderBook
3145
- * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
3146
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getproductbook
3147
- * @param {string} symbol unified symbol of the market to fetch the order book for
3148
- * @param {int} [limit] the maximum amount of order book entries to return
3149
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3150
- * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
3151
- */
3152
- await this.loadMarkets();
3153
- const market = this.market(symbol);
3154
- const request = {
3155
- 'product_id': market['id'],
3156
- };
3157
- if (limit !== undefined) {
3158
- request['limit'] = limit;
3159
- }
3160
- const response = await this.v3PrivateGetBrokerageProductBook(this.extend(request, params));
3161
- //
3162
- // {
3163
- // "pricebook": {
3164
- // "product_id": "BTC-USDT",
3165
- // "bids": [
3166
- // {
3167
- // "price": "30757.85",
3168
- // "size": "0.115"
3169
- // },
3170
- // ],
3171
- // "asks": [
3172
- // {
3173
- // "price": "30759.07",
3174
- // "size": "0.04877659"
3175
- // },
3176
- // ],
3177
- // "time": "2023-06-30T04:02:40.533606Z"
3178
- // }
3179
- // }
3180
- //
3181
- const data = this.safeValue(response, 'pricebook', {});
3182
- const time = this.safeString(data, 'time');
3183
- const timestamp = this.parse8601(time);
3184
- return this.parseOrderBook(data, symbol, timestamp, 'bids', 'asks', 'price', 'size');
3185
- }
3186
- async fetchBidsAsks(symbols = undefined, params = {}) {
3187
- /**
3188
- * @method
3189
- * @name coinbase#fetchBidsAsks
3190
- * @description fetches the bid and ask price and volume for multiple markets
3191
- * @see https://docs.cloud.coinbase.com/advanced-trade-api/reference/retailbrokerageapi_getbestbidask
3192
- * @param {string[]} [symbols] unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
3193
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3194
- * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
3195
- */
3196
- await this.loadMarkets();
3197
- symbols = this.marketSymbols(symbols);
3198
- // the 'product_ids' param isn't working properly and returns {"pricebooks":[]} when defined
3199
- const response = await this.v3PrivateGetBrokerageBestBidAsk(params);
3200
- //
3201
- // {
3202
- // "pricebooks": [
3203
- // {
3204
- // "product_id": "TRAC-EUR",
3205
- // "bids": [
3206
- // {
3207
- // "price": "0.2384",
3208
- // "size": "386.1"
3209
- // }
3210
- // ],
3211
- // "asks": [
3212
- // {
3213
- // "price": "0.2406",
3214
- // "size": "672"
3215
- // }
3216
- // ],
3217
- // "time": "2023-06-30T07:15:24.656044Z"
3218
- // },
3219
- // ]
3220
- // }
3221
- //
3222
- const tickers = this.safeValue(response, 'pricebooks', []);
3223
- return this.parseTickers(tickers, symbols);
3224
- }
3225
- async withdraw(code, amount, address, tag = undefined, params = {}) {
3226
- /**
3227
- * @method
3228
- * @name coinbase#withdraw
3229
- * @description make a withdrawal
3230
- * @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#send-money
3231
- * @param {string} code unified currency code
3232
- * @param {float} amount the amount to withdraw
3233
- * @param {string} address the address to withdraw to
3234
- * @param {string} [tag] an optional tag for the withdrawal
3235
- * @param {object} [params] extra parameters specific to the exchange API endpoint
3236
- * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
3237
- */
3238
- [tag, params] = this.handleWithdrawTagAndParams(tag, params);
3239
- this.checkAddress(address);
3240
- await this.loadMarkets();
3241
- const currency = this.currency(code);
3242
- let accountId = this.safeString2(params, 'account_id', 'accountId');
3243
- params = this.omit(params, ['account_id', 'accountId']);
3244
- if (accountId === undefined) {
3245
- if (code === undefined) {
3246
- throw new errors.ArgumentsRequired(this.id + ' withdraw() requires an account_id (or accountId) parameter OR a currency code argument');
3247
- }
3248
- accountId = await this.findAccountId(code);
3249
- if (accountId === undefined) {
3250
- throw new errors.ExchangeError(this.id + ' withdraw() could not find account id for ' + code);
3251
- }
3252
- }
3253
- const request = {
3254
- 'account_id': accountId,
3255
- 'type': 'send',
3256
- 'to': address,
3257
- 'amount': amount,
3258
- 'currency': currency['id'],
3259
- };
3260
- if (tag !== undefined) {
3261
- request['destination_tag'] = tag;
3262
- }
3263
- const response = await this.v2PrivatePostAccountsAccountIdTransactions(this.extend(request, params));
3264
- //
3265
- // {
3266
- // "data": {
3267
- // "id": "a1794ecf-5693-55fa-70cf-ef731748ed82",
3268
- // "type": "send",
3269
- // "status": "pending",
3270
- // "amount": {
3271
- // "amount": "-14.008308",
3272
- // "currency": "USDC"
3273
- // },
3274
- // "native_amount": {
3275
- // "amount": "-18.74",
3276
- // "currency": "CAD"
3277
- // },
3278
- // "description": null,
3279
- // "created_at": "2024-01-12T01:27:31Z",
3280
- // "updated_at": "2024-01-12T01:27:31Z",
3281
- // "resource": "transaction",
3282
- // "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82",
3283
- // "instant_exchange": false,
3284
- // "network": {
3285
- // "status": "pending",
3286
- // "status_description": "Pending (est. less than 10 minutes)",
3287
- // "transaction_fee": {
3288
- // "amount": "4.008308",
3289
- // "currency": "USDC"
3290
- // },
3291
- // "transaction_amount": {
3292
- // "amount": "10.000000",
3293
- // "currency": "USDC"
3294
- // },
3295
- // "confirmations": 0
3296
- // },
3297
- // "to": {
3298
- // "resource": "ethereum_address",
3299
- // "address": "0x9...",
3300
- // "currency": "USDC",
3301
- // "address_info": {
3302
- // "address": "0x9..."
3303
- // }
3304
- // },
3305
- // "idem": "748d8591-dg9a-7831-a45b-crd61dg78762",
3306
- // "details": {
3307
- // "title": "Sent USDC",
3308
- // "subtitle": "To USDC address on Ethereum network",
3309
- // "header": "Sent 14.008308 USDC ($18.74)",
3310
- // "health": "warning"
3311
- // },
3312
- // "hide_native_amount": false
3313
- // }
3314
- // }
3315
- //
3316
- const data = this.safeValue(response, 'data', {});
3317
- return this.parseTransaction(data, currency);
3318
- }
3319
- sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
3320
- const version = api[0];
3321
- const signed = api[1] === 'private';
3322
- const pathPart = (version === 'v3') ? 'api/v3' : 'v2';
3323
- let fullPath = '/' + pathPart + '/' + this.implodeParams(path, params);
3324
- const query = this.omit(params, this.extractParams(path));
3325
- const savedPath = fullPath;
3326
- if (method === 'GET') {
3327
- if (Object.keys(query).length) {
3328
- fullPath += '?' + this.urlencode(query);
3329
- }
3330
- }
3331
- const url = this.urls['api']['rest'] + fullPath;
3332
- if (signed) {
3333
- const authorization = this.safeString(this.headers, 'Authorization');
3334
- if (authorization !== undefined) {
3335
- headers = {
3336
- 'Authorization': authorization,
3337
- 'Content-Type': 'application/json',
3338
- };
3339
- }
3340
- else if (this.token) {
3341
- headers = {
3342
- 'Authorization': 'Bearer ' + this.token,
3343
- 'Content-Type': 'application/json',
3344
- };
3345
- }
3346
- else {
3347
- this.checkRequiredCredentials();
3348
- const nonce = this.nonce().toString();
3349
- let payload = '';
3350
- if (method !== 'GET') {
3351
- if (Object.keys(query).length) {
3352
- body = this.json(query);
3353
- payload = body;
3354
- }
3355
- }
3356
- let auth = undefined;
3357
- if (version === 'v3') {
3358
- auth = nonce + method + savedPath + payload;
3359
- }
3360
- else {
3361
- auth = nonce + method + fullPath + payload;
3362
- }
3363
- const signature = this.hmac(this.encode(auth), this.encode(this.secret), sha256.sha256);
3364
- headers = {
3365
- 'CB-ACCESS-KEY': this.apiKey,
3366
- 'CB-ACCESS-SIGN': signature,
3367
- 'CB-ACCESS-TIMESTAMP': nonce,
3368
- 'Content-Type': 'application/json',
3369
- };
3370
- }
3371
- }
3372
- return { 'url': url, 'method': method, 'body': body, 'headers': headers };
3373
- }
3374
- handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
3375
- if (response === undefined) {
3376
- return undefined; // fallback to default error handler
3377
- }
3378
- const feedback = this.id + ' ' + body;
3379
- //
3380
- // {"error": "invalid_request", "error_description": "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}
3381
- //
3382
- // or
3383
- //
3384
- // {
3385
- // "errors": [
3386
- // {
3387
- // "id": "not_found",
3388
- // "message": "Not found"
3389
- // }
3390
- // ]
3391
- // }
3392
- //
3393
- let errorCode = this.safeString(response, 'error');
3394
- if (errorCode !== undefined) {
3395
- const errorMessage = this.safeString(response, 'error_description');
3396
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
3397
- this.throwBroadlyMatchedException(this.exceptions['broad'], errorMessage, feedback);
3398
- throw new errors.ExchangeError(feedback);
3399
- }
3400
- const errors$1 = this.safeValue(response, 'errors');
3401
- if (errors$1 !== undefined) {
3402
- if (Array.isArray(errors$1)) {
3403
- const numErrors = errors$1.length;
3404
- if (numErrors > 0) {
3405
- errorCode = this.safeString(errors$1[0], 'id');
3406
- const errorMessage = this.safeString(errors$1[0], 'message');
3407
- if (errorCode !== undefined) {
3408
- this.throwExactlyMatchedException(this.exceptions['exact'], errorCode, feedback);
3409
- this.throwBroadlyMatchedException(this.exceptions['broad'], errorMessage, feedback);
3410
- throw new errors.ExchangeError(feedback);
3411
- }
3412
- }
3413
- }
3414
- }
3415
- const advancedTrade = this.options['advanced'];
3416
- const data = this.safeValue(response, 'data');
3417
- if ((data === undefined) && (!advancedTrade)) {
3418
- throw new errors.ExchangeError(this.id + ' failed due to a malformed response ' + this.json(response));
3419
- }
3420
- return undefined;
3421
- }
3422
- }
3423
-
3424
- module.exports = coinbase;