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