ccxt 4.2.72 → 4.2.74

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 (379) hide show
  1. package/README.md +124 -122
  2. package/build.sh +2 -2
  3. package/dist/ccxt.browser.js +3277 -460
  4. package/dist/ccxt.browser.min.js +4 -4
  5. package/dist/cjs/ccxt.js +6 -1
  6. package/dist/cjs/src/abstract/coinbaseinternational.js +9 -0
  7. package/dist/cjs/src/base/Exchange.js +31 -7
  8. package/dist/cjs/src/bitget.js +62 -50
  9. package/dist/cjs/src/btcturk.js +3 -3
  10. package/dist/cjs/src/bybit.js +90 -30
  11. package/dist/cjs/src/coinbaseinternational.js +2019 -0
  12. package/dist/cjs/src/gate.js +1 -1
  13. package/dist/cjs/src/htx.js +16 -9
  14. package/dist/cjs/src/hyperliquid.js +9 -2
  15. package/dist/cjs/src/mexc.js +1 -1
  16. package/dist/cjs/src/okx.js +1 -1
  17. package/dist/cjs/src/pro/coinbaseinternational.js +645 -0
  18. package/dist/cjs/src/pro/krakenfutures.js +8 -7
  19. package/examples/README.md +308 -0
  20. package/examples/ccxt.pro/html/watchTicker.html +51 -0
  21. package/examples/ccxt.pro/js/binance-fetch-balance-snapshot-watch-balance-updates.js +55 -0
  22. package/examples/ccxt.pro/js/binance-https-proxy.js +48 -0
  23. package/examples/ccxt.pro/js/binance-watch-ohlcv-many-symbols-continuously.js +38 -0
  24. package/examples/ccxt.pro/js/binance-watch-ohlcv-many-symbols.js +64 -0
  25. package/examples/ccxt.pro/js/binance-watch-ticker-many-symbols.js +62 -0
  26. package/examples/ccxt.pro/js/build-ohlcv-many-symbols.js +68 -0
  27. package/examples/ccxt.pro/js/calculate-ohlcvs-from-trades-warmup.js +82 -0
  28. package/examples/ccxt.pro/js/calculate-ohlcvs-from-trades.js +59 -0
  29. package/examples/ccxt.pro/js/exchange-capabitities.js +72 -0
  30. package/examples/ccxt.pro/js/exchange-close.js +46 -0
  31. package/examples/ccxt.pro/js/gateio-swap-watch-many-orderbooks.js +30 -0
  32. package/examples/ccxt.pro/js/gateio-watch-balance.js +23 -0
  33. package/examples/ccxt.pro/js/gateio-watch-order-book.js +71 -0
  34. package/examples/ccxt.pro/js/graceful-shutdown.js +43 -0
  35. package/examples/ccxt.pro/js/many-exchanges-many-streams.js +37 -0
  36. package/examples/ccxt.pro/js/okex-create-futures-order.js +48 -0
  37. package/examples/ccxt.pro/js/okex-watch-balance-and-create-order.js +54 -0
  38. package/examples/ccxt.pro/js/okx-watch-tickers.js +31 -0
  39. package/examples/ccxt.pro/js/one-exchange-many-different-streams.js +46 -0
  40. package/examples/ccxt.pro/js/one-exchange-many-streams-2.js +26 -0
  41. package/examples/ccxt.pro/js/one-exchange-many-streams.js +28 -0
  42. package/examples/ccxt.pro/js/socks-binance-watch-orderbook.js +30 -0
  43. package/examples/ccxt.pro/js/watch-fetch-many-exchanges-many-ordersbooks.js +40 -0
  44. package/examples/ccxt.pro/js/watch-many-exchanges-many-ordersbooks.js +38 -0
  45. package/examples/ccxt.pro/js/watch-many-exchanges-many-symbols.js +40 -0
  46. package/examples/ccxt.pro/js/watch-many-orderbooks.js +27 -0
  47. package/examples/ccxt.pro/js/watch-new-trades-only.js +43 -0
  48. package/examples/ccxt.pro/js/watch-new-trades.js +42 -0
  49. package/examples/ccxt.pro/js/watch-trades-many-symbols.js +29 -0
  50. package/examples/ccxt.pro/js/watch-vs-fetch.js +29 -0
  51. package/examples/cs/Examples.sln +22 -0
  52. package/examples/cs/c#.csproj +19 -0
  53. package/examples/html/basic-cors-proxy.html +46 -0
  54. package/examples/html/basic-inheritance.html +47 -0
  55. package/examples/html/basic-poller.html +52 -0
  56. package/examples/html/basic-rate-limiting.html +49 -0
  57. package/examples/html/basic.html +43 -0
  58. package/examples/html/binance-cors-proxy.html +28 -0
  59. package/examples/html/bitmex-browser-cors-proxy.js +7 -0
  60. package/examples/html/bitmex-cors.html +46 -0
  61. package/examples/html/tradingview-charts.html +61 -0
  62. package/examples/html/webworker/index.html +97 -0
  63. package/examples/html/webworker/worker.js +43 -0
  64. package/examples/js/README.md +15 -0
  65. package/examples/js/advanced-error-handling.js +39 -0
  66. package/examples/js/aggregate-orderbook.js +54 -0
  67. package/examples/js/arbitrage-pairs.js +130 -0
  68. package/examples/js/basic-chart.js +29 -0
  69. package/examples/js/basic-orderbook-polling.js +13 -0
  70. package/examples/js/bcc-vs-bch.js +115 -0
  71. package/examples/js/binance-fetch-all-deposits.js +45 -0
  72. package/examples/js/binance-fetch-ohlcv-many-symbols-async-await.js +34 -0
  73. package/examples/js/binance-fetch-ohlcv-many-symbols-promise-then-callbacks.js +33 -0
  74. package/examples/js/binance-fetchTicker-delivery-vs-future.js +31 -0
  75. package/examples/js/binance-futures-transfer-from-sub-account-to-master.js +41 -0
  76. package/examples/js/binance-margin-stop-order.js +39 -0
  77. package/examples/js/binance-server-time.js +34 -0
  78. package/examples/js/binance-universal-transfer.js +16 -0
  79. package/examples/js/bitfinex-fetch-trades.js +35 -0
  80. package/examples/js/bitfinex2-fetch-trades.js +35 -0
  81. package/examples/js/bitmex-browser-cors-proxy.js +7 -0
  82. package/examples/js/bitpanda-fetchMyTrades-reduce.js +36 -0
  83. package/examples/js/bitrue-fetch-balance.js +28 -0
  84. package/examples/js/bitstamp-private-api.js +115 -0
  85. package/examples/js/bitstamp-public-api.js +39 -0
  86. package/examples/js/bittrex-balance.js +50 -0
  87. package/examples/js/bittrex-fetch-closed-orders-history.js +69 -0
  88. package/examples/js/blockchaincom-withdrawal.js +59 -0
  89. package/examples/js/build-ohlcv-bars.js +48 -0
  90. package/examples/js/builtin-rate-limiting-rest-poller.js +25 -0
  91. package/examples/js/bybit-trailing.js +62 -0
  92. package/examples/js/bybit-updated.cjs +154 -0
  93. package/examples/js/cli.js +405 -0
  94. package/examples/js/coinbase-fetch-all-balances.js +36 -0
  95. package/examples/js/coinex-fetch-all-deposit-addresses-using-fetchDepositAddress.js +47 -0
  96. package/examples/js/coinex-futures.js +75 -0
  97. package/examples/js/coinone-fetch-tickers.js +54 -0
  98. package/examples/js/coinone-markets.js +16 -0
  99. package/examples/js/compare-two-exchanges-capabilities.js +36 -0
  100. package/examples/js/cors-proxy.js +5 -0
  101. package/examples/js/create-order-handle-errors.js +55 -0
  102. package/examples/js/create-order-position-with-takeprofit-stoploss.js +71 -0
  103. package/examples/js/create-order-with-retry.js +65 -0
  104. package/examples/js/create-order-ws-example.js +25 -0
  105. package/examples/js/create-orders-example.js +17 -0
  106. package/examples/js/create-trailing-amount-order.js +36 -0
  107. package/examples/js/create-trailing-percent-order.js +36 -0
  108. package/examples/js/credentials.json +5 -0
  109. package/examples/js/custom-proxy-agent-for-js.js +10 -0
  110. package/examples/js/custom-proxy-url.js +23 -0
  111. package/examples/js/delta-maintenance-margin-rate-max-leverage.js +60 -0
  112. package/examples/js/env-variables.js +26 -0
  113. package/examples/js/error-handling.js +89 -0
  114. package/examples/js/exchange-capabilities.js +135 -0
  115. package/examples/js/exchanges-by-volume.js +60 -0
  116. package/examples/js/exchanges.js +40 -0
  117. package/examples/js/fetch-all-balances.js +219 -0
  118. package/examples/js/fetch-all-tickers-to-files-2.js +53 -0
  119. package/examples/js/fetch-all-tickers-to-files.js +77 -0
  120. package/examples/js/fetch-balance.js +28 -0
  121. package/examples/js/fetch-create-deposit-address.js +101 -0
  122. package/examples/js/fetch-from-many-exchanges-simultaneously.js +21 -0
  123. package/examples/js/fetch-funding-rate-history.js +25 -0
  124. package/examples/js/fetch-futures/prettier.config.js +5 -0
  125. package/examples/js/fetch-futures/src/index.js +25 -0
  126. package/examples/js/fetch-ohlcv-from-to-mark-index-premium.js +72 -0
  127. package/examples/js/fetch-ohlcv-many-exchanges-continuosly.js +39 -0
  128. package/examples/js/fetch-ohlcv.js +16 -0
  129. package/examples/js/fetch-okex-futures.js +22 -0
  130. package/examples/js/fetch-orders.js +27 -0
  131. package/examples/js/fetch-ticker-from-multiple-exchanges.js +35 -0
  132. package/examples/js/fetch-ticker-where-available.js +75 -0
  133. package/examples/js/fetch-tickers/build/index.js +19 -0
  134. package/examples/js/fetch-tickers/prettier.config.js +5 -0
  135. package/examples/js/fetch-tickers/src/index.js +17 -0
  136. package/examples/js/gateio-create-batch-order.js +43 -0
  137. package/examples/js/gateio-futures.js +49 -0
  138. package/examples/js/gateio-open-close-contract.js +49 -0
  139. package/examples/js/gateio-swaps.js +74 -0
  140. package/examples/js/gdax-fetch-trades-pagination.js +29 -0
  141. package/examples/js/hitbtc2-withdraw.js +61 -0
  142. package/examples/js/how-to-import-one-exchange-esm.js +10 -0
  143. package/examples/js/huobi-futures.js +71 -0
  144. package/examples/js/huobi-open-close-contract.js +63 -0
  145. package/examples/js/huobi-swaps.js +70 -0
  146. package/examples/js/huobipro-market-buy-sell-fetch-trading-limits.js +98 -0
  147. package/examples/js/hybridCJSExample.cjs +19 -0
  148. package/examples/js/hybridESMExample.js +19 -0
  149. package/examples/js/idex-fetch-balance.js +13 -0
  150. package/examples/js/instantiate-all-at-once.js +46 -0
  151. package/examples/js/instantiate-all-from-json.js +31 -0
  152. package/examples/js/kraken-create-and-close-position.js +54 -0
  153. package/examples/js/kraken-fetch-order-trades.js +33 -0
  154. package/examples/js/kraken-margin-trading.js +89 -0
  155. package/examples/js/kucoin-rate-limit.js +38 -0
  156. package/examples/js/latoken-example.js +108 -0
  157. package/examples/js/live-orderbook.js +106 -0
  158. package/examples/js/live-ticker.js +80 -0
  159. package/examples/js/live-tickers.js +74 -0
  160. package/examples/js/load-all-contracts.js +41 -0
  161. package/examples/js/load-all-symbols-at-once.js +69 -0
  162. package/examples/js/load-all-tickers-at-once.js +91 -0
  163. package/examples/js/load-markets-to-files.js +57 -0
  164. package/examples/js/looping-over-all-symbols-of-specific-exchanges.js +61 -0
  165. package/examples/js/looping-over-specific-symbols-of-all-exchanges.js +91 -0
  166. package/examples/js/margin-loan-borrow-buy-sell-repay.js +70 -0
  167. package/examples/js/market-status-and-currency-status.js +29 -0
  168. package/examples/js/ohlcv-console-chart.js +29 -0
  169. package/examples/js/okex-fetch-closed-orders-archive.js +31 -0
  170. package/examples/js/okex-transfer.js +51 -0
  171. package/examples/js/okx-poll-fetch-my-trades.js +37 -0
  172. package/examples/js/okx-poll-rate-limit.js +48 -0
  173. package/examples/js/order-book-extra-level-depth-param.js +20 -0
  174. package/examples/js/phemex-create-order-position-with-takeprofit-stoploss.js +49 -0
  175. package/examples/js/poll-ohlcv.js +43 -0
  176. package/examples/js/poloniex-fetch-order-books.js +35 -0
  177. package/examples/js/poloniex-limits-amount-min.js +62 -0
  178. package/examples/js/proxy-round-robin.js +98 -0
  179. package/examples/js/proxy-usage.js +32 -0
  180. package/examples/js/sample-local-proxy-server-with-cors.js +12 -0
  181. package/examples/js/search-all-exchanges.js +159 -0
  182. package/examples/js/shared-load-markets.js +80 -0
  183. package/examples/js/sort-swap-markets-by-hourly-price-change.js +55 -0
  184. package/examples/js/symbols.js +110 -0
  185. package/examples/js/theocean.js +41 -0
  186. package/examples/js/tickers.js +106 -0
  187. package/examples/js/validate-paginated-data.js +61 -0
  188. package/examples/js/watch-OHLCV-For-Symbols.js +15 -0
  189. package/examples/js/watch-OHLCV.js +12 -0
  190. package/examples/js/watch-OrderBook-For-Symbols.js +11 -0
  191. package/examples/js/watch-Trades-For-Symbols.js +11 -0
  192. package/examples/js/watch-tickers.js +11 -0
  193. package/examples/js/watchOHLCVForSymbols.js +15 -0
  194. package/examples/js/watchOrderBookForSymbols.js +11 -0
  195. package/examples/js/watchPositions-many-exchanges-continuosly.d.ts +2 -0
  196. package/examples/js/watchPositions-many-exchanges-continuosly.d.ts.map +1 -0
  197. package/examples/js/watchPositions-many-exchanges-continuosly.js +49 -0
  198. package/examples/js/watchPositions.d.ts +2 -0
  199. package/examples/js/watchPositions.d.ts.map +1 -0
  200. package/examples/js/watchPositions.js +13 -0
  201. package/examples/js/watchPositionsForSymbols.d.ts +2 -0
  202. package/examples/js/watchPositionsForSymbols.d.ts.map +1 -0
  203. package/examples/js/watchPositionsForSymbols.js +14 -0
  204. package/examples/js/watchTradesForSymbols.js +11 -0
  205. package/examples/js/withdraw-from-one-exchange-to-another.js +50 -0
  206. package/examples/php/README.md +7 -0
  207. package/examples/py/README.md +15 -0
  208. package/examples/py/playing_with_ccxt_example.ipynb +222 -0
  209. package/examples/ts/.eslintrc +111 -0
  210. package/examples/ts/build-ohlcv-bars.ts +53 -0
  211. package/examples/ts/cli.ts +397 -0
  212. package/examples/ts/compare-two-exchanges-capabilities.ts +36 -0
  213. package/examples/ts/create-order-position-with-takeprofit-stoploss.ts +89 -0
  214. package/examples/ts/create-order-ws-example.ts +33 -0
  215. package/examples/ts/create-orders-example.ts +21 -0
  216. package/examples/ts/create-trailing-amount-order.ts +37 -0
  217. package/examples/ts/create-trailing-percent-order.ts +37 -0
  218. package/examples/ts/custom-proxy-agent-for-js.ts +14 -0
  219. package/examples/ts/fetch-futures/package-lock.json +116 -0
  220. package/examples/ts/fetch-futures/package.json +34 -0
  221. package/examples/ts/fetch-futures/prettier.config.js +4 -0
  222. package/examples/ts/fetch-futures/src/index.ts +28 -0
  223. package/examples/ts/fetch-futures/tsconfig.json +28 -0
  224. package/examples/ts/fetch-ohlcv-many-exchanges-continuosly.ts +44 -0
  225. package/examples/ts/fetch-ohlcv.ts +17 -0
  226. package/examples/ts/fetch-tickers/package-lock.json +116 -0
  227. package/examples/ts/fetch-tickers/package.json +34 -0
  228. package/examples/ts/fetch-tickers/prettier.config.js +4 -0
  229. package/examples/ts/fetch-tickers/src/index.ts +21 -0
  230. package/examples/ts/fetch-tickers/tsconfig.json +28 -0
  231. package/examples/ts/how-to-import-one-exchange-esm.ts +11 -0
  232. package/examples/ts/kraken-create-and-close-position.ts +69 -0
  233. package/examples/ts/margin-loan-borrow-buy-sell-repay.ts +72 -0
  234. package/examples/ts/nextjs-page-router/.eslintrc.json +3 -0
  235. package/examples/ts/nextjs-page-router/README.md +43 -0
  236. package/examples/ts/nextjs-page-router/next.config.js +6 -0
  237. package/examples/ts/nextjs-page-router/package-lock.json +7425 -0
  238. package/examples/ts/nextjs-page-router/package.json +28 -0
  239. package/examples/ts/nextjs-page-router/postcss.config.js +6 -0
  240. package/examples/ts/nextjs-page-router/public/favicon.ico +0 -0
  241. package/examples/ts/nextjs-page-router/src/pages/_app.tsx +6 -0
  242. package/examples/ts/nextjs-page-router/src/pages/_document.tsx +13 -0
  243. package/examples/ts/nextjs-page-router/src/pages/balance.tsx +46 -0
  244. package/examples/ts/nextjs-page-router/src/pages/index.tsx +8 -0
  245. package/examples/ts/nextjs-page-router/src/pages/tickers.tsx +61 -0
  246. package/examples/ts/nextjs-page-router/src/styles/globals.css +27 -0
  247. package/examples/ts/nextjs-page-router/tailwind.config.ts +20 -0
  248. package/examples/ts/nextjs-page-router/tsconfig.json +22 -0
  249. package/examples/ts/phemex-create-order-position-with-takeprofit-stoploss.ts +62 -0
  250. package/examples/ts/proxy-usage.ts +41 -0
  251. package/examples/ts/sample-local-proxy-server-with-cors.ts +15 -0
  252. package/examples/ts/watch-OHLCV-For-Symbols.ts +17 -0
  253. package/examples/ts/watch-OHLCV.ts +14 -0
  254. package/examples/ts/watch-OrderBook-For-Symbols.ts +13 -0
  255. package/examples/ts/watch-Trades-For-Symbols.ts +13 -0
  256. package/examples/ts/watch-tickers.ts +13 -0
  257. package/examples/ts/watchPositions-many-exchanges-continuosly.ts +53 -0
  258. package/examples/ts/watchPositions.ts +15 -0
  259. package/examples/ts/watchPositionsForSymbols.ts +16 -0
  260. package/examples/tsconfig.json +27 -0
  261. package/js/ccxt.d.ts +8 -2
  262. package/js/ccxt.js +6 -2
  263. package/js/src/abstract/coinbaseinternational.d.ts +42 -0
  264. package/js/src/abstract/coinbaseinternational.js +11 -0
  265. package/js/src/ace.d.ts +2 -2
  266. package/js/src/alpaca.d.ts +2 -2
  267. package/js/src/ascendex.d.ts +3 -3
  268. package/js/src/base/Exchange.d.ts +27 -24
  269. package/js/src/base/Exchange.js +31 -7
  270. package/js/src/bigone.d.ts +2 -2
  271. package/js/src/binance.d.ts +7 -7
  272. package/js/src/bingx.d.ts +4 -4
  273. package/js/src/bit2c.d.ts +2 -2
  274. package/js/src/bitbank.d.ts +2 -2
  275. package/js/src/bitbns.d.ts +2 -2
  276. package/js/src/bitfinex.d.ts +3 -3
  277. package/js/src/bitfinex2.d.ts +4 -4
  278. package/js/src/bitflyer.d.ts +2 -2
  279. package/js/src/bitget.d.ts +4 -4
  280. package/js/src/bitget.js +62 -50
  281. package/js/src/bithumb.d.ts +2 -2
  282. package/js/src/bitmart.d.ts +4 -4
  283. package/js/src/bitmex.d.ts +3 -3
  284. package/js/src/bitopro.d.ts +2 -2
  285. package/js/src/bitrue.d.ts +2 -2
  286. package/js/src/bitso.d.ts +2 -2
  287. package/js/src/bitstamp.d.ts +2 -2
  288. package/js/src/bitteam.d.ts +2 -2
  289. package/js/src/bitvavo.d.ts +4 -4
  290. package/js/src/bl3p.d.ts +2 -2
  291. package/js/src/blockchaincom.d.ts +2 -2
  292. package/js/src/blofin.d.ts +4 -4
  293. package/js/src/btcalpha.d.ts +2 -2
  294. package/js/src/btcbox.d.ts +2 -2
  295. package/js/src/btcmarkets.d.ts +2 -2
  296. package/js/src/btcturk.d.ts +2 -2
  297. package/js/src/btcturk.js +3 -3
  298. package/js/src/bybit.d.ts +8 -6
  299. package/js/src/bybit.js +90 -30
  300. package/js/src/cex.d.ts +3 -3
  301. package/js/src/coinbase.d.ts +3 -3
  302. package/js/src/coinbaseinternational.d.ts +146 -0
  303. package/js/src/coinbaseinternational.js +2020 -0
  304. package/js/src/coinbasepro.d.ts +2 -2
  305. package/js/src/coincheck.d.ts +2 -2
  306. package/js/src/coinex.d.ts +4 -4
  307. package/js/src/coinlist.d.ts +3 -3
  308. package/js/src/coinmate.d.ts +2 -2
  309. package/js/src/coinmetro.d.ts +2 -2
  310. package/js/src/coinone.d.ts +2 -2
  311. package/js/src/coinsph.d.ts +2 -2
  312. package/js/src/coinspot.d.ts +2 -2
  313. package/js/src/cryptocom.d.ts +4 -4
  314. package/js/src/currencycom.d.ts +2 -2
  315. package/js/src/delta.d.ts +3 -3
  316. package/js/src/deribit.d.ts +3 -3
  317. package/js/src/digifinex.d.ts +3 -3
  318. package/js/src/exmo.d.ts +3 -3
  319. package/js/src/gate.d.ts +4 -4
  320. package/js/src/gate.js +1 -1
  321. package/js/src/gemini.d.ts +2 -2
  322. package/js/src/hitbtc.d.ts +4 -4
  323. package/js/src/hollaex.d.ts +2 -2
  324. package/js/src/htx.d.ts +5 -5
  325. package/js/src/htx.js +16 -9
  326. package/js/src/huobijp.d.ts +2 -2
  327. package/js/src/hyperliquid.d.ts +4 -3
  328. package/js/src/hyperliquid.js +10 -3
  329. package/js/src/idex.d.ts +2 -2
  330. package/js/src/independentreserve.d.ts +2 -2
  331. package/js/src/indodax.d.ts +2 -2
  332. package/js/src/kraken.d.ts +3 -3
  333. package/js/src/krakenfutures.d.ts +4 -4
  334. package/js/src/kucoin.d.ts +4 -4
  335. package/js/src/kucoinfutures.d.ts +3 -3
  336. package/js/src/kuna.d.ts +2 -2
  337. package/js/src/latoken.d.ts +2 -2
  338. package/js/src/lbank.d.ts +2 -2
  339. package/js/src/luno.d.ts +2 -2
  340. package/js/src/lykke.d.ts +2 -2
  341. package/js/src/mercado.d.ts +2 -2
  342. package/js/src/mexc.d.ts +2 -2
  343. package/js/src/mexc.js +1 -1
  344. package/js/src/ndax.d.ts +3 -3
  345. package/js/src/novadax.d.ts +2 -2
  346. package/js/src/oceanex.d.ts +2 -2
  347. package/js/src/okcoin.d.ts +3 -3
  348. package/js/src/okx.d.ts +4 -4
  349. package/js/src/okx.js +1 -1
  350. package/js/src/onetrading.d.ts +2 -2
  351. package/js/src/p2b.d.ts +2 -2
  352. package/js/src/paymium.d.ts +2 -2
  353. package/js/src/phemex.d.ts +3 -3
  354. package/js/src/poloniex.d.ts +3 -3
  355. package/js/src/poloniexfutures.d.ts +2 -2
  356. package/js/src/pro/binance.d.ts +3 -3
  357. package/js/src/pro/bitvavo.d.ts +3 -3
  358. package/js/src/pro/cex.d.ts +3 -3
  359. package/js/src/pro/coinbaseinternational.d.ts +28 -0
  360. package/js/src/pro/coinbaseinternational.js +646 -0
  361. package/js/src/pro/cryptocom.d.ts +2 -2
  362. package/js/src/pro/hitbtc.d.ts +2 -2
  363. package/js/src/pro/kraken.d.ts +3 -3
  364. package/js/src/pro/krakenfutures.js +8 -7
  365. package/js/src/pro/okx.d.ts +3 -3
  366. package/js/src/pro/poloniex.d.ts +2 -2
  367. package/js/src/probit.d.ts +2 -2
  368. package/js/src/timex.d.ts +3 -3
  369. package/js/src/tokocrypto.d.ts +2 -2
  370. package/js/src/upbit.d.ts +2 -2
  371. package/js/src/wavesexchange.d.ts +2 -2
  372. package/js/src/wazirx.d.ts +2 -2
  373. package/js/src/whitebit.d.ts +2 -2
  374. package/js/src/woo.d.ts +5 -5
  375. package/js/src/yobit.d.ts +2 -2
  376. package/js/src/zaif.d.ts +2 -2
  377. package/js/src/zonda.d.ts +2 -2
  378. package/package.json +4 -1
  379. package/skip-tests.json +227 -424
