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