@@ -0,0 +1,2020 @@
1
+ // ----------------------------------------------------------------------------
2
+
3
+ // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+ // EDIT THE CORRESPONDENT .ts FILE INSTEAD
6
+
7
+ // ----------------------------------------------------------------------------
8
+ import Exchange from './abstract/coinbaseinternational.js';
9
+ import { ExchangeError, ArgumentsRequired, BadRequest, InvalidOrder, PermissionDenied, DuplicateOrderId, AuthenticationError } from './base/errors.js';
10
+ import { Precise } from './base/Precise.js';
11
+ import { TICK_SIZE } from './base/functions/number.js';
12
+ import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
13
+ // ----------------------------------------------------------------------------
14
+ /**
15
+ * @class coinbaseinternational
16
+ * @augments Exchange
17
+ */
18
+ export default class coinbaseinternational extends Exchange {
19
+ describe() {
20
+ return this.deepExtend(super.describe(), {
21
+ 'id': 'coinbaseinternational',
22
+ 'name': 'coinbase International',
23
+ 'countries': ['US'],
24
+ 'certified': true,
25
+ 'pro': true,
26
+ 'rateLimit': 100,
27
+ 'version': 'v1',
28
+ 'userAgent': this.userAgents['chrome'],
29
+ 'headers': {
30
+ 'CB-VERSION': '2018-05-30',
31
+ },
32
+ 'has': {
33
+ 'CORS': true,
34
+ 'spot': true,
35
+ 'margin': true,
36
+ 'swap': true,
37
+ 'future': true,
38
+ 'option': false,
39
+ 'addMargin': false,
40
+ 'cancelAllOrders': true,
41
+ 'cancelOrder': true,
42
+ 'cancelOrders': false,
43
+ 'closeAllPositions': false,
44
+ 'closePosition': false,
45
+ 'createDepositAddress': true,
46
+ 'createLimitBuyOrder': true,
47
+ 'createLimitSellOrder': true,
48
+ 'createMarketBuyOrder': true,
49
+ 'createMarketBuyOrderWithCost': false,
50
+ 'createMarketOrderWithCost': false,
51
+ 'createMarketSellOrder': true,
52
+ 'createMarketSellOrderWithCost': false,
53
+ 'createOrder': true,
54
+ 'createPostOnlyOrder': true,
55
+ 'createReduceOnlyOrder': false,
56
+ 'createStopLimitOrder': true,
57
+ 'createStopMarketOrder': true,
58
+ 'createStopOrder': true,
59
+ 'editOrder': true,
60
+ 'fetchAccounts': true,
61
+ 'fetchBalance': true,
62
+ 'fetchBidsAsks': false,
63
+ 'fetchBorrowRateHistories': false,
64
+ 'fetchBorrowRateHistory': false,
65
+ 'fetchCanceledOrders': false,
66
+ 'fetchClosedOrders': false,
67
+ 'fetchCrossBorrowRate': false,
68
+ 'fetchCrossBorrowRates': false,
69
+ 'fetchCurrencies': true,
70
+ 'fetchDeposits': true,
71
+ 'fetchFundingHistory': false,
72
+ 'fetchFundingRate': false,
73
+ 'fetchFundingRateHistory': true,
74
+ 'fetchFundingRates': false,
75
+ 'fetchIndexOHLCV': false,
76
+ 'fetchIsolatedBorrowRate': false,
77
+ 'fetchIsolatedBorrowRates': false,
78
+ 'fetchL2OrderBook': false,
79
+ 'fetchLedger': false,
80
+ 'fetchLeverage': false,
81
+ 'fetchLeverageTiers': false,
82
+ 'fetchMarginMode': false,
83
+ 'fetchMarkets': true,
84
+ 'fetchMarkOHLCV': false,
85
+ 'fetchMyBuys': true,
86
+ 'fetchMySells': true,
87
+ 'fetchMyTrades': true,
88
+ 'fetchOHLCV': false,
89
+ 'fetchOpenInterestHistory': false,
90
+ 'fetchOpenOrders': true,
91
+ 'fetchOrder': true,
92
+ 'fetchOrderBook': false,
93
+ 'fetchOrders': false,
94
+ 'fetchPosition': true,
95
+ 'fetchPositionMode': false,
96
+ 'fetchPositions': true,
97
+ 'fetchPositionsRisk': false,
98
+ 'fetchPremiumIndexOHLCV': false,
99
+ 'fetchTicker': true,
100
+ 'fetchTickers': true,
101
+ 'fetchTime': false,
102
+ 'fetchTrades': false,
103
+ 'fetchTradingFee': false,
104
+ 'fetchTradingFees': false,
105
+ 'fetchWithdrawals': true,
106
+ 'reduceMargin': false,
107
+ 'setLeverage': false,
108
+ 'setMargin': true,
109
+ 'setMarginMode': false,
110
+ 'setPositionMode': false,
111
+ 'withdraw': true,
112
+ },
113
+ 'urls': {
114
+ 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/866ae638-6ab5-4ebf-ab2c-cdcce9545625',
115
+ 'api': {
116
+ 'rest': 'https://api.international.coinbase.com/api',
117
+ },
118
+ 'test': {
119
+ 'rest': 'https://api-n5e1.coinbase.com/api',
120
+ },
121
+ 'www': 'https://international.coinbase.com',
122
+ 'doc': [
123
+ 'https://docs.cloud.coinbaseinternational.com/intx/docs',
124
+ ],
125
+ 'fees': [
126
+ 'https://help.coinbaseinternational.com/en/international-exchange/trading-deposits-withdrawals/international-exchange-fees',
127
+ ],
128
+ 'referral': '',
129
+ },
130
+ 'requiredCredentials': {
131
+ 'apiKey': true,
132
+ 'secret': true,
133
+ 'password': true,
134
+ },
135
+ 'api': {
136
+ 'v1': {
137
+ 'public': {
138
+ 'get': [
139
+ 'assets',
140
+ 'assets/{assets}',
141
+ 'assets/{asset}/networks',
142
+ 'instruments',
143
+ 'instruments/{instrument}',
144
+ 'instruments/{instrument}/quote',
145
+ 'instruments/{instrument}/funding',
146
+ '',
147
+ ],
148
+ },
149
+ 'private': {
150
+ 'get': [
151
+ 'orders',
152
+ 'orders/{id}',
153
+ 'portfolios',
154
+ 'portfolios/{portfolio}',
155
+ 'portfolios/{portfolio}/detail',
156
+ 'portfolios/{portfolio}/summary',
157
+ 'portfolios/{portfolio}/balances',
158
+ 'portfolios/{portfolio}/balances/{asset}',
159
+ 'portfolios/{portfolio}/positions',
160
+ 'portfolios/{portfolio}/positions/{instrument}',
161
+ 'portfolios/fills',
162
+ 'portfolios/{portfolio}/fills',
163
+ 'transfers',
164
+ 'transfers/{transfer_uuid}',
165
+ ],
166
+ 'post': [
167
+ 'orders',
168
+ 'portfolios',
169
+ 'portfolios/margin',
170
+ 'portfolios/transfer',
171
+ 'transfers/withdraw',
172
+ 'transfers/address',
173
+ 'transfers/create-counterparty-id',
174
+ 'transfers/validate-counterparty-id',
175
+ 'transfers/withdraw/counterparty',
176
+ ],
177
+ 'put': [
178
+ 'orders/{id}',
179
+ 'portfolios/{portfolio}',
180
+ ],
181
+ 'delete': [
182
+ 'orders',
183
+ 'orders/{id}',
184
+ ],
185
+ },
186
+ },
187
+ },
188
+ 'fees': {
189
+ 'trading': {
190
+ 'taker': this.parseNumber('0.004'),
191
+ 'maker': this.parseNumber('0.002'),
192
+ 'tierBased': true,
193
+ 'percentage': true,
194
+ 'tiers': {
195
+ 'taker': [
196
+ [this.parseNumber('0'), this.parseNumber('0.004')],
197
+ [this.parseNumber('1000000'), this.parseNumber('0.004')],
198
+ [this.parseNumber('5000000'), this.parseNumber('0.0035')],
199
+ [this.parseNumber('10000000'), this.parseNumber('0.0035')],
200
+ [this.parseNumber('50000000'), this.parseNumber('0.003')],
201
+ [this.parseNumber('250000000'), this.parseNumber('0.0025')],
202
+ ],
203
+ 'maker': [
204
+ [this.parseNumber('0'), this.parseNumber('0.002')],
205
+ [this.parseNumber('1000000'), this.parseNumber('0.0016')],
206
+ [this.parseNumber('5000000'), this.parseNumber('0.001')],
207
+ [this.parseNumber('10000000'), this.parseNumber('0.0008')],
208
+ [this.parseNumber('50000000'), this.parseNumber('0.0005')],
209
+ [this.parseNumber('250000000'), this.parseNumber('0')],
210
+ ],
211
+ },
212
+ },
213
+ },
214
+ 'precisionMode': TICK_SIZE,
215
+ 'exceptions': {
216
+ 'exact': {},
217
+ 'broad': {
218
+ 'DUPLICATE_CLIENT_ORDER_ID': DuplicateOrderId,
219
+ 'Order rejected': InvalidOrder,
220
+ 'market orders must be IoC': InvalidOrder,
221
+ 'tif is required': InvalidOrder,
222
+ 'Invalid replace order request': InvalidOrder,
223
+ 'Unauthorized': PermissionDenied,
224
+ 'invalid result_limit': BadRequest,
225
+ 'is a required field': BadRequest,
226
+ 'Not Found': BadRequest,
227
+ 'ip not allowed': AuthenticationError,
228
+ },
229
+ },
230
+ 'timeframes': {
231
+ '1m': 'ONE_MINUTE',
232
+ '5m': 'FIVE_MINUTE',
233
+ '15m': 'FIFTEEN_MINUTE',
234
+ '30m': 'THIRTY_MINUTE',
235
+ '1h': 'ONE_HOUR',
236
+ '2h': 'TWO_HOUR',
237
+ '6h': 'SIX_HOUR',
238
+ '1d': 'ONE_DAY',
239
+ },
240
+ 'options': {
241
+ 'brokerId': 'nfqkvdjp',
242
+ 'portfolio': '',
243
+ 'withdraw': {
244
+ 'method': 'v1PrivatePostTransfersWithdraw', // use v1PrivatePostTransfersWithdrawCounterparty for counterparty withdrawals
245
+ },
246
+ 'networksById': {
247
+ 'ethereum': 'ETH',
248
+ 'arbitrum': 'ARBITRUM',
249
+ 'avacchain': 'AVAX',
250
+ 'optimism': 'OPTIMISM',
251
+ 'polygon': 'MATIC',
252
+ 'solana': 'SOL',
253
+ 'bitcoin': 'BTC',
254
+ },
255
+ },
256
+ });
257
+ }
258
+ async handlePortfolioAndParams(methodName, params = {}) {
259
+ let portfolio = undefined;
260
+ [portfolio, params] = this.handleOptionAndParams(params, methodName, 'portfolio');
261
+ if ((portfolio !== undefined) && (portfolio !== '')) {
262
+ return [portfolio, params];
263
+ }
264
+ const defaultPortfolio = this.safeString(this.options, 'portfolio');
265
+ if ((defaultPortfolio !== undefined) && (defaultPortfolio !== '')) {
266
+ return [defaultPortfolio, params];
267
+ }
268
+ const accounts = await this.fetchAccounts();
269
+ for (let i = 0; i < accounts.length; i++) {
270
+ const account = accounts[i];
271
+ const info = this.safeDict(account, 'info', {});
272
+ if (this.safeBool(info, 'is_default')) {
273
+ const portfolioId = this.safeString(info, 'portfolio_id');
274
+ this.options['portfolio'] = portfolioId;
275
+ return [portfolioId, params];
276
+ }
277
+ }
278
+ throw new ArgumentsRequired(this.id + ' ' + methodName + '() requires a portfolio parameter or set the default portfolio with this.options["portfolio"]');
279
+ }
280
+ async handleNetworkIdAndParams(currencyCode, methodName, params) {
281
+ let networkId = undefined;
282
+ [networkId, params] = this.handleOptionAndParams(params, methodName, 'network_arn_id');
283
+ if (networkId === undefined) {
284
+ await this.loadCurrencyNetworks(currencyCode);
285
+ const networks = this.currencies[currencyCode]['networks'];
286
+ const network = this.safeString2(params, 'networkCode', 'network');
287
+ if (network === undefined) {
288
+ // find default network
289
+ if (this.isEmpty(networks)) {
290
+ throw new BadRequest(this.id + ' createDepositAddress network not found for currency ' + currencyCode + ' please specify networkId in params');
291
+ }
292
+ const defaultNetwork = this.findDefaultNetwork(networks);
293
+ networkId = defaultNetwork['id'];
294
+ }
295
+ else {
296
+ networkId = this.networkCodeToId(network, currencyCode);
297
+ }
298
+ }
299
+ return [networkId, params];
300
+ }
301
+ async fetchAccounts(params = {}) {
302
+ /**
303
+ * @method
304
+ * @name coinbaseinternational#fetchAccounts
305
+ * @description fetch all the accounts associated with a profile
306
+ * @see https://docs.cloud.coinbase.com/intx/reference/getportfolios
307
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
308
+ * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
309
+ */
310
+ await this.loadMarkets();
311
+ const response = await this.v1PrivateGetPortfolios(params);
312
+ //
313
+ // [
314
+ // {
315
+ // "portfolio_id":"1ap32qsc-1-0",
316
+ // "portfolio_uuid":"028d7f6c-b92c-7361-8b7e-2932711e5a22",
317
+ // "name":"CCXT Portfolio 030624-17:16",
318
+ // "user_uuid":"e6cf46b6-a32f-5fa7-addb-3324d4526fbd",
319
+ // "maker_fee_rate":"0",
320
+ // "taker_fee_rate":"0.0002",
321
+ // "trading_lock":false,
322
+ // "borrow_disabled":false,
323
+ // "is_lsp":false,
324
+ // "is_default":true,
325
+ // "cross_collateral_enabled":false
326
+ // }
327
+ // ]
328
+ //
329
+ return this.parseAccounts(response, params);
330
+ }
331
+ parseAccount(account) {
332
+ //
333
+ // {
334
+ // "portfolio_id":"1ap32qsc-1-0",
335
+ // "portfolio_uuid":"028d7f6c-b92c-7361-8b7e-2932711e5a22",
336
+ // "name":"CCXT Portfolio 030624-17:16",
337
+ // "user_uuid":"e6cf46b6-a32f-5fa7-addb-3324d4526fbd",
338
+ // "maker_fee_rate":"0",
339
+ // "taker_fee_rate":"0.0002",
340
+ // "trading_lock":false,
341
+ // "borrow_disabled":false,
342
+ // "is_lsp":false,
343
+ // "is_default":true,
344
+ // "cross_collateral_enabled":false
345
+ // }
346
+ //
347
+ return {
348
+ 'id': this.safeString2(account, 'portfolio_id', 'portfolio_uuid'),
349
+ 'type': undefined,
350
+ 'code': undefined,
351
+ 'info': account,
352
+ };
353
+ }
354
+ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
355
+ /**
356
+ * @method
357
+ * @name coinbaseinternational#fetchFundingRateHistory
358
+ * @description fetches historical funding rate prices
359
+ * @see https://docs.cloud.coinbase.com/intx/reference/getinstrumentfunding
360
+ * @param {string} symbol unified symbol of the market to fetch the funding rate history for
361
+ * @param {int} [since] timestamp in ms of the earliest funding rate to fetch
362
+ * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch
363
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
364
+ * @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)
365
+ */
366
+ if (symbol === undefined) {
367
+ throw new ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
368
+ }
369
+ await this.loadMarkets();
370
+ let paginate = false;
371
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'paginate');
372
+ let maxEntriesPerRequest = undefined;
373
+ [maxEntriesPerRequest, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'maxEntriesPerRequest', 100);
374
+ const pageKey = 'ccxtPageKey';
375
+ if (paginate) {
376
+ return await this.fetchPaginatedCallIncremental('fetchFundingRateHistory', symbol, since, limit, params, pageKey, maxEntriesPerRequest);
377
+ }
378
+ const market = this.market(symbol);
379
+ const page = this.safeInteger(params, pageKey, 1) - 1;
380
+ const request = {
381
+ 'instrument': market['id'],
382
+ 'result_offset': this.safeInteger2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
383
+ };
384
+ if (limit !== undefined) {
385
+ request['result_limit'] = limit;
386
+ }
387
+ const response = await this.v1PublicGetInstrumentsInstrumentFunding(this.extend(request, params));
388
+ //
389
+ // {
390
+ // "pagination":{
391
+ // "result_limit":"25",
392
+ // "result_offset":"0"
393
+ // },
394
+ // "results":[
395
+ // {
396
+ // "instrument_id":"149264167780483072",
397
+ // "funding_rate":"0.000011",
398
+ // "mark_price":"47388.1",
399
+ // "event_time":"2024-02-10T16:00:00Z"
400
+ // },
401
+ // ...
402
+ // ]
403
+ // }
404
+ //
405
+ const rawRates = this.safeList(response, 'results', []);
406
+ return this.parseFundingRateHistories(rawRates, market, since, limit);
407
+ }
408
+ parseFundingRateHistory(info, market = undefined) {
409
+ return this.parseFundingRate(info, market);
410
+ }
411
+ parseFundingRate(contract, market = undefined) {
412
+ //
413
+ // {
414
+ // "instrument_id":"149264167780483072",
415
+ // "funding_rate":"0.000011",
416
+ // "mark_price":"47388.1",
417
+ // "event_time":"2024-02-10T16:00:00Z"
418
+ // }
419
+ //
420
+ const fundingDatetime = this.safeString2(contract, 'event_time', 'time');
421
+ return {
422
+ 'info': contract,
423
+ 'symbol': this.safeSymbol(undefined, market),
424
+ 'markPrice': this.safeNumber(contract, 'mark_price'),
425
+ 'indexPrice': undefined,
426
+ 'interestRate': undefined,
427
+ 'estimatedSettlePrice': undefined,
428
+ 'timestamp': this.parse8601(fundingDatetime),
429
+ 'datetime': fundingDatetime,
430
+ 'fundingRate': this.safeNumber(contract, 'funding_rate'),
431
+ 'fundingTimestamp': this.parse8601(fundingDatetime),
432
+ 'fundingDatetime': fundingDatetime,
433
+ 'nextFundingRate': undefined,
434
+ 'nextFundingTimestamp': undefined,
435
+ 'nextFundingDatetime': undefined,
436
+ 'previousFundingRate': undefined,
437
+ 'previousFundingTimestamp': undefined,
438
+ 'previousFundingDatetime': undefined,
439
+ };
440
+ }
441
+ async createDepositAddress(code, params = {}) {
442
+ /**
443
+ * @method
444
+ * @name coinbaseinternational#createDepositAddress
445
+ * @description create a currency deposit address
446
+ * @see https://docs.cloud.coinbase.com/intx/reference/createaddress
447
+ * @see https://docs.cloud.coinbase.com/intx/reference/createcounterpartyid
448
+ * @param {string} code unified currency code of the currency for the deposit address
449
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
450
+ * @param {string} [params.network_arn_id] Identifies the blockchain network (e.g., networks/ethereum-mainnet/assets/313ef8a9-ae5a-5f2f-8a56-572c0e2a4d5a) if not provided will pick default
451
+ * @param {string} [params.network] unified network code to identify the blockchain network
452
+ * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
453
+ */
454
+ await this.loadMarkets();
455
+ let method = undefined;
456
+ [method, params] = this.handleOptionAndParams(params, 'createDepositAddress', 'method', 'v1PrivatePostTransfersAddress');
457
+ let portfolio = undefined;
458
+ [portfolio, params] = await this.handlePortfolioAndParams('createDepositAddress', params);
459
+ const request = {
460
+ 'portfolio': portfolio,
461
+ };
462
+ if (method === 'v1PrivatePostTransfersAddress') {
463
+ const currency = this.currency(code);
464
+ request['asset'] = currency['id'];
465
+ let networkId = undefined;
466
+ [networkId, params] = await this.handleNetworkIdAndParams(code, 'createDepositAddress', params);
467
+ request['network_arn_id'] = networkId;
468
+ }
469
+ const response = await this[method](this.extend(request, params));
470
+ //
471
+ // v1PrivatePostTransfersAddress
472
+ // {
473
+ // address: "3LkwYscRyh6tUR1XTqXSJQoJnK7ucC1F4n",
474
+ // network_arn_id: "networks/bitcoin-mainnet/assets/6ecc0dcc-10a2-500e-b315-a3b9abae19ce",
475
+ // destination_tag: "",
476
+ // }
477
+ // v1PrivatePostTransfersCreateCounterpartyId
478
+ // {
479
+ // "portfolio_uuid":"018e0a8b-6b6b-70e0-9689-1e7926c2c8bc",
480
+ // "counterparty_id":"CB2ZPUCZBE"
481
+ // }
482
+ //
483
+ const tag = this.safeString(response, 'destination_tag');
484
+ const address = this.safeString2(response, 'address', 'counterparty_id');
485
+ return {
486
+ 'currency': code,
487
+ 'tag': tag,
488
+ 'address': address,
489
+ 'info': response,
490
+ };
491
+ }
492
+ findDefaultNetwork(networks) {
493
+ const networksArray = this.toArray(networks);
494
+ for (let i = 0; i < networksArray.length; i++) {
495
+ const info = networksArray[i]['info'];
496
+ const is_default = this.safeBool(info, 'is_default', false);
497
+ if (is_default === true) {
498
+ return networksArray[i];
499
+ }
500
+ }
501
+ return networksArray[0];
502
+ }
503
+ async loadCurrencyNetworks(code, params = {}) {
504
+ const currency = this.currency(code);
505
+ const networks = this.safeDict(currency, 'networks');
506
+ if (networks !== undefined) {
507
+ return;
508
+ }
509
+ const request = {
510
+ 'asset': currency['id'],
511
+ };
512
+ const rawNetworks = await this.v1PublicGetAssetsAssetNetworks(request);
513
+ //
514
+ // [
515
+ // {
516
+ // "asset_id":"1",
517
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
518
+ // "asset_name":"USDC",
519
+ // "network_arn_id":"networks/ethereum-mainnet/assets/9bc140b4-69c3-5fc9-bd0d-b041bcf40039",
520
+ // "min_withdrawal_amt":"1",
521
+ // "max_withdrawal_amt":"100000000",
522
+ // "network_confirms":35,
523
+ // "processing_time":485,
524
+ // "is_default":true,
525
+ // "network_name":"ethereum",
526
+ // "display_name":"Ethereum"
527
+ // },
528
+ // ....
529
+ // ]
530
+ //
531
+ currency['networks'] = this.parseNetworks(rawNetworks);
532
+ }
533
+ parseNetworks(networks, params = {}) {
534
+ const result = {};
535
+ for (let i = 0; i < networks.length; i++) {
536
+ const network = this.extend(this.parseNetwork(networks[i]), params);
537
+ result[network['network']] = network;
538
+ }
539
+ return result;
540
+ }
541
+ parseNetwork(network, params = {}) {
542
+ //
543
+ // {
544
+ // "asset_id":"1",
545
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
546
+ // "asset_name":"USDC",
547
+ // "network_arn_id":"networks/ethereum-mainnet/assets/9bc140b4-69c3-5fc9-bd0d-b041bcf40039",
548
+ // "min_withdrawal_amt":"1",
549
+ // "max_withdrawal_amt":"100000000",
550
+ // "network_confirms":35,
551
+ // "processing_time":485,
552
+ // "is_default":true,
553
+ // "network_name":"ethereum",
554
+ // "display_name":"Ethereum"
555
+ // }
556
+ //
557
+ const currencyId = this.safeString(network, 'asset_name');
558
+ const currencyCode = this.safeCurrencyCode(currencyId);
559
+ const networkId = this.safeString(network, 'network_arn_id');
560
+ return this.safeNetwork({
561
+ 'info': network,
562
+ 'id': networkId,
563
+ 'name': this.safeString(network, 'display_name'),
564
+ 'network': this.networkIdToCode(this.safeStringN(network, ['network_name', 'display_name', 'network_arn_id'], ''), currencyCode),
565
+ 'active': undefined,
566
+ 'deposit': undefined,
567
+ 'withdraw': undefined,
568
+ 'precision': undefined,
569
+ 'fee': undefined,
570
+ 'limits': {
571
+ 'withdraw': {
572
+ 'min': this.safeNumber(network, 'min_withdrawal_amt'),
573
+ 'max': this.safeNumber(network, 'max_withdrawal_amt'),
574
+ },
575
+ 'deposit': {
576
+ 'min': undefined,
577
+ 'max': undefined,
578
+ },
579
+ },
580
+ });
581
+ }
582
+ async setMargin(symbol, amount, params = {}) {
583
+ /**
584
+ * @method
585
+ * @name coinbaseinternational#setMargin
586
+ * @description Either adds or reduces margin in order to set the margin to a specific value
587
+ * @see https://docs.cloud.coinbase.com/intx/reference/setportfoliomarginoverride
588
+ * @param {string} symbol unified market symbol of the market to set margin in
589
+ * @param {float} amount the amount to set the margin to
590
+ * @param {object} [params] parameters specific to the exchange API endpoint
591
+ * @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure}
592
+ */
593
+ let portfolio = undefined;
594
+ [portfolio, params] = await this.handlePortfolioAndParams('setMargin', params);
595
+ if (symbol !== undefined) {
596
+ throw new BadRequest(this.id + ' setMargin() only allows setting margin to full portfolio');
597
+ }
598
+ const request = {
599
+ 'portfolio': portfolio,
600
+ 'margin_override': amount,
601
+ };
602
+ return await this.v1PrivatePostPortfoliosMargin(this.extend(request, params));
603
+ }
604
+ async fetchDepositsWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
605
+ /**
606
+ * @method
607
+ * @name exchange#fetchDepositsWithdrawals
608
+ * @description fetch history of deposits and withdrawals
609
+ * @see https://docs.cloud.coinbase.com/intx/reference/gettransfers
610
+ * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
611
+ * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
612
+ * @param {int} [limit] max number of deposit/withdrawals to return, default is undefined
613
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
614
+ * @param {string} [params.portfolios] Identifies the portfolios by UUID (e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID (e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
615
+ * @param {int} [params.until] Only find transfers updated before this time. Use timestamp format
616
+ * @param {string} [params.status] The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
617
+ * @param {string} [params.type] The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
618
+ * @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)
619
+ * @returns {object} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
620
+ */
621
+ await this.loadMarkets();
622
+ let paginate = undefined;
623
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchDepositsWithdrawals', 'paginate');
624
+ let maxEntriesPerRequest = undefined;
625
+ [maxEntriesPerRequest, params] = this.handleOptionAndParams(params, 'fetchDepositsWithdrawals', 'maxEntriesPerRequest', 100);
626
+ const pageKey = 'ccxtPageKey';
627
+ if (paginate) {
628
+ return await this.fetchPaginatedCallIncremental('fetchDepositsWithdrawals', code, since, limit, params, pageKey, maxEntriesPerRequest);
629
+ }
630
+ const page = this.safeInteger(params, pageKey, 1) - 1;
631
+ const request = {
632
+ 'result_offset': this.safeInteger2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
633
+ };
634
+ if (since !== undefined) {
635
+ request['time_from'] = this.iso8601(since);
636
+ }
637
+ if (limit !== undefined) {
638
+ const newLimit = Math.min(limit, 100);
639
+ request['result_limit'] = newLimit;
640
+ }
641
+ let portfolios = undefined;
642
+ [portfolios, params] = this.handleOptionAndParams(params, 'fetchDepositsWithdrawals', 'portfolios');
643
+ if (portfolios !== undefined) {
644
+ request['portfolios'] = portfolios;
645
+ }
646
+ let until = undefined;
647
+ [until, params] = this.handleOptionAndParams(params, 'fetchDepositsWithdrawals', 'until');
648
+ if (until !== undefined) {
649
+ request['time_to'] = this.iso8601(until);
650
+ }
651
+ const response = await this.v1PrivateGetTransfers(this.extend(request, params));
652
+ //
653
+ // {
654
+ // "pagination":{
655
+ // "result_limit":25,
656
+ // "result_offset":0
657
+ // },
658
+ // "results":[
659
+ // {
660
+ // "transfer_uuid":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3",
661
+ // "transfer_type":"WITHDRAW",
662
+ // "amount":"1.000000",
663
+ // "asset":"USDC",
664
+ // "status":"PROCESSED",
665
+ // "network_name":"ethereum",
666
+ // "created_at":"2024-03-14T02:32:18.497795Z",
667
+ // "updated_at":"2024-03-14T02:35:38.514588Z",
668
+ // "from_portfolio":{
669
+ // "id":"1yun54bb-1-6",
670
+ // "uuid":"018e0a8b-6b6b-70e0-9689-1e7926c2c8bc",
671
+ // "name":"fungus technology o?Portfolio"
672
+ // },
673
+ // "to_address":"0xcdcE79F820BE9d6C5033db5c31d1AE3A8c2399bB"
674
+ // }
675
+ // ]
676
+ // }
677
+ //
678
+ const rawTransactions = this.safeList(response, 'results', []);
679
+ return this.parseTransactions(rawTransactions);
680
+ }
681
+ async fetchPosition(symbol, params = {}) {
682
+ /**
683
+ * @method
684
+ * @name coinbaseinternational#fetchPosition
685
+ * @see https://docs.cloud.coinbase.com/intx/reference/getportfolioposition
686
+ * @description fetch data on an open position
687
+ * @param {string} symbol unified market symbol of the market the position is held in
688
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
689
+ * @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
690
+ */
691
+ await this.loadMarkets();
692
+ symbol = this.symbol(symbol);
693
+ let portfolio = undefined;
694
+ [portfolio, params] = await this.handlePortfolioAndParams('fetchPosition', params);
695
+ const request = {
696
+ 'portfolio': portfolio,
697
+ 'instrument': this.marketId(symbol),
698
+ };
699
+ const position = await this.v1PrivateGetPortfoliosPortfolioPositionsInstrument(this.extend(request, params));
700
+ //
701
+ // {
702
+ // "symbol":"BTC-PERP",
703
+ // "instrument_id":"114jqr89-0-0",
704
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
705
+ // "vwap":"52482.3",
706
+ // "net_size":"0",
707
+ // "buy_order_size":"0.001",
708
+ // "sell_order_size":"0",
709
+ // "im_contribution":"0.2",
710
+ // "unrealized_pnl":"0",
711
+ // "mark_price":"52406.8",
712
+ // "entry_vwap":"52472.9"
713
+ // }
714
+ //
715
+ return this.parsePosition(position);
716
+ }
717
+ parsePosition(position, market = undefined) {
718
+ //
719
+ // {
720
+ // "symbol":"BTC-PERP",
721
+ // "instrument_id":"114jqr89-0-0",
722
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
723
+ // "vwap":"52482.3",
724
+ // "net_size":"0",
725
+ // "buy_order_size":"0.001",
726
+ // "sell_order_size":"0",
727
+ // "im_contribution":"0.2",
728
+ // "unrealized_pnl":"0",
729
+ // "mark_price":"52406.8",
730
+ // "entry_vwap":"52472.9"
731
+ // }
732
+ //
733
+ const marketId = this.safeString(position, 'symbol');
734
+ let quantity = this.safeString(position, 'net_size');
735
+ market = this.safeMarket(marketId, market, '-');
736
+ let side = 'long';
737
+ if (Precise.stringLe(quantity, '0')) {
738
+ side = 'short';
739
+ quantity = Precise.stringMul('-1', quantity);
740
+ }
741
+ return this.safePosition({
742
+ 'info': position,
743
+ 'id': this.safeString(position, 'id'),
744
+ 'symbol': market['symbol'],
745
+ 'entryPrice': undefined,
746
+ 'markPrice': this.safeNumber(position, 'mark_price'),
747
+ 'notional': undefined,
748
+ 'collateral': undefined,
749
+ 'unrealizedPnl': this.safeNumber(position, 'unrealized_pnl'),
750
+ 'side': side,
751
+ 'contracts': this.parseNumber(quantity),
752
+ 'contractSize': this.safeNumber(market, 'contractSize'),
753
+ 'timestamp': undefined,
754
+ 'datetime': undefined,
755
+ 'hedged': undefined,
756
+ 'maintenanceMargin': undefined,
757
+ 'maintenanceMarginPercentage': undefined,
758
+ 'initialMargin': this.safeNumber(position, 'im_contribution'),
759
+ 'initialMarginPercentage': undefined,
760
+ 'leverage': undefined,
761
+ 'liquidationPrice': undefined,
762
+ 'marginRatio': undefined,
763
+ 'marginMode': undefined,
764
+ 'percentage': undefined,
765
+ });
766
+ }
767
+ async fetchPositions(symbols = undefined, params = {}) {
768
+ /**
769
+ * @method
770
+ * @name coinbaseinternational#fetchPositions
771
+ * @see https://docs.cloud.coinbase.com/intx/reference/getportfoliopositions
772
+ * @description fetch all open positions
773
+ * @param {string[]} [symbols] list of unified market symbols
774
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
775
+ * @param {string} [method] method name to call, "positionRisk", "account" or "option", default is "positionRisk"
776
+ * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
777
+ */
778
+ await this.loadMarkets();
779
+ let portfolio = undefined;
780
+ [portfolio, params] = await this.handlePortfolioAndParams('fetchPositions', params);
781
+ const request = {
782
+ 'portfolio': portfolio,
783
+ };
784
+ const response = await this.v1PrivateGetPortfoliosPortfolioPositions(this.extend(request, params));
785
+ //
786
+ // [
787
+ // {
788
+ // "symbol":"BTC-PERP",
789
+ // "instrument_id":"114jqr89-0-0",
790
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
791
+ // "vwap":"52482.3",
792
+ // "net_size":"0",
793
+ // "buy_order_size":"0.001",
794
+ // "sell_order_size":"0",
795
+ // "im_contribution":"0.2",
796
+ // "unrealized_pnl":"0",
797
+ // "mark_price":"52406.8",
798
+ // "entry_vwap":"52472.9"
799
+ // }
800
+ // ]
801
+ //
802
+ const positions = this.parsePositions(response);
803
+ if (this.isEmpty(symbols)) {
804
+ return positions;
805
+ }
806
+ symbols = this.marketSymbols(symbols);
807
+ return this.filterByArrayPositions(positions, 'symbol', symbols, false);
808
+ }
809
+ async fetchWithdrawals(code = undefined, since = undefined, limit = undefined, params = {}) {
810
+ /**
811
+ * @method
812
+ * @name coinbaseinternational#fetchWithdrawals
813
+ * @description fetch all withdrawals made from an account
814
+ * @see https://docs.cloud.coinbase.com/intx/reference/gettransfers
815
+ * @param {string} code unified currency code
816
+ * @param {int} [since] the earliest time in ms to fetch withdrawals for
817
+ * @param {int} [limit] the maximum number of withdrawals structures to retrieve
818
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
819
+ * @param {string} [params.portfolios] Identifies the portfolios by UUID (e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID (e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
820
+ * @param {int} [params.until] Only find transfers updated before this time. Use timestamp format
821
+ * @param {string} [params.status] The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
822
+ * @param {string} [params.type] The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
823
+ * @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)
824
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
825
+ */
826
+ await this.loadMarkets();
827
+ params['type'] = 'WITHDRAW';
828
+ return await this.fetchDepositsWithdrawals(code, since, limit, params);
829
+ }
830
+ async fetchDeposits(code = undefined, since = undefined, limit = undefined, params = {}) {
831
+ /**
832
+ * @method
833
+ * @name coinbaseinternational#fetchDeposits
834
+ * @description fetch all deposits made to an account
835
+ * @param {string} code unified currency code
836
+ * @param {int} [since] the earliest time in ms to fetch deposits for
837
+ * @param {int} [limit] the maximum number of deposits structures to retrieve
838
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
839
+ * @param {string} [params.portfolios] Identifies the portfolios by UUID (e.g., 892e8c7c-e979-4cad-b61b-55a197932cf1) or portfolio ID (e.g., 5189861793641175). Can provide single or multiple portfolios to filter by or fetches transfers for all portfolios if none are provided.
840
+ * @param {int} [params.until] Only find transfers updated before this time. Use timestamp format
841
+ * @param {string} [params.status] The current status of transfer. Possible values: [PROCESSED, NEW, FAILED, STARTED]
842
+ * @param {string} [params.type] The type of transfer Possible values: [DEPOSIT, WITHDRAW, REBATE, STIPEND, INTERNAL, FUNDING]
843
+ * @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)
844
+ * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
845
+ */
846
+ await this.loadMarkets();
847
+ params['type'] = 'DEPOSIT';
848
+ return await this.fetchDepositsWithdrawals(code, since, limit, params);
849
+ }
850
+ parseTransactionStatus(status) {
851
+ const statuses = {
852
+ 'PROCESSED': 'ok',
853
+ 'NEW': 'pending',
854
+ 'STARTED': 'pending',
855
+ 'FAILED': 'canceled',
856
+ };
857
+ return this.safeString(statuses, status, status);
858
+ }
859
+ parseTransaction(transaction, currency = undefined) {
860
+ //
861
+ // {
862
+ // "idem":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3"
863
+ // }
864
+ // const transactionType = this.safeString (transaction, 'type');
865
+ const datetime = this.safeString(transaction, 'updated_at');
866
+ const fromPorfolio = this.safeDict(transaction, 'from_portfolio', {});
867
+ const addressFrom = this.safeStringN(transaction, ['from_address', 'from_cb_account', this.safeStringN(fromPorfolio, ['id', 'uuid', 'name']), 'from_counterparty_id']);
868
+ const toPorfolio = this.safeDict(transaction, 'from_portfolio', {});
869
+ const addressTo = this.safeStringN(transaction, ['to_address', 'to_cb_account', this.safeStringN(toPorfolio, ['id', 'uuid', 'name']), 'to_counterparty_id']);
870
+ return {
871
+ 'info': transaction,
872
+ 'id': this.safeString(transaction, 'transfer_uuid'),
873
+ 'txid': this.safeString(transaction, 'transaction_uuid'),
874
+ 'timestamp': this.parse8601(datetime),
875
+ 'datetime': datetime,
876
+ 'network': this.networkIdToCode(this.safeString(transaction, 'network_name')),
877
+ 'address': undefined,
878
+ 'addressTo': addressTo,
879
+ 'addressFrom': addressFrom,
880
+ 'tag': undefined,
881
+ 'tagTo': undefined,
882
+ 'tagFrom': undefined,
883
+ 'type': this.safeString(transaction, 'resource'),
884
+ 'amount': this.safeNumber(transaction, 'amount'),
885
+ 'currency': this.safeCurrencyCode(this.safeString(transaction, 'asset'), currency),
886
+ 'status': this.parseTransactionStatus(this.safeString(transaction, 'status')),
887
+ 'updated': this.parse8601(datetime),
888
+ 'fee': {
889
+ 'cost': undefined,
890
+ 'currency': undefined,
891
+ },
892
+ };
893
+ }
894
+ parseTrade(trade, market = undefined) {
895
+ //
896
+ // {
897
+ // "portfolio_id":"1wp37qsc-1-0",
898
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
899
+ // "portfolio_name":"CCXT Portfolio 020624-17:16",
900
+ // "fill_id":"1xbfy19y-1-184",
901
+ // "exec_id":"280841526207070392",
902
+ // "order_id":"1xbfv8yw-1-0",
903
+ // "instrument_id":"114jqr89-0-0",
904
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
905
+ // "symbol":"BTC-PERP",
906
+ // "match_id":"280841526207053840",
907
+ // "fill_price":"52500",
908
+ // "fill_qty":"0.01",
909
+ // "client_id":"1x59ctku-1-1",
910
+ // "client_order_id":"ccxt3e4e2a5f-4a89-",
911
+ // "order_qty":"0.01",
912
+ // "limit_price":"52500",
913
+ // "total_filled":"0.01",
914
+ // "filled_vwap":"52500",
915
+ // "expire_time":"",
916
+ // "stop_price":"",
917
+ // "side":"BUY",
918
+ // "tif":"GTC",
919
+ // "stp_mode":"BOTH",
920
+ // "flags":"",
921
+ // "fee":"0.105",
922
+ // "fee_asset":"USDC",
923
+ // "order_status":"DONE",
924
+ // "event_time":"2024-02-15T00:43:57.631Z"
925
+ // }
926
+ //
927
+ const marketId = this.safeString(trade, 'symbol');
928
+ const datetime = this.safeString(trade, 'event_time');
929
+ return this.safeTrade({
930
+ 'info': trade,
931
+ 'id': this.safeString2(trade, 'fill_id', 'exec_id'),
932
+ 'order': this.safeString(trade, 'order_id'),
933
+ 'timestamp': this.parse8601(datetime),
934
+ 'datetime': datetime,
935
+ 'symbol': this.safeSymbol(marketId, market),
936
+ 'type': undefined,
937
+ 'side': this.safeStringLower(trade, 'side'),
938
+ 'takerOrMaker': undefined,
939
+ 'price': this.safeNumber(trade, 'fill_price'),
940
+ 'amount': this.safeNumber(trade, 'fill_qty'),
941
+ 'cost': undefined,
942
+ 'fee': {
943
+ 'cost': this.safeNumber(trade, 'fee'),
944
+ 'currency': this.safeCurrencyCode(this.safeString(trade, 'fee_asset')),
945
+ },
946
+ });
947
+ }
948
+ async fetchMarkets(params = {}) {
949
+ /**
950
+ * @method
951
+ * @name coinbaseinternational#fetchMarkets
952
+ * @see https://docs.cloud.coinbase.com/intx/reference/getinstruments
953
+ * @description retrieves data on all markets for coinbaseinternational
954
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
955
+ * @returns {object[]} an array of objects representing market data
956
+ */
957
+ const response = await this.v1PublicGetInstruments(params);
958
+ //
959
+ // [
960
+ // {
961
+ // "instrument_id":"149264164756389888",
962
+ // "instrument_uuid":"e9360798-6a10-45d6-af05-67c30eb91e2d",
963
+ // "symbol":"ETH-PERP",
964
+ // "type":"PERP",
965
+ // "base_asset_id":"118059611793145856",
966
+ // "base_asset_uuid":"d85dce9b-5b73-5c3c-8978-522ce1d1c1b4",
967
+ // "base_asset_name":"ETH",
968
+ // "quote_asset_id":"1",
969
+ // "quote_asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
970
+ // "quote_asset_name":"USDC",
971
+ // "base_increment":"0.0001",
972
+ // "quote_increment":"0.01",
973
+ // "price_band_percent":"0.02",
974
+ // "market_order_percent":"0.0075",
975
+ // "qty_24hr":"44434.8131",
976
+ // "notional_24hr":"110943454.279785",
977
+ // "avg_daily_qty":"1099171.6025",
978
+ // "avg_daily_notional":"2637240145.456987",
979
+ // "previous_day_qty":"78909.3939",
980
+ // "open_interest":"1270.749",
981
+ // "position_limit_qty":"1831.9527",
982
+ // "position_limit_adq_pct":"0.05",
983
+ // "replacement_cost":"0.23",
984
+ // "base_imf":"0.1",
985
+ // "min_notional_value":"10",
986
+ // "funding_interval":"3600000000000",
987
+ // "trading_state":"TRADING",
988
+ // "quote":{
989
+ // "best_bid_price":"2490.8",
990
+ // "best_bid_size":"9.0515",
991
+ // "best_ask_price":"2490.81",
992
+ // "best_ask_size":"4.8486",
993
+ // "trade_price":"2490.39",
994
+ // "trade_qty":"0.9508",
995
+ // "index_price":"2490.5",
996
+ // "mark_price":"2490.8",
997
+ // "settlement_price":"2490.81",
998
+ // "limit_up":"2615.42",
999
+ // "limit_down":"2366.34",
1000
+ // "predicted_funding":"0.000009",
1001
+ // "timestamp":"2024-02-10T16:07:39.454Z"
1002
+ // }
1003
+ // },
1004
+ // ...
1005
+ // ]
1006
+ //
1007
+ return this.parseMarkets(response);
1008
+ }
1009
+ parseMarket(market) {
1010
+ //
1011
+ // {
1012
+ // "instrument_id":"149264164756389888",
1013
+ // "instrument_uuid":"e9360798-6a10-45d6-af05-67c30eb91e2d",
1014
+ // "symbol":"ETH-PERP",
1015
+ // "type":"PERP",
1016
+ // "base_asset_id":"118059611793145856",
1017
+ // "base_asset_uuid":"d85dce9b-5b73-5c3c-8978-522ce1d1c1b4",
1018
+ // "base_asset_name":"ETH",
1019
+ // "quote_asset_id":"1",
1020
+ // "quote_asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1021
+ // "quote_asset_name":"USDC",
1022
+ // "base_increment":"0.0001",
1023
+ // "quote_increment":"0.01",
1024
+ // "price_band_percent":"0.02",
1025
+ // "market_order_percent":"0.0075",
1026
+ // "qty_24hr":"44434.8131",
1027
+ // "notional_24hr":"110943454.279785",
1028
+ // "avg_daily_qty":"1099171.6025",
1029
+ // "avg_daily_notional":"2637240145.456987",
1030
+ // "previous_day_qty":"78909.3939",
1031
+ // "open_interest":"1270.749",
1032
+ // "position_limit_qty":"1831.9527",
1033
+ // "position_limit_adq_pct":"0.05",
1034
+ // "replacement_cost":"0.23",
1035
+ // "base_imf":"0.1",
1036
+ // "min_notional_value":"10",
1037
+ // "funding_interval":"3600000000000",
1038
+ // "trading_state":"TRADING",
1039
+ // "quote":{
1040
+ // "best_bid_price":"2490.8",
1041
+ // "best_bid_size":"9.0515",
1042
+ // "best_ask_price":"2490.81",
1043
+ // "best_ask_size":"4.8486",
1044
+ // "trade_price":"2490.39",
1045
+ // "trade_qty":"0.9508",
1046
+ // "index_price":"2490.5",
1047
+ // "mark_price":"2490.8",
1048
+ // "settlement_price":"2490.81",
1049
+ // "limit_up":"2615.42",
1050
+ // "limit_down":"2366.34",
1051
+ // "predicted_funding":"0.000009",
1052
+ // "timestamp":"2024-02-10T16:07:39.454Z"
1053
+ // }
1054
+ // }
1055
+ //
1056
+ const marketId = this.safeString(market, 'symbol');
1057
+ const baseId = this.safeString(market, 'base_asset_name');
1058
+ const quoteId = this.safeString(market, 'quote_asset_name');
1059
+ const typeId = this.safeString(market, 'type'); // 'SPOT', 'PERP'
1060
+ const isSpot = (typeId === 'SPOT');
1061
+ const fees = this.fees;
1062
+ let symbol = baseId + '/' + quoteId;
1063
+ let settleId = undefined;
1064
+ if (!isSpot) {
1065
+ settleId = quoteId;
1066
+ symbol += ':' + quoteId;
1067
+ }
1068
+ return {
1069
+ 'id': marketId,
1070
+ 'lowercaseId': marketId.toLowerCase(),
1071
+ 'symbol': symbol,
1072
+ 'base': baseId,
1073
+ 'quote': quoteId,
1074
+ 'settle': settleId ? settleId : undefined,
1075
+ 'baseId': baseId,
1076
+ 'quoteId': quoteId,
1077
+ 'settleId': settleId ? settleId : undefined,
1078
+ 'type': isSpot ? 'spot' : 'swap',
1079
+ 'spot': isSpot,
1080
+ 'margin': false,
1081
+ 'swap': !isSpot,
1082
+ 'future': false,
1083
+ 'option': false,
1084
+ 'active': this.safeString(market, 'trading_state') === 'TRADING',
1085
+ 'contract': !isSpot,
1086
+ 'linear': isSpot ? undefined : (settleId === quoteId),
1087
+ 'inverse': isSpot ? undefined : (settleId !== quoteId),
1088
+ 'taker': fees['trading']['taker'],
1089
+ 'maker': fees['trading']['maker'],
1090
+ 'contractSize': isSpot ? undefined : 1,
1091
+ 'expiry': undefined,
1092
+ 'expiryDatetime': undefined,
1093
+ 'strike': undefined,
1094
+ 'optionType': undefined,
1095
+ 'precision': {
1096
+ 'amount': this.safeNumber(market, 'base_increment'),
1097
+ 'price': this.safeNumber(market, 'quote_increment'),
1098
+ 'cost': this.safeNumber(market, 'quote_increment'),
1099
+ },
1100
+ 'limits': {
1101
+ 'leverage': {
1102
+ 'min': undefined,
1103
+ 'max': this.safeNumber(market, 'base_imf'),
1104
+ },
1105
+ 'amount': {
1106
+ 'min': undefined,
1107
+ 'max': isSpot ? undefined : this.safeNumber(market, 'position_limit_qty'),
1108
+ },
1109
+ 'price': {
1110
+ 'min': undefined,
1111
+ 'max': undefined,
1112
+ },
1113
+ 'cost': {
1114
+ 'min': this.safeNumber(market, 'min_notional_value'),
1115
+ 'max': undefined,
1116
+ },
1117
+ },
1118
+ 'info': market,
1119
+ 'created': undefined,
1120
+ };
1121
+ }
1122
+ async fetchCurrencies(params = {}) {
1123
+ /**
1124
+ * @method
1125
+ * @name coinbaseinternational#fetchCurrencies
1126
+ * @description fetches all available currencies on an exchange
1127
+ * @see https://docs.cloud.coinbase.com/intx/reference/getassets
1128
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1129
+ * @returns {object} an associative dictionary of currencies
1130
+ */
1131
+ const currencies = await this.v1PublicGetAssets(params);
1132
+ //
1133
+ // [
1134
+ // {
1135
+ // "asset_id":"1",
1136
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1137
+ // "asset_name":"USDC",
1138
+ // "status":"ACTIVE",
1139
+ // "collateral_weight":1.0,
1140
+ // "supported_networks_enabled":true
1141
+ // },
1142
+ // ...
1143
+ // ]
1144
+ //
1145
+ const result = {};
1146
+ for (let i = 0; i < currencies.length; i++) {
1147
+ const currency = this.parseCurrency(currencies[i]);
1148
+ result[currency['code']] = currency;
1149
+ }
1150
+ return result;
1151
+ }
1152
+ parseCurrency(currency) {
1153
+ //
1154
+ // {
1155
+ // "asset_id":"1",
1156
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1157
+ // "asset_name":"USDC",
1158
+ // "status":"ACTIVE",
1159
+ // "collateral_weight":1.0,
1160
+ // "supported_networks_enabled":true
1161
+ // }
1162
+ //
1163
+ const id = this.safeString(currency, 'asset_name');
1164
+ const code = this.safeCurrencyCode(id);
1165
+ const statusId = this.safeString(currency, 'status');
1166
+ return {
1167
+ 'id': id,
1168
+ 'name': code,
1169
+ 'code': code,
1170
+ 'precision': undefined,
1171
+ 'info': currency,
1172
+ 'active': (statusId === 'ACTIVE'),
1173
+ 'deposit': undefined,
1174
+ 'withdraw': undefined,
1175
+ 'networks': undefined,
1176
+ 'fee': undefined,
1177
+ 'fees': undefined,
1178
+ 'limits': this.limits,
1179
+ };
1180
+ }
1181
+ async fetchTickers(symbols = undefined, params = {}) {
1182
+ /**
1183
+ * @method
1184
+ * @name coinbaseinternational#fetchTickers
1185
+ * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1186
+ * @see https://docs.cloud.coinbase.com/intx/reference/getinstruments
1187
+ * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1188
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1189
+ * @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1190
+ */
1191
+ await this.loadMarkets();
1192
+ symbols = this.marketSymbols(symbols);
1193
+ const instruments = await this.v1PublicGetInstruments(params);
1194
+ const tickers = {};
1195
+ for (let i = 0; i < instruments.length; i++) {
1196
+ const instrument = instruments[i];
1197
+ const marketId = this.safeString(instrument, 'symbol');
1198
+ const symbol = this.safeSymbol(marketId);
1199
+ const quote = this.safeDict(instrument, 'quote', {});
1200
+ tickers[symbol] = this.parseTicker(quote, this.safeMarket(marketId));
1201
+ }
1202
+ return this.filterByArray(tickers, 'symbol', symbols, true);
1203
+ }
1204
+ async fetchTicker(symbol, params = {}) {
1205
+ /**
1206
+ * @method
1207
+ * @name coinbaseinternational#fetchTicker
1208
+ * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1209
+ * @see https://docs.cloud.coinbase.com/intx/reference/getinstrumentquote
1210
+ * @param {string} symbol unified symbol of the market to fetch the ticker for
1211
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1212
+ * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
1213
+ */
1214
+ await this.loadMarkets();
1215
+ const market = this.market(symbol);
1216
+ const request = {
1217
+ 'instrument': this.marketId(symbol),
1218
+ };
1219
+ const ticker = await this.v1PublicGetInstrumentsInstrumentQuote(this.extend(request, params));
1220
+ return this.parseTicker(ticker, market);
1221
+ }
1222
+ parseTicker(ticker, market = undefined) {
1223
+ //
1224
+ // {
1225
+ // "best_bid_price":"2490.8",
1226
+ // "best_bid_size":"9.0515",
1227
+ // "best_ask_price":"2490.81",
1228
+ // "best_ask_size":"4.8486",
1229
+ // "trade_price":"2490.39",
1230
+ // "trade_qty":"0.9508",
1231
+ // "index_price":"2490.5",
1232
+ // "mark_price":"2490.8",
1233
+ // "settlement_price":"2490.81",
1234
+ // "limit_up":"2615.42",
1235
+ // "limit_down":"2366.34",
1236
+ // "predicted_funding":"0.000009",
1237
+ // "timestamp":"2024-02-10T16:07:39.454Z"
1238
+ // }
1239
+ //
1240
+ const datetime = this.safeString(ticker, 'timestamp');
1241
+ return this.safeTicker({
1242
+ 'info': ticker,
1243
+ 'symbol': this.safeSymbol(undefined, market),
1244
+ 'timestamp': this.parse8601(datetime),
1245
+ 'datetime': datetime,
1246
+ 'bid': this.safeNumber(ticker, 'best_bid_price'),
1247
+ 'bidVolume': this.safeNumber(ticker, 'best_bid_size'),
1248
+ 'ask': this.safeNumber(ticker, 'best_ask_price'),
1249
+ 'askVolume': this.safeNumber(ticker, 'best_ask_size'),
1250
+ 'high': undefined,
1251
+ 'low': undefined,
1252
+ 'open': undefined,
1253
+ 'close': undefined,
1254
+ 'last': undefined,
1255
+ 'change': undefined,
1256
+ 'percentage': undefined,
1257
+ 'average': undefined,
1258
+ 'vwap': undefined,
1259
+ 'baseVolume': undefined,
1260
+ 'quoteVolume': undefined,
1261
+ 'previousClose': undefined,
1262
+ });
1263
+ }
1264
+ async fetchBalance(params = {}) {
1265
+ /**
1266
+ * @method
1267
+ * @name coinbaseinternational#fetchBalance
1268
+ * @description query for balance and get the amount of funds available for trading or funds locked in orders
1269
+ * @see https://docs.cloud.coinbase.com/intx/reference/getportfoliobalances
1270
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1271
+ * @param {boolean} [params.v3] default false, set true to use v3 api endpoint
1272
+ * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
1273
+ */
1274
+ await this.loadMarkets();
1275
+ let portfolio = undefined;
1276
+ [portfolio, params] = await this.handlePortfolioAndParams('fetchBalance', params);
1277
+ const request = {
1278
+ 'portfolio': portfolio,
1279
+ };
1280
+ const balances = await this.v1PrivateGetPortfoliosPortfolioBalances(this.extend(request, params));
1281
+ //
1282
+ // [
1283
+ // {
1284
+ // "asset_id":"0-0-1",
1285
+ // "asset_name":"USDC",
1286
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1287
+ // "quantity":"500000.0000000000",
1288
+ // "hold":"0",
1289
+ // "hold_available_for_collateral":"0",
1290
+ // "transfer_hold":"0",
1291
+ // "collateral_value":"500000.0",
1292
+ // "max_withdraw_amount":"500000.0000000000",
1293
+ // "loan":"0",
1294
+ // "loan_collateral_requirement":"0.0"
1295
+ // }
1296
+ // ]
1297
+ //
1298
+ return this.parseBalance(balances);
1299
+ }
1300
+ parseBalance(response) {
1301
+ //
1302
+ // {
1303
+ // "asset_id":"0-0-1",
1304
+ // "asset_name":"USDC",
1305
+ // "asset_uuid":"2b92315d-eab7-5bef-84fa-089a131333f5",
1306
+ // "quantity":"500000.0000000000",
1307
+ // "hold":"0",
1308
+ // "hold_available_for_collateral":"0",
1309
+ // "transfer_hold":"0",
1310
+ // "collateral_value":"500000.0",
1311
+ // "max_withdraw_amount":"500000.0000000000",
1312
+ // "loan":"0",
1313
+ // "loan_collateral_requirement":"0.0"
1314
+ // }
1315
+ //
1316
+ const result = {
1317
+ 'info': response,
1318
+ };
1319
+ for (let i = 0; i < response.length; i++) {
1320
+ const rawBalance = response[i];
1321
+ const currencyId = this.safeString(rawBalance, 'asset_name');
1322
+ const code = this.safeCurrencyCode(currencyId);
1323
+ const account = this.account();
1324
+ account['total'] = this.safeString(rawBalance, 'quantity');
1325
+ account['used'] = this.safeString(rawBalance, 'hold');
1326
+ result[code] = account;
1327
+ }
1328
+ return this.safeBalance(result);
1329
+ }
1330
+ async transfer(code, amount, fromAccount, toAccount, params = {}) {
1331
+ /**
1332
+ * @method
1333
+ * @name coinbaseinternational#transfer
1334
+ * @description Transfer an amount of asset from one portfolio to another.
1335
+ * @see https://docs.cloud.coinbase.com/intx/reference/createportfolioassettransfer
1336
+ * @param {string} code unified currency code
1337
+ * @param {float} amount amount to transfer
1338
+ * @param {string} fromAccount account to transfer from
1339
+ * @param {string} toAccount account to transfer to
1340
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1341
+ * @returns {object} a [transfer structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure}
1342
+ */
1343
+ await this.loadMarkets();
1344
+ const currency = this.currency(code);
1345
+ const request = {
1346
+ 'asset': currency['id'],
1347
+ 'ammount': amount,
1348
+ 'from': fromAccount,
1349
+ 'to': toAccount,
1350
+ };
1351
+ const response = await this.v1PrivatePostPortfoliosTransfer(this.extend(request, params));
1352
+ const success = this.safeBool(response, 'success');
1353
+ return {
1354
+ 'info': response,
1355
+ 'id': undefined,
1356
+ 'timestamp': undefined,
1357
+ 'datetime': undefined,
1358
+ 'currency': code,
1359
+ 'amount': amount,
1360
+ 'fromAccount': fromAccount,
1361
+ 'toAccount': toAccount,
1362
+ 'status': success ? 'ok' : 'failed',
1363
+ };
1364
+ }
1365
+ async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
1366
+ /**
1367
+ * @method
1368
+ * @name coinbaseinternational#createOrder
1369
+ * @description create a trade order
1370
+ * @see https://docs.cloud.coinbase.com/intx/reference/createorder
1371
+ * @param {string} symbol unified symbol of the market to create an order in
1372
+ * @param {string} type 'market' or 'limit'
1373
+ * @param {string} side 'buy' or 'sell'
1374
+ * @param {float} amount how much you want to trade in units of the base currency, quote currency for 'market' 'buy' orders
1375
+ * @param {float} [price] the price to fulfill the order, in units of the quote currency, ignored in market orders
1376
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1377
+ * @param {float} [params.stopPrice] price to trigger stop orders
1378
+ * @param {float} [params.triggerPrice] price to trigger stop orders
1379
+ * @param {float} [params.stopLossPrice] price to trigger stop-loss orders
1380
+ * @param {bool} [params.postOnly] true or false
1381
+ * @param {string} [params.tif] 'GTC', 'IOC', 'GTD' default is 'GTC' for limit orders and 'IOC' for market orders
1382
+ * @param {string} [params.expire_time] The expiration time required for orders with the time in force set to GTT. Must not go beyond 30 days of the current time. Uses ISO-8601 format (e.g., 2023-03-16T23:59:53Z)
1383
+ * @param {string} [params.stp_mode] Possible values: [NONE, AGGRESSING, BOTH] Specifies the behavior for self match handling. None disables the functionality, new cancels the newest order, and both cancels both orders.
1384
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1385
+ */
1386
+ await this.loadMarkets();
1387
+ const market = this.market(symbol);
1388
+ let typeId = type.toUpperCase();
1389
+ const stopPrice = this.safeNumberN(params, ['triggerPrice', 'stopPrice', 'stop_price']);
1390
+ const clientOrderIdprefix = this.safeString(this.options, 'brokerId', 'nfqkvdjp');
1391
+ let clientOrderId = clientOrderIdprefix + '-' + this.uuid();
1392
+ clientOrderId = clientOrderId.slice(0, 17);
1393
+ const request = {
1394
+ 'client_order_id': clientOrderId,
1395
+ 'side': side.toUpperCase(),
1396
+ 'instrument': market['id'],
1397
+ 'size': this.amountToPrecision(market['symbol'], amount),
1398
+ };
1399
+ if (stopPrice !== undefined) {
1400
+ if (type === 'limit') {
1401
+ typeId = 'STOP_LIMIT';
1402
+ }
1403
+ else {
1404
+ typeId = 'STOP';
1405
+ }
1406
+ request['stop_price'] = stopPrice;
1407
+ }
1408
+ request['type'] = typeId;
1409
+ if (type === 'limit') {
1410
+ if (price === undefined) {
1411
+ throw new InvalidOrder(this.id + 'createOrder() requires a price parameter for a limit order types');
1412
+ }
1413
+ request['price'] = price;
1414
+ }
1415
+ let portfolio = undefined;
1416
+ [portfolio, params] = await this.handlePortfolioAndParams('createOrder', params);
1417
+ if (portfolio !== undefined) {
1418
+ request['portfolio'] = portfolio;
1419
+ }
1420
+ const postOnly = this.safeBool2(params, 'postOnly', 'post_only');
1421
+ let tif = this.safeString2(params, 'tif', 'timeInForce');
1422
+ // market orders must be IOC
1423
+ if (typeId === 'MARKET') {
1424
+ if (tif !== undefined && tif !== 'IOC') {
1425
+ throw new InvalidOrder(this.id + 'createOrder() market orders must have tif set to "IOC"');
1426
+ }
1427
+ tif = 'IOC';
1428
+ }
1429
+ else {
1430
+ tif = (tif === undefined) ? 'GTC' : tif;
1431
+ }
1432
+ if (postOnly !== undefined) {
1433
+ request['post_only'] = postOnly;
1434
+ }
1435
+ request['tif'] = tif;
1436
+ params = this.omit(params, ['client_order_id', 'user', 'postOnly', 'timeInForce']);
1437
+ const response = await this.v1PrivatePostOrders(this.extend(request, params));
1438
+ //
1439
+ // {
1440
+ // "order_id":"1x96skvg-1-0",
1441
+ // "client_order_id":"ccxt",
1442
+ // "side":"BUY",
1443
+ // "instrument_id":"114jqr89-0-0",
1444
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1445
+ // "symbol":"BTC-PERP",
1446
+ // "portfolio_id":"1wp37qsc-1-0",
1447
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1448
+ // "type":"LIMIT",
1449
+ // "price":"10000",
1450
+ // "size":"0.001",
1451
+ // "tif":"GTC",
1452
+ // "stp_mode":"BOTH",
1453
+ // "event_type":"NEW",
1454
+ // "order_status":"WORKING",
1455
+ // "leaves_qty":"0.001",
1456
+ // "exec_qty":"0",
1457
+ // "avg_price":"0",
1458
+ // "fee":"0"
1459
+ // }
1460
+ //
1461
+ return this.parseOrder(response, market);
1462
+ }
1463
+ parseOrder(order, market = undefined) {
1464
+ //
1465
+ // {
1466
+ // "order_id":"1x96skvg-1-0",
1467
+ // "client_order_id":"ccxt",
1468
+ // "side":"BUY",
1469
+ // "instrument_id":"114jqr89-0-0",
1470
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1471
+ // "symbol":"BTC-PERP",
1472
+ // "portfolio_id":"1wp37qsc-1-0",
1473
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1474
+ // "type":"LIMIT",
1475
+ // "price":"10000",
1476
+ // "size":"0.001",
1477
+ // "tif":"GTC",
1478
+ // "stp_mode":"BOTH",
1479
+ // "event_type":"NEW",
1480
+ // "order_status":"WORKING",
1481
+ // "leaves_qty":"0.001",
1482
+ // "exec_qty":"0",
1483
+ // "avg_price":"0",
1484
+ // "fee":"0"
1485
+ // }
1486
+ //
1487
+ const marketId = this.safeString(order, 'symbol');
1488
+ const feeCost = this.safeNumber(order, 'fee');
1489
+ let fee = undefined;
1490
+ if (feeCost !== undefined) {
1491
+ fee = {
1492
+ 'cost': feeCost,
1493
+ };
1494
+ }
1495
+ const datetime = this.safeString2(order, 'submit_time', 'event_time');
1496
+ return this.safeOrder({
1497
+ 'info': order,
1498
+ 'id': this.safeString(order, 'order_id'),
1499
+ 'clientOrderId': this.safeString(order, 'client_order_id'),
1500
+ 'timestamp': this.parse8601(datetime),
1501
+ 'datetime': datetime,
1502
+ 'lastTradeTimestamp': undefined,
1503
+ 'symbol': this.safeSymbol(marketId, market),
1504
+ 'type': this.parseOrderType(this.safeString(order, 'type')),
1505
+ 'timeInForce': this.safeString(order, 'tif'),
1506
+ 'postOnly': undefined,
1507
+ 'side': this.safeStringLower(order, 'side'),
1508
+ 'price': this.safeString(order, 'price'),
1509
+ 'stopPrice': this.safeString(order, 'stop_price'),
1510
+ 'triggerPrice': this.safeString(order, 'stop_price'),
1511
+ 'amount': this.safeString(order, 'size'),
1512
+ 'filled': this.safeString(order, 'exec_qty'),
1513
+ 'remaining': this.safeString(order, 'leaves_qty'),
1514
+ 'cost': undefined,
1515
+ 'average': this.safeString(order, 'avg_price'),
1516
+ 'status': this.parseOrderStatus(this.safeString(order, 'order_status')),
1517
+ 'fee': fee,
1518
+ 'trades': undefined,
1519
+ }, market);
1520
+ }
1521
+ parseOrderStatus(status) {
1522
+ const statuses = {
1523
+ 'NEW': 'open',
1524
+ 'PARTIAL_FILLED': 'open',
1525
+ 'FILLED': 'closed',
1526
+ 'CANCELED': 'canceled',
1527
+ 'REPLACED': 'canceled',
1528
+ 'PENDING_CANCEL': 'open',
1529
+ 'REJECTED': 'rejected',
1530
+ 'PENDING_NEW': 'open',
1531
+ 'EXPIRED': 'expired',
1532
+ 'PENDING_REPLACE': 'open',
1533
+ };
1534
+ return this.safeString(statuses, status, status);
1535
+ }
1536
+ parseOrderType(type) {
1537
+ if (type === 'UNKNOWN_ORDER_TYPE') {
1538
+ return undefined;
1539
+ }
1540
+ const types = {
1541
+ 'MARKET': 'market',
1542
+ 'LIMIT': 'limit',
1543
+ 'STOP': 'limit',
1544
+ 'STOP_LIMIT': 'limit',
1545
+ };
1546
+ return this.safeString(types, type, type);
1547
+ }
1548
+ async cancelOrder(id, symbol = undefined, params = {}) {
1549
+ /**
1550
+ * @method
1551
+ * @name coinbaseinternational#cancelOrder
1552
+ * @description cancels an open order
1553
+ * @see https://docs.cloud.coinbase.com/intx/reference/cancelorder
1554
+ * @param {string} id order id
1555
+ * @param {string} symbol not used by coinbaseinternational cancelOrder()
1556
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1557
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1558
+ */
1559
+ await this.loadMarkets();
1560
+ let portfolio = undefined;
1561
+ [portfolio, params] = await this.handlePortfolioAndParams('cancelOrder', params);
1562
+ const request = {
1563
+ 'portfolio': portfolio,
1564
+ 'id': id,
1565
+ };
1566
+ let market = undefined;
1567
+ if (symbol !== undefined) {
1568
+ market = this.market(symbol);
1569
+ }
1570
+ const orders = await this.v1PrivateDeleteOrdersId(this.extend(request, params));
1571
+ //
1572
+ // {
1573
+ // "order_id":"1x96skvg-1-0",
1574
+ // "client_order_id":"ccxt",
1575
+ // "side":"BUY",
1576
+ // "instrument_id":"114jqr89-0-0",
1577
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1578
+ // "symbol":"BTC-PERP",
1579
+ // "portfolio_id":"1wp37qsc-1-0",
1580
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1581
+ // "type":"LIMIT",
1582
+ // "price":"10000",
1583
+ // "size":"0.001",
1584
+ // "tif":"GTC",
1585
+ // "stp_mode":"BOTH",
1586
+ // "event_type":"CANCELED",
1587
+ // "order_status":"DONE",
1588
+ // "leaves_qty":"0.001",
1589
+ // "exec_qty":"0",
1590
+ // "avg_price":"0",
1591
+ // "fee":"0"
1592
+ // }
1593
+ //
1594
+ return this.parseOrder(orders, market);
1595
+ }
1596
+ async cancelAllOrders(symbol = undefined, params = {}) {
1597
+ /**
1598
+ * @method
1599
+ * @name coinbaseinternational#cancelAllOrders
1600
+ * @description cancel all open orders
1601
+ * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
1602
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1603
+ * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1604
+ */
1605
+ await this.loadMarkets();
1606
+ let portfolio = undefined;
1607
+ [portfolio, params] = await this.handlePortfolioAndParams('cancelAllOrders', params);
1608
+ const request = {
1609
+ 'portfolio': portfolio,
1610
+ };
1611
+ let market = undefined;
1612
+ if (symbol) {
1613
+ market = this.market(symbol);
1614
+ request['instrument'] = market['id'];
1615
+ }
1616
+ const orders = await this.v1PrivateDeleteOrders(this.extend(request, params));
1617
+ return this.parseOrders(orders, market);
1618
+ }
1619
+ async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
1620
+ /**
1621
+ * @method
1622
+ * @name coinbaseinternational#editOrder
1623
+ * @description edit a trade order
1624
+ * @see https://docs.cloud.coinbase.com/intx/reference/modifyorder
1625
+ * @param {string} id cancel order id
1626
+ * @param {string} symbol unified symbol of the market to create an order in
1627
+ * @param {string} type 'market' or 'limit'
1628
+ * @param {string} side 'buy' or 'sell'
1629
+ * @param {float} amount how much of currency you want to trade in units of base currency
1630
+ * @param {float} [price] the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1631
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1632
+ * @param {string} params.clientOrderId client order id
1633
+ * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1634
+ */
1635
+ await this.loadMarkets();
1636
+ const market = this.market(symbol);
1637
+ const request = {
1638
+ 'id': id,
1639
+ };
1640
+ let portfolio = undefined;
1641
+ [portfolio, params] = await this.handlePortfolioAndParams('editOrder', params);
1642
+ if (portfolio !== undefined) {
1643
+ request['portfolio'] = portfolio;
1644
+ }
1645
+ if (amount !== undefined) {
1646
+ request['size'] = this.amountToPrecision(symbol, amount);
1647
+ }
1648
+ if (price !== undefined) {
1649
+ request['price'] = this.priceToPrecision(symbol, price);
1650
+ }
1651
+ const stopPrice = this.safeNumberN(params, ['stopPrice', 'stop_price', 'triggerPrice']);
1652
+ if (stopPrice !== undefined) {
1653
+ request['stop_price'] = stopPrice;
1654
+ }
1655
+ const clientOrderId = this.safeString2(params, 'client_order_id', 'clientOrderId');
1656
+ if (clientOrderId === undefined) {
1657
+ throw new BadRequest(this.id + ' editOrder() requires a clientOrderId parameter');
1658
+ }
1659
+ request['client_order_id'] = clientOrderId;
1660
+ const order = await this.v1PrivatePutOrdersId(this.extend(request, params));
1661
+ return this.parseOrder(order, market);
1662
+ }
1663
+ async fetchOrder(id, symbol = undefined, params = {}) {
1664
+ /**
1665
+ * @method
1666
+ * @name coinbaseinternational#fetchOrder
1667
+ * @description fetches information on an order made by the user
1668
+ * @see https://docs.cloud.coinbase.com/intx/reference/modifyorder
1669
+ * @param {string} id the order id
1670
+ * @param {string} symbol unified market symbol that the order was made in
1671
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1672
+ * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
1673
+ */
1674
+ await this.loadMarkets();
1675
+ let market = undefined;
1676
+ if (symbol !== undefined) {
1677
+ market = this.market(symbol);
1678
+ }
1679
+ let portfolio = undefined;
1680
+ [portfolio, params] = await this.handlePortfolioAndParams('fetchOrder', params);
1681
+ const request = {
1682
+ 'id': id,
1683
+ 'portfolio': portfolio,
1684
+ };
1685
+ const order = await this.v1PrivateGetOrdersId(this.extend(request, params));
1686
+ //
1687
+ // {
1688
+ // "order_id":"1x96skvg-1-0",
1689
+ // "client_order_id":"ccxt",
1690
+ // "side":"BUY",
1691
+ // "instrument_id":"114jqr89-0-0",
1692
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1693
+ // "symbol":"BTC-PERP",
1694
+ // "portfolio_id":"1wp37qsc-1-0",
1695
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1696
+ // "type":"LIMIT",
1697
+ // "price":"10000",
1698
+ // "size":"0.001",
1699
+ // "tif":"GTC",
1700
+ // "stp_mode":"BOTH",
1701
+ // "event_type":"NEW",
1702
+ // "event_time":"2024-02-14T03:25:14Z",
1703
+ // "submit_time":"2024-02-14T03:25:13.999Z",
1704
+ // "order_status":"WORKING",
1705
+ // "leaves_qty":"0.001",
1706
+ // "exec_qty":"0",
1707
+ // "avg_price":"0",
1708
+ // "fee":"0"
1709
+ // }
1710
+ //
1711
+ return this.parseOrder(order, market);
1712
+ }
1713
+ async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1714
+ /**
1715
+ * @method
1716
+ * @name coinbaseinternational#fetchOpenOrders
1717
+ * @description fetches information on all currently open orders
1718
+ * @see https://docs.cloud.coinbase.com/intx/reference/getorders
1719
+ * @param {string} symbol unified market symbol of the orders
1720
+ * @param {int} [since] timestamp in ms of the earliest order, default is undefined
1721
+ * @param {int} [limit] the maximum number of open order structures to retrieve
1722
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1723
+ * @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)
1724
+ * @param {int} [params.offset] offset
1725
+ * @param {string} [params.event_type] The most recent type of event that happened to the order. Allowed values: NEW, TRADE, REPLACED
1726
+ * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
1727
+ */
1728
+ await this.loadMarkets();
1729
+ let portfolio = undefined;
1730
+ [portfolio, params] = await this.handlePortfolioAndParams('fetchOpenOrders', params);
1731
+ let paginate = false;
1732
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'paginate');
1733
+ let maxEntriesPerRequest = undefined;
1734
+ [maxEntriesPerRequest, params] = this.handleOptionAndParams(params, 'fetchOpenOrders', 'maxEntriesPerRequest', 100);
1735
+ const pageKey = 'ccxtPageKey';
1736
+ if (paginate) {
1737
+ return await this.fetchPaginatedCallIncremental('fetchOpenOrders', symbol, since, limit, params, pageKey, maxEntriesPerRequest);
1738
+ }
1739
+ const page = this.safeInteger(params, pageKey, 1) - 1;
1740
+ const request = {
1741
+ 'portfolio': portfolio,
1742
+ 'result_offset': this.safeInteger2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
1743
+ };
1744
+ let market = undefined;
1745
+ if (symbol) {
1746
+ market = this.market(symbol);
1747
+ request['instrument'] = symbol;
1748
+ }
1749
+ if (limit !== undefined) {
1750
+ if (limit > 100) {
1751
+ throw new BadRequest(this.id + ' fetchOpenOrders() maximum limit is 100');
1752
+ }
1753
+ request['result_limit'] = limit;
1754
+ }
1755
+ if (since !== undefined) {
1756
+ request['ref_datetime'] = this.iso8601(since);
1757
+ }
1758
+ const response = await this.v1PrivateGetOrders(this.extend(request, params));
1759
+ //
1760
+ // {
1761
+ // "pagination":{
1762
+ // "result_limit":25,
1763
+ // "result_offset":0
1764
+ // },
1765
+ // "results":[
1766
+ // {
1767
+ // "order_id":"1y4cm6b4-1-0",
1768
+ // "client_order_id":"ccxtd0dd4b5d-8e5f-",
1769
+ // "side":"SELL",
1770
+ // "instrument_id":"114jqr89-0-0",
1771
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1772
+ // "symbol":"BTC-PERP",
1773
+ // "portfolio_id":"1wp37qsc-1-0",
1774
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1775
+ // "type":"LIMIT",
1776
+ // "price":"54000",
1777
+ // "size":"0.01",
1778
+ // "tif":"GTC",
1779
+ // "stp_mode":"BOTH",
1780
+ // "event_type":"NEW",
1781
+ // "event_time":"2024-02-24T16:46:37.413Z",
1782
+ // "submit_time":"2024-02-24T16:46:37.412Z",
1783
+ // "order_status":"WORKING",
1784
+ // "leaves_qty":"0.01",
1785
+ // "exec_qty":"0",
1786
+ // "avg_price":"0",
1787
+ // "fee":"0"
1788
+ // },
1789
+ // ...
1790
+ // ]
1791
+ // }
1792
+ //
1793
+ const rawOrders = this.safeList(response, 'results', []);
1794
+ return this.parseOrders(rawOrders, market, since, limit);
1795
+ }
1796
+ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
1797
+ /**
1798
+ * @method
1799
+ * @name coinbaseinternational#fetchMyTrades
1800
+ * @description fetch all trades made by the user
1801
+ * @see https://docs.cloud.coinbase.com/intx/reference/getmultiportfoliofills
1802
+ * @param {string} symbol unified market symbol of the trades
1803
+ * @param {int} [since] timestamp in ms of the earliest order, default is undefined
1804
+ * @param {int} [limit] the maximum number of trade structures to fetch
1805
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1806
+ * @param {int} [params.until] the latest time in ms to fetch trades for
1807
+ * @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)
1808
+ * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
1809
+ */
1810
+ await this.loadMarkets();
1811
+ let paginate = false;
1812
+ [paginate, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'paginate');
1813
+ const pageKey = 'ccxtPageKey';
1814
+ let maxEntriesPerRequest = undefined;
1815
+ [maxEntriesPerRequest, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'maxEntriesPerRequest', 100);
1816
+ if (paginate) {
1817
+ return await this.fetchPaginatedCallIncremental('fetchMyTrades', symbol, since, limit, params, pageKey, maxEntriesPerRequest);
1818
+ }
1819
+ let market = undefined;
1820
+ if (symbol !== undefined) {
1821
+ market = this.market(symbol);
1822
+ }
1823
+ const page = this.safeInteger(params, pageKey, 1) - 1;
1824
+ const request = {
1825
+ 'result_offset': this.safeInteger2(params, 'offset', 'result_offset', page * maxEntriesPerRequest),
1826
+ };
1827
+ if (limit !== undefined) {
1828
+ if (limit > 100) {
1829
+ throw new BadRequest(this.id + ' fetchMyTrades() maximum limit is 100. Consider setting paginate to true to fetch more trades.');
1830
+ }
1831
+ request['result_limit'] = limit;
1832
+ }
1833
+ if (since !== undefined) {
1834
+ request['time_from'] = this.iso8601(since);
1835
+ }
1836
+ const until = this.safeStringN(params, ['until', 'till']);
1837
+ if (until !== undefined) {
1838
+ params = this.omit(params, ['until', 'till']);
1839
+ request['ref_datetime'] = this.iso8601(until);
1840
+ }
1841
+ const response = await this.v1PrivateGetPortfoliosFills(this.extend(request, params));
1842
+ //
1843
+ // {
1844
+ // "pagination":{
1845
+ // "result_limit":25,
1846
+ // "result_offset":0
1847
+ // },
1848
+ // "results":[
1849
+ // {
1850
+ // "portfolio_id":"1wp37qsc-1-0",
1851
+ // "portfolio_uuid":"018d7f6c-b92c-7361-8b7e-2932711e5a22",
1852
+ // "portfolio_name":"CCXT Portfolio 020624-17:16",
1853
+ // "fill_id":"1xbfy19y-1-184",
1854
+ // "exec_id":"280841526207070392",
1855
+ // "order_id":"1xbfv8yw-1-0",
1856
+ // "instrument_id":"114jqr89-0-0",
1857
+ // "instrument_uuid":"b3469e0b-222c-4f8a-9f68-1f9e44d7e5e0",
1858
+ // "symbol":"BTC-PERP",
1859
+ // "match_id":"280841526207053840",
1860
+ // "fill_price":"52500",
1861
+ // "fill_qty":"0.01",
1862
+ // "client_id":"1x59ctku-1-1",
1863
+ // "client_order_id":"ccxt3e4e2a5f-4a89-",
1864
+ // "order_qty":"0.01",
1865
+ // "limit_price":"52500",
1866
+ // "total_filled":"0.01",
1867
+ // "filled_vwap":"52500",
1868
+ // "expire_time":"",
1869
+ // "stop_price":"",
1870
+ // "side":"BUY",
1871
+ // "tif":"GTC",
1872
+ // "stp_mode":"BOTH",
1873
+ // "flags":"",
1874
+ // "fee":"0.105",
1875
+ // "fee_asset":"USDC",
1876
+ // "order_status":"DONE",
1877
+ // "event_time":"2024-02-15T00:43:57.631Z"
1878
+ // },
1879
+ // ]
1880
+ // }
1881
+ //
1882
+ const trades = this.safeList(response, 'results', []);
1883
+ return this.parseTrades(trades, market, since, limit);
1884
+ }
1885
+ async withdraw(code, amount, address, tag = undefined, params = {}) {
1886
+ /**
1887
+ * @method
1888
+ * @name coinbaseinternational#withdraw
1889
+ * @description make a withdrawal
1890
+ * @see https://docs.cloud.coinbase.com/intx/reference/withdraw
1891
+ * @see https://docs.cloud.coinbase.com/intx/reference/counterpartywithdraw
1892
+ * @param {string} code unified currency code
1893
+ * @param {float} amount the amount to withdraw
1894
+ * @param {string} address the address to withdraw to
1895
+ * @param {string} [tag] an optional tag for the withdrawal
1896
+ * @param {object} [params] extra parameters specific to the exchange API endpoint
1897
+ * @param {boolean} [params.add_network_fee_to_total] if true, deducts network fee from the portfolio, otherwise deduct fee from the withdrawal
1898
+ * @param {string} [params.network_arn_id] Identifies the blockchain network (e.g., networks/ethereum-mainnet/assets/313ef8a9-ae5a-5f2f-8a56-572c0e2a4d5a)
1899
+ * @param {string} [params.nonce] a unique integer representing the withdrawal request
1900
+ * @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
1901
+ */
1902
+ [tag, params] = this.handleWithdrawTagAndParams(tag, params);
1903
+ this.checkAddress(address);
1904
+ await this.loadMarkets();
1905
+ const currency = this.currency(code);
1906
+ let portfolio = undefined;
1907
+ [portfolio, params] = await this.handlePortfolioAndParams('withdraw', params);
1908
+ let method = undefined;
1909
+ [method, params] = this.handleOptionAndParams(params, 'withdraw', 'method', 'v1PrivatePostTransfersWithdraw');
1910
+ let networkId = undefined;
1911
+ [networkId, params] = await this.handleNetworkIdAndParams(code, 'withdraw', params);
1912
+ const request = {
1913
+ 'portfolio': portfolio,
1914
+ 'type': 'send',
1915
+ 'asset': currency['id'],
1916
+ 'address': address,
1917
+ 'amount': amount,
1918
+ 'currency': currency['id'],
1919
+ 'network_arn_id': networkId,
1920
+ 'nonce': this.nonce(),
1921
+ };
1922
+ const response = await this[method](this.extend(request, params));
1923
+ //
1924
+ // {
1925
+ // "idem":"8e471d77-4208-45a8-9e5b-f3bd8a2c1fc3"
1926
+ // }
1927
+ //
1928
+ return this.parseTransaction(response, currency);
1929
+ }
1930
+ safeNetwork(network) {
1931
+ let withdrawEnabled = this.safeBool(network, 'withdraw');
1932
+ let depositEnabled = this.safeBool(network, 'deposit');
1933
+ const limits = this.safeDict(network, 'limits');
1934
+ const withdraw = this.safeDict(limits, 'withdraw');
1935
+ const withdrawMax = this.safeNumber(withdraw, 'max');
1936
+ const deposit = this.safeDict(limits, 'deposit');
1937
+ const depositMax = this.safeNumber(deposit, 'max');
1938
+ if (withdrawEnabled === undefined && withdrawMax !== undefined) {
1939
+ withdrawEnabled = (withdrawMax > 0);
1940
+ }
1941
+ if (depositEnabled === undefined && depositMax !== undefined) {
1942
+ depositEnabled = (depositMax > 0);
1943
+ }
1944
+ const networkId = this.safeString(network, 'id');
1945
+ const isEnabled = (withdrawEnabled && depositEnabled);
1946
+ return {
1947
+ 'info': network['info'],
1948
+ 'id': networkId,
1949
+ 'name': this.safeString(network, 'name'),
1950
+ 'network': this.safeString(network, 'network'),
1951
+ 'active': this.safeBool(network, 'active', isEnabled),
1952
+ 'deposit': depositEnabled,
1953
+ 'withdraw': withdrawEnabled,
1954
+ 'fee': this.safeNumber(network, 'fee'),
1955
+ 'precision': this.safeNumber(network, 'precision'),
1956
+ 'limits': {
1957
+ 'withdraw': {
1958
+ 'min': this.safeNumber(withdraw, 'min'),
1959
+ 'max': withdrawMax,
1960
+ },
1961
+ 'deposit': {
1962
+ 'min': this.safeNumber(deposit, 'min'),
1963
+ 'max': depositMax,
1964
+ },
1965
+ },
1966
+ };
1967
+ }
1968
+ sign(path, api = [], method = 'GET', params = {}, headers = undefined, body = undefined) {
1969
+ const version = api[0];
1970
+ const signed = api[1] === 'private';
1971
+ let fullPath = '/' + version + '/' + this.implodeParams(path, params);
1972
+ const query = this.omit(params, this.extractParams(path));
1973
+ const savedPath = '/api' + fullPath;
1974
+ if (method === 'GET' || method === 'DELETE') {
1975
+ if (Object.keys(query).length) {
1976
+ fullPath += '?' + this.urlencodeWithArrayRepeat(query);
1977
+ }
1978
+ }
1979
+ const url = this.urls['api']['rest'] + fullPath;
1980
+ if (signed) {
1981
+ this.checkRequiredCredentials();
1982
+ const nonce = this.nonce().toString();
1983
+ let payload = '';
1984
+ if (method !== 'GET') {
1985
+ if (Object.keys(query).length) {
1986
+ body = this.json(query);
1987
+ payload = body;
1988
+ }
1989
+ }
1990
+ const auth = nonce + method + savedPath + payload;
1991
+ const signature = this.hmac(this.encode(auth), this.base64ToBinary(this.secret), sha256, 'base64');
1992
+ headers = {
1993
+ 'CB-ACCESS-TIMESTAMP': nonce,
1994
+ 'CB-ACCESS-SIGN': signature,
1995
+ 'CB-ACCESS-PASSPHRASE': this.password,
1996
+ 'CB-ACCESS-KEY': this.apiKey,
1997
+ };
1998
+ }
1999
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
2000
+ }
2001
+ handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
2002
+ //
2003
+ // {
2004
+ // "title":"io.javalin.http.BadRequestResponse: Order rejected (DUPLICATE_CLIENT_ORDER_ID - duplicate client order id detected)",
2005
+ // "status":400
2006
+ // }
2007
+ //
2008
+ if (response === undefined) {
2009
+ return undefined; // fallback to default error handler
2010
+ }
2011
+ const feedback = this.id + ' ' + body;
2012
+ const errMsg = this.safeString(response, 'title');
2013
+ if (errMsg !== undefined) {
2014
+ this.throwExactlyMatchedException(this.exceptions['exact'], errMsg, feedback);
2015
+ this.throwBroadlyMatchedException(this.exceptions['broad'], errMsg, feedback);
2016
+ throw new ExchangeError(feedback);
2017
+ }
2018
+ return undefined;
2019
+ }
2020
+ }