ccxt-look 1.81.50
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/.cache/eslintcache +1 -0
- package/.dockerignore +6 -0
- package/.eslintignore +1 -0
- package/.gitattributes +5 -0
- package/.readthedocs.yaml +16 -0
- package/CONTRIBUTING.md +1049 -0
- package/LICENSE.txt +21 -0
- package/README.md +537 -0
- package/SECURITY.md +5 -0
- package/build/cleanup-old-tags.js +94 -0
- package/build/countries.js +256 -0
- package/build/export-exchanges.js +520 -0
- package/build/fs.js +51 -0
- package/build/transpile.js +1772 -0
- package/build/vss.js +78 -0
- package/ccxt.browser.js +7 -0
- package/ccxt.d.ts +692 -0
- package/ccxt.js +171 -0
- package/cleanup.sh +2 -0
- package/composer-install.sh +20 -0
- package/dist/ccxt.browser.js +208383 -0
- package/gource.sh +3 -0
- package/index.html +7 -0
- package/js/.eslintrc +87 -0
- package/js/aax.js +2686 -0
- package/js/ascendex.js +2584 -0
- package/js/base/.eslintrc.js +43 -0
- package/js/base/Exchange.js +2371 -0
- package/js/base/Precise.js +283 -0
- package/js/base/errorHierarchy.js +47 -0
- package/js/base/errors.js +55 -0
- package/js/base/functions/crypto.js +158 -0
- package/js/base/functions/encode.js +118 -0
- package/js/base/functions/generic.js +270 -0
- package/js/base/functions/misc.js +138 -0
- package/js/base/functions/number.js +329 -0
- package/js/base/functions/platform.js +38 -0
- package/js/base/functions/string.js +21 -0
- package/js/base/functions/throttle.js +79 -0
- package/js/base/functions/time.js +210 -0
- package/js/base/functions/type.js +66 -0
- package/js/base/functions.js +28 -0
- package/js/bequant.js +32 -0
- package/js/bibox.js +1407 -0
- package/js/bigone.js +1366 -0
- package/js/binance.js +5652 -0
- package/js/binancecoinm.js +46 -0
- package/js/binanceus.js +46 -0
- package/js/binanceusdm.js +49 -0
- package/js/bit2c.js +535 -0
- package/js/bitbank.js +842 -0
- package/js/bitbay.js +16 -0
- package/js/bitbns.js +1073 -0
- package/js/bitcoincom.js +15 -0
- package/js/bitfinex.js +1433 -0
- package/js/bitfinex2.js +2025 -0
- package/js/bitflyer.js +840 -0
- package/js/bitforex.js +614 -0
- package/js/bitget.js +2397 -0
- package/js/bithumb.js +980 -0
- package/js/bitmart.js +2516 -0
- package/js/bitmex.js +1809 -0
- package/js/bitopro.js +1443 -0
- package/js/bitpanda.js +1782 -0
- package/js/bitrue.js +1747 -0
- package/js/bitso.js +1062 -0
- package/js/bitstamp.js +1757 -0
- package/js/bitstamp1.js +343 -0
- package/js/bittrex.js +1876 -0
- package/js/bitvavo.js +1579 -0
- package/js/bkex.js +1233 -0
- package/js/bl3p.js +346 -0
- package/js/blockchaincom.js +969 -0
- package/js/btcalpha.js +680 -0
- package/js/btcbox.js +477 -0
- package/js/btcmarkets.js +1022 -0
- package/js/btctradeua.js +466 -0
- package/js/btcturk.js +734 -0
- package/js/buda.js +946 -0
- package/js/bw.js +1265 -0
- package/js/bybit.js +3372 -0
- package/js/bytetrade.js +1336 -0
- package/js/cdax.js +1646 -0
- package/js/cex.js +1410 -0
- package/js/coinbase.js +1342 -0
- package/js/coinbaseprime.js +31 -0
- package/js/coinbasepro.js +1466 -0
- package/js/coincheck.js +755 -0
- package/js/coinex.js +3400 -0
- package/js/coinfalcon.js +880 -0
- package/js/coinmate.js +794 -0
- package/js/coinone.js +816 -0
- package/js/coinspot.js +345 -0
- package/js/crex24.js +1636 -0
- package/js/cryptocom.js +1832 -0
- package/js/currencycom.js +1748 -0
- package/js/delta.js +1547 -0
- package/js/deribit.js +2148 -0
- package/js/digifinex.js +1585 -0
- package/js/eqonex.js +1660 -0
- package/js/exmo.js +1670 -0
- package/js/fairdesk.js +1231 -0
- package/js/flowbtc.js +35 -0
- package/js/fmfwio.js +34 -0
- package/js/ftx.js +2751 -0
- package/js/ftxus.js +38 -0
- package/js/gateio.js +4174 -0
- package/js/gemini.js +1397 -0
- package/js/hitbtc.js +1343 -0
- package/js/hitbtc3.js +2329 -0
- package/js/hollaex.js +1486 -0
- package/js/huobi.js +5706 -0
- package/js/huobijp.js +1710 -0
- package/js/huobipro.js +18 -0
- package/js/idex.js +1439 -0
- package/js/independentreserve.js +649 -0
- package/js/indodax.js +742 -0
- package/js/itbit.js +722 -0
- package/js/kraken.js +2179 -0
- package/js/kucoin.js +2571 -0
- package/js/kucoinfutures.js +1771 -0
- package/js/kuna.js +809 -0
- package/js/latoken.js +1445 -0
- package/js/lbank.js +760 -0
- package/js/liquid.js +1432 -0
- package/js/luno.js +873 -0
- package/js/lykke.js +1147 -0
- package/js/mercado.js +771 -0
- package/js/mexc.js +3151 -0
- package/js/ndax.js +2233 -0
- package/js/novadax.js +1318 -0
- package/js/oceanex.js +816 -0
- package/js/okcoin.js +3841 -0
- package/js/okex.js +16 -0
- package/js/okex5.js +16 -0
- package/js/okx.js +4795 -0
- package/js/paymium.js +498 -0
- package/js/phemex.js +2957 -0
- package/js/poloniex.js +1674 -0
- package/js/probit.js +1346 -0
- package/js/qtrade.js +1588 -0
- package/js/ripio.js +1061 -0
- package/js/static_dependencies/BN/bn.js +3526 -0
- package/js/static_dependencies/README.md +1 -0
- package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
- package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
- package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
- package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
- package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
- package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
- package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
- package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
- package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
- package/js/static_dependencies/node-fetch/index.js +1564 -0
- package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
- package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
- package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
- package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
- package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
- package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
- package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
- package/js/static_dependencies/node-rsa/formats/components.js +71 -0
- package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
- package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
- package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
- package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
- package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
- package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
- package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
- package/js/static_dependencies/node-rsa/utils.js +98 -0
- package/js/static_dependencies/qs/formats.js +18 -0
- package/js/static_dependencies/qs/index.js +11 -0
- package/js/static_dependencies/qs/parse.js +242 -0
- package/js/static_dependencies/qs/stringify.js +269 -0
- package/js/static_dependencies/qs/utils.js +230 -0
- package/js/stex.js +1925 -0
- package/js/test/.eslintrc.js +42 -0
- package/js/test/Exchange/test.balance.js +61 -0
- package/js/test/Exchange/test.borrowRate.js +32 -0
- package/js/test/Exchange/test.currency.js +52 -0
- package/js/test/Exchange/test.fetchBalance.js +23 -0
- package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
- package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
- package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
- package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
- package/js/test/Exchange/test.fetchCurrencies.js +35 -0
- package/js/test/Exchange/test.fetchDeposits.js +31 -0
- package/js/test/Exchange/test.fetchFundingFees.js +19 -0
- package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
- package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
- package/js/test/Exchange/test.fetchLedger.js +42 -0
- package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
- package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
- package/js/test/Exchange/test.fetchMarkets.js +33 -0
- package/js/test/Exchange/test.fetchMyTrades.js +42 -0
- package/js/test/Exchange/test.fetchOHLCV.js +46 -0
- package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
- package/js/test/Exchange/test.fetchOrderBook.js +25 -0
- package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
- package/js/test/Exchange/test.fetchOrders.js +41 -0
- package/js/test/Exchange/test.fetchPositions.js +47 -0
- package/js/test/Exchange/test.fetchStatus.js +35 -0
- package/js/test/Exchange/test.fetchTicker.js +38 -0
- package/js/test/Exchange/test.fetchTickers.js +49 -0
- package/js/test/Exchange/test.fetchTrades.js +39 -0
- package/js/test/Exchange/test.fetchTradingFee.js +18 -0
- package/js/test/Exchange/test.fetchTradingFees.js +22 -0
- package/js/test/Exchange/test.fetchTransactions.js +31 -0
- package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
- package/js/test/Exchange/test.ledgerItem.js +46 -0
- package/js/test/Exchange/test.leverageTier.js +33 -0
- package/js/test/Exchange/test.loadMarkets.js +35 -0
- package/js/test/Exchange/test.market.js +129 -0
- package/js/test/Exchange/test.ohlcv.js +33 -0
- package/js/test/Exchange/test.order.js +62 -0
- package/js/test/Exchange/test.orderbook.js +61 -0
- package/js/test/Exchange/test.position.js +21 -0
- package/js/test/Exchange/test.throttle.js +94 -0
- package/js/test/Exchange/test.ticker.js +95 -0
- package/js/test/Exchange/test.trade.js +68 -0
- package/js/test/Exchange/test.tradingFee.js +34 -0
- package/js/test/Exchange/test.transaction.js +35 -0
- package/js/test/base/.eslintrc +38 -0
- package/js/test/base/functions/test.crypto.js +110 -0
- package/js/test/base/functions/test.datetime.js +62 -0
- package/js/test/base/functions/test.generic.js +152 -0
- package/js/test/base/functions/test.number.js +362 -0
- package/js/test/base/functions/test.time.js +56 -0
- package/js/test/base/functions/test.type.js +53 -0
- package/js/test/base/test.base.js +193 -0
- package/js/test/errors/test.InsufficientFunds.js +86 -0
- package/js/test/errors/test.InvalidNonce.js +64 -0
- package/js/test/errors/test.InvalidOrder.js +35 -0
- package/js/test/errors/test.OrderNotFound.js +39 -0
- package/js/test/test.js +426 -0
- package/js/test/test.timeout_hang.js +12 -0
- package/js/therock.js +1431 -0
- package/js/tidebit.js +632 -0
- package/js/tidex.js +939 -0
- package/js/timex.js +1283 -0
- package/js/upbit.js +1622 -0
- package/js/vcc.js +1353 -0
- package/js/wavesexchange.js +2185 -0
- package/js/wazirx.js +732 -0
- package/js/whitebit.js +1352 -0
- package/js/woo.js +1577 -0
- package/js/xena.js +1948 -0
- package/js/yobit.js +1129 -0
- package/js/zaif.js +647 -0
- package/js/zb.js +4088 -0
- package/js/zipmex.js +40 -0
- package/js/zonda.js +1497 -0
- package/multilang.sh +159 -0
- package/package.json +591 -0
- package/postinstall.js +103 -0
package/js/whitebit.js
ADDED
@@ -0,0 +1,1352 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { ExchangeNotAvailable, ExchangeError, DDoSProtection, BadSymbol, InvalidOrder, ArgumentsRequired, AuthenticationError, OrderNotFound, PermissionDenied, InsufficientFunds, BadRequest } = require ('./base/errors');
|
7
|
+
const Precise = require ('./base/Precise');
|
8
|
+
|
9
|
+
// ---------------------------------------------------------------------------
|
10
|
+
|
11
|
+
module.exports = class whitebit extends Exchange {
|
12
|
+
describe () {
|
13
|
+
return this.deepExtend (super.describe (), {
|
14
|
+
'id': 'whitebit',
|
15
|
+
'name': 'WhiteBit',
|
16
|
+
'version': 'v2',
|
17
|
+
'countries': [ 'EE' ],
|
18
|
+
'rateLimit': 500,
|
19
|
+
'has': {
|
20
|
+
'CORS': undefined,
|
21
|
+
'spot': true,
|
22
|
+
'margin': undefined, // has but unimplemented
|
23
|
+
'swap': false,
|
24
|
+
'future': false,
|
25
|
+
'option': false,
|
26
|
+
'cancelOrder': true,
|
27
|
+
'createDepositAddress': undefined,
|
28
|
+
'createLimitOrder': undefined,
|
29
|
+
'createMarketOrder': undefined,
|
30
|
+
'createOrder': true,
|
31
|
+
'createStopLimitOrder': true,
|
32
|
+
'createStopMarketOrder': true,
|
33
|
+
'createStopOrder': true,
|
34
|
+
'editOrder': undefined,
|
35
|
+
'fetchBalance': true,
|
36
|
+
'fetchBidsAsks': undefined,
|
37
|
+
'fetchClosedOrders': true,
|
38
|
+
'fetchCurrencies': true,
|
39
|
+
'fetchDepositAddress': true,
|
40
|
+
'fetchFundingFees': true,
|
41
|
+
'fetchFundingHistory': false,
|
42
|
+
'fetchFundingRate': false,
|
43
|
+
'fetchFundingRateHistory': false,
|
44
|
+
'fetchFundingRates': false,
|
45
|
+
'fetchIndexOHLCV': false,
|
46
|
+
'fetchMarkets': true,
|
47
|
+
'fetchMarkOHLCV': false,
|
48
|
+
'fetchOHLCV': true,
|
49
|
+
'fetchOpenOrders': true,
|
50
|
+
'fetchOrderBook': true,
|
51
|
+
'fetchOrderTrades': true,
|
52
|
+
'fetchPremiumIndexOHLCV': false,
|
53
|
+
'fetchTicker': true,
|
54
|
+
'fetchTickers': true,
|
55
|
+
'fetchTime': true,
|
56
|
+
'fetchTrades': true,
|
57
|
+
'fetchTradingFee': false,
|
58
|
+
'fetchTradingFees': true,
|
59
|
+
'transfer': true,
|
60
|
+
'withdraw': true,
|
61
|
+
},
|
62
|
+
'timeframes': {
|
63
|
+
'1m': '1m',
|
64
|
+
'3m': '3m',
|
65
|
+
'5m': '5m',
|
66
|
+
'15m': '15m',
|
67
|
+
'30m': '30m',
|
68
|
+
'1h': '1h',
|
69
|
+
'2h': '2h',
|
70
|
+
'4h': '4h',
|
71
|
+
'6h': '6h',
|
72
|
+
'8h': '8h',
|
73
|
+
'12h': '12h',
|
74
|
+
'1d': '1d',
|
75
|
+
'3d': '3d',
|
76
|
+
'1w': '1w',
|
77
|
+
'1M': '1M',
|
78
|
+
},
|
79
|
+
'urls': {
|
80
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/66732963-8eb7dd00-ee66-11e9-849b-10d9282bb9e0.jpg',
|
81
|
+
'api': {
|
82
|
+
'v1': {
|
83
|
+
'public': 'https://whitebit.com/api/v1/public',
|
84
|
+
'private': 'https://whitebit.com/api/v1',
|
85
|
+
},
|
86
|
+
'v2': {
|
87
|
+
'public': 'https://whitebit.com/api/v2/public',
|
88
|
+
},
|
89
|
+
'v4': {
|
90
|
+
'public': 'https://whitebit.com/api/v4/public',
|
91
|
+
'private': 'https://whitebit.com/api/v4',
|
92
|
+
},
|
93
|
+
},
|
94
|
+
'www': 'https://www.whitebit.com',
|
95
|
+
'doc': 'https://github.com/whitebit-exchange/api-docs',
|
96
|
+
'fees': 'https://whitebit.com/fee-schedule',
|
97
|
+
'referral': 'https://whitebit.com/referral/d9bdf40e-28f2-4b52-b2f9-cd1415d82963',
|
98
|
+
},
|
99
|
+
'api': {
|
100
|
+
'web': {
|
101
|
+
'get': [
|
102
|
+
'v1/healthcheck',
|
103
|
+
],
|
104
|
+
},
|
105
|
+
'v1': {
|
106
|
+
'public': {
|
107
|
+
'get': [
|
108
|
+
'markets',
|
109
|
+
'tickers',
|
110
|
+
'ticker',
|
111
|
+
'symbols',
|
112
|
+
'depth/result',
|
113
|
+
'history',
|
114
|
+
'kline',
|
115
|
+
],
|
116
|
+
},
|
117
|
+
'private': {
|
118
|
+
'post': [
|
119
|
+
'account/balance',
|
120
|
+
'order/new',
|
121
|
+
'order/cancel',
|
122
|
+
'orders',
|
123
|
+
'account/order_history',
|
124
|
+
'account/executed_history',
|
125
|
+
'account/executed_history/all',
|
126
|
+
'account/order',
|
127
|
+
],
|
128
|
+
},
|
129
|
+
},
|
130
|
+
'v2': {
|
131
|
+
'public': {
|
132
|
+
'get': [
|
133
|
+
'markets',
|
134
|
+
'ticker',
|
135
|
+
'assets',
|
136
|
+
'fee',
|
137
|
+
'depth/{market}',
|
138
|
+
'trades/{market}',
|
139
|
+
],
|
140
|
+
},
|
141
|
+
},
|
142
|
+
'v4': {
|
143
|
+
'public': {
|
144
|
+
'get': [
|
145
|
+
'assets',
|
146
|
+
'fee',
|
147
|
+
'orderbook/{market}',
|
148
|
+
'ticker',
|
149
|
+
'trades/{market}',
|
150
|
+
'time',
|
151
|
+
'ping',
|
152
|
+
],
|
153
|
+
},
|
154
|
+
'private': {
|
155
|
+
'post': [
|
156
|
+
'main-account/address',
|
157
|
+
'main-account/balance',
|
158
|
+
'main-account/create-new-address',
|
159
|
+
'main-account/codes',
|
160
|
+
'main-account/codes/apply',
|
161
|
+
'main-account/codes/my',
|
162
|
+
'main-account/codes/history',
|
163
|
+
'main-account/fiat-deposit-url',
|
164
|
+
'main-account/history',
|
165
|
+
'main-account/withdraw',
|
166
|
+
'main-account/withdraw-pay',
|
167
|
+
'main-account/transfer',
|
168
|
+
'trade-account/balance',
|
169
|
+
'trade-account/executed-history',
|
170
|
+
'trade-account/order',
|
171
|
+
'trade-account/order/history',
|
172
|
+
'order/new',
|
173
|
+
'order/market',
|
174
|
+
'order/stock_market',
|
175
|
+
'order/stop_limit',
|
176
|
+
'order/stop_market',
|
177
|
+
'order/cancel',
|
178
|
+
'orders',
|
179
|
+
],
|
180
|
+
},
|
181
|
+
},
|
182
|
+
},
|
183
|
+
'fees': {
|
184
|
+
'trading': {
|
185
|
+
'tierBased': false,
|
186
|
+
'percentage': true,
|
187
|
+
'taker': this.parseNumber ('0.001'),
|
188
|
+
'maker': this.parseNumber ('0.001'),
|
189
|
+
},
|
190
|
+
},
|
191
|
+
'options': {
|
192
|
+
'createMarketBuyOrderRequiresPrice': true,
|
193
|
+
'fiatCurrencies': [ 'EUR', 'USD', 'RUB', 'UAH' ],
|
194
|
+
'accountsByType': {
|
195
|
+
'main': 'main',
|
196
|
+
'spot': 'trade',
|
197
|
+
'margin': 'margin', // api does not suppot transfers to margin
|
198
|
+
},
|
199
|
+
'transfer': {
|
200
|
+
'fillTransferResponseFromRequest': true,
|
201
|
+
},
|
202
|
+
},
|
203
|
+
'exceptions': {
|
204
|
+
'exact': {
|
205
|
+
'Unauthorized request.': AuthenticationError, // {"code":10,"message":"Unauthorized request."}
|
206
|
+
'The market format is invalid.': BadSymbol, // {"code":0,"message":"Validation failed","errors":{"market":["The market format is invalid."]}}
|
207
|
+
'Market is not available': BadSymbol, // {"success":false,"message":{"market":["Market is not available"]},"result":[]}
|
208
|
+
'Invalid payload.': BadRequest, // {"code":9,"message":"Invalid payload."}
|
209
|
+
'Amount must be greater than 0': InvalidOrder, // {"code":0,"message":"Validation failed","errors":{"amount":["Amount must be greater than 0"]}}
|
210
|
+
'The order id field is required.': InvalidOrder, // {"code":0,"message":"Validation failed","errors":{"orderId":["The order id field is required."]}}
|
211
|
+
'Not enough balance': InsufficientFunds, // {"code":0,"message":"Validation failed","errors":{"amount":["Not enough balance"]}}
|
212
|
+
'This action is unauthorized.': PermissionDenied, // {"code":0,"message":"This action is unauthorized."}
|
213
|
+
'This API Key is not authorized to perform this action.': PermissionDenied, // {"code":4,"message":"This API Key is not authorized to perform this action."}
|
214
|
+
'Unexecuted order was not found.': OrderNotFound, // {"code":2,"message":"Inner validation failed","errors":{"order_id":["Unexecuted order was not found."]}}
|
215
|
+
'503': ExchangeNotAvailable, // {"response":null,"status":503,"errors":{"message":[""]},"notification":null,"warning":null,"_token":null},
|
216
|
+
'422': OrderNotFound, // {"response":null,"status":422,"errors":{"orderId":["Finished order id 1295772653 not found on your account"]},"notification":null,"warning":"Finished order id 1295772653 not found on your account","_token":null}
|
217
|
+
},
|
218
|
+
'broad': {
|
219
|
+
'Given amount is less than min amount': InvalidOrder, // {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
|
220
|
+
'Total is less than': InvalidOrder, // {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
|
221
|
+
'fee must be no less than': InvalidOrder, // {"code":0,"message":"Validation failed","errors":{"amount":["Total amount + fee must be no less than 5.05505"]}}
|
222
|
+
'Enable your key in API settings': PermissionDenied, // {"code":2,"message":"This action is unauthorized. Enable your key in API settings"}
|
223
|
+
},
|
224
|
+
},
|
225
|
+
});
|
226
|
+
}
|
227
|
+
|
228
|
+
async fetchMarkets (params = {}) {
|
229
|
+
const response = await this.v2PublicGetMarkets (params);
|
230
|
+
//
|
231
|
+
// {
|
232
|
+
// "success": true,
|
233
|
+
// "message": "",
|
234
|
+
// "result": [
|
235
|
+
// {
|
236
|
+
// "name":
|
237
|
+
// "C98_USDT",
|
238
|
+
// "stock":"C98",
|
239
|
+
// "money":"USDT",
|
240
|
+
// "stockPrec":"3",
|
241
|
+
// "moneyPrec":"5",
|
242
|
+
// "feePrec":"6",
|
243
|
+
// "makerFee":"0.001",
|
244
|
+
// "takerFee":"0.001",
|
245
|
+
// "minAmount":"2.5",
|
246
|
+
// "minTotal":"5.05",
|
247
|
+
// "tradesEnabled":true
|
248
|
+
// },
|
249
|
+
// ...
|
250
|
+
// ]
|
251
|
+
// }
|
252
|
+
//
|
253
|
+
const markets = this.safeValue (response, 'result');
|
254
|
+
const result = [];
|
255
|
+
for (let i = 0; i < markets.length; i++) {
|
256
|
+
const market = markets[i];
|
257
|
+
const id = this.safeString (market, 'name');
|
258
|
+
const baseId = this.safeString (market, 'stock');
|
259
|
+
const quoteId = this.safeString (market, 'money');
|
260
|
+
const base = this.safeCurrencyCode (baseId);
|
261
|
+
const quote = this.safeCurrencyCode (quoteId);
|
262
|
+
const symbol = base + '/' + quote;
|
263
|
+
const active = this.safeValue (market, 'tradesEnabled');
|
264
|
+
const entry = {
|
265
|
+
'id': id,
|
266
|
+
'symbol': symbol,
|
267
|
+
'base': base,
|
268
|
+
'quote': quote,
|
269
|
+
'settle': undefined,
|
270
|
+
'baseId': baseId,
|
271
|
+
'quoteId': quoteId,
|
272
|
+
'settleId': undefined,
|
273
|
+
'type': 'spot',
|
274
|
+
'spot': true,
|
275
|
+
'margin': undefined,
|
276
|
+
'swap': false,
|
277
|
+
'future': false,
|
278
|
+
'option': false,
|
279
|
+
'active': active,
|
280
|
+
'contract': false,
|
281
|
+
'linear': undefined,
|
282
|
+
'inverse': undefined,
|
283
|
+
'taker': this.safeNumber (market, 'makerFee'),
|
284
|
+
'maker': this.safeNumber (market, 'takerFee'),
|
285
|
+
'contractSize': undefined,
|
286
|
+
'expiry': undefined,
|
287
|
+
'expiryDatetime': undefined,
|
288
|
+
'strike': undefined,
|
289
|
+
'optionType': undefined,
|
290
|
+
'precision': {
|
291
|
+
'amount': this.safeInteger (market, 'stockPrec'),
|
292
|
+
'price': this.safeInteger (market, 'moneyPrec'),
|
293
|
+
},
|
294
|
+
'limits': {
|
295
|
+
'leverage': {
|
296
|
+
'min': undefined,
|
297
|
+
'max': undefined,
|
298
|
+
},
|
299
|
+
'amount': {
|
300
|
+
'min': this.safeNumber (market, 'minAmount'),
|
301
|
+
'max': undefined,
|
302
|
+
},
|
303
|
+
'price': {
|
304
|
+
'min': undefined,
|
305
|
+
'max': undefined,
|
306
|
+
},
|
307
|
+
'cost': {
|
308
|
+
'min': this.safeNumber (market, 'minTotal'),
|
309
|
+
'max': undefined,
|
310
|
+
},
|
311
|
+
},
|
312
|
+
'info': market,
|
313
|
+
};
|
314
|
+
result.push (entry);
|
315
|
+
}
|
316
|
+
return result;
|
317
|
+
}
|
318
|
+
|
319
|
+
async fetchCurrencies (params = {}) {
|
320
|
+
const response = await this.v4PublicGetAssets (params);
|
321
|
+
//
|
322
|
+
// "BTC": {
|
323
|
+
// "name": "Bitcoin",
|
324
|
+
// "unified_cryptoasset_id": 1,
|
325
|
+
// "can_withdraw": true,
|
326
|
+
// "can_deposit": true,
|
327
|
+
// "min_withdraw": "0.001",
|
328
|
+
// "max_withdraw": "2",
|
329
|
+
// "maker_fee": "0.1",
|
330
|
+
// "taker_fee": "0.1",
|
331
|
+
// "min_deposit": "0.0001",
|
332
|
+
// "max_deposit": "0",
|
333
|
+
// },
|
334
|
+
//
|
335
|
+
const ids = Object.keys (response);
|
336
|
+
const result = {};
|
337
|
+
for (let i = 0; i < ids.length; i++) {
|
338
|
+
const id = ids[i];
|
339
|
+
const currency = response[id];
|
340
|
+
// breaks down in Python due to utf8 encoding issues on the exchange side
|
341
|
+
// const name = this.safeString (currency, 'name');
|
342
|
+
const canDeposit = this.safeValue (currency, 'can_deposit', true);
|
343
|
+
const canWithdraw = this.safeValue (currency, 'can_withdraw', true);
|
344
|
+
const active = canDeposit && canWithdraw;
|
345
|
+
const code = this.safeCurrencyCode (id);
|
346
|
+
result[code] = {
|
347
|
+
'id': id,
|
348
|
+
'code': code,
|
349
|
+
'info': currency, // the original payload
|
350
|
+
'name': undefined, // see the comment above
|
351
|
+
'active': active,
|
352
|
+
'deposit': canDeposit,
|
353
|
+
'withdraw': canWithdraw,
|
354
|
+
'fee': undefined,
|
355
|
+
'precision': undefined,
|
356
|
+
'limits': {
|
357
|
+
'amount': {
|
358
|
+
'min': undefined,
|
359
|
+
'max': undefined,
|
360
|
+
},
|
361
|
+
'withdraw': {
|
362
|
+
'min': this.safeNumber (currency, 'min_withdraw'),
|
363
|
+
'max': this.safeNumber (currency, 'max_withdraw'),
|
364
|
+
},
|
365
|
+
},
|
366
|
+
};
|
367
|
+
}
|
368
|
+
return result;
|
369
|
+
}
|
370
|
+
|
371
|
+
async fetchFundingFees (params = {}) {
|
372
|
+
await this.loadMarkets ();
|
373
|
+
const response = await this.v4PublicGetFee (params);
|
374
|
+
//
|
375
|
+
// {
|
376
|
+
// "1INCH":{
|
377
|
+
// "is_depositable":true,
|
378
|
+
// "is_withdrawal":true,
|
379
|
+
// "ticker":"1INCH",
|
380
|
+
// "name":"1inch",
|
381
|
+
// "providers":[
|
382
|
+
// ],
|
383
|
+
// "withdraw":{
|
384
|
+
// "max_amount":"0",
|
385
|
+
// "min_amount":"21.5",
|
386
|
+
// "fixed":"17.5",
|
387
|
+
// "flex":null
|
388
|
+
// },
|
389
|
+
// "deposit":{
|
390
|
+
// "max_amount":"0",
|
391
|
+
// "min_amount":"19.5",
|
392
|
+
// "fixed":null,
|
393
|
+
// "flex":null
|
394
|
+
// }
|
395
|
+
// },
|
396
|
+
// {...}
|
397
|
+
// }
|
398
|
+
//
|
399
|
+
const currenciesIds = Object.keys (response);
|
400
|
+
const withdrawFees = {};
|
401
|
+
const depositFees = {};
|
402
|
+
for (let i = 0; i < currenciesIds.length; i++) {
|
403
|
+
const currency = currenciesIds[i];
|
404
|
+
const data = response[currency];
|
405
|
+
const code = this.safeCurrencyCode (currency);
|
406
|
+
const withdraw = this.safeValue (data, 'withdraw', {});
|
407
|
+
withdrawFees[code] = this.safeString (withdraw, 'fixed');
|
408
|
+
const deposit = this.safeValue (data, 'deposit', {});
|
409
|
+
depositFees[code] = this.safeString (deposit, 'fixed');
|
410
|
+
}
|
411
|
+
return {
|
412
|
+
'withdraw': withdrawFees,
|
413
|
+
'deposit': depositFees,
|
414
|
+
'info': response,
|
415
|
+
};
|
416
|
+
}
|
417
|
+
|
418
|
+
async fetchTradingFees (params = {}) {
|
419
|
+
const response = await this.v4PublicGetAssets (params);
|
420
|
+
//
|
421
|
+
// {
|
422
|
+
// '1INCH': {
|
423
|
+
// name: '1inch',
|
424
|
+
// unified_cryptoasset_id: '8104',
|
425
|
+
// can_withdraw: true,
|
426
|
+
// can_deposit: true,
|
427
|
+
// min_withdraw: '33',
|
428
|
+
// max_withdraw: '0',
|
429
|
+
// maker_fee: '0.1',
|
430
|
+
// taker_fee: '0.1',
|
431
|
+
// min_deposit: '30',
|
432
|
+
// max_deposit: '0'
|
433
|
+
// },
|
434
|
+
// ...
|
435
|
+
// }
|
436
|
+
//
|
437
|
+
const result = {};
|
438
|
+
for (let i = 0; i < this.symbols.length; i++) {
|
439
|
+
const symbol = this.symbols[i];
|
440
|
+
const market = this.market (symbol);
|
441
|
+
const fee = this.safeValue (response, market['baseId'], {});
|
442
|
+
let makerFee = this.safeString (fee, 'maker_fee');
|
443
|
+
let takerFee = this.safeString (fee, 'taker_fee');
|
444
|
+
makerFee = Precise.stringDiv (makerFee, '100');
|
445
|
+
takerFee = Precise.stringDiv (takerFee, '100');
|
446
|
+
result[symbol] = {
|
447
|
+
'info': fee,
|
448
|
+
'symbol': market['symbol'],
|
449
|
+
'percentage': true,
|
450
|
+
'tierBased': false,
|
451
|
+
'maker': this.parseNumber (makerFee),
|
452
|
+
'taker': this.parseNumber (takerFee),
|
453
|
+
};
|
454
|
+
}
|
455
|
+
return result;
|
456
|
+
}
|
457
|
+
|
458
|
+
async fetchTicker (symbol, params = {}) {
|
459
|
+
await this.loadMarkets ();
|
460
|
+
const market = this.market (symbol);
|
461
|
+
const request = {
|
462
|
+
'market': market['id'],
|
463
|
+
};
|
464
|
+
const response = await this.v1PublicGetTicker (this.extend (request, params));
|
465
|
+
//
|
466
|
+
// {
|
467
|
+
// "success":true,
|
468
|
+
// "message":"",
|
469
|
+
// "result": {
|
470
|
+
// "bid":"0.021979",
|
471
|
+
// "ask":"0.021996",
|
472
|
+
// "open":"0.02182",
|
473
|
+
// "high":"0.022039",
|
474
|
+
// "low":"0.02161",
|
475
|
+
// "last":"0.021987",
|
476
|
+
// "volume":"2810.267",
|
477
|
+
// "deal":"61.383565474",
|
478
|
+
// "change":"0.76",
|
479
|
+
// },
|
480
|
+
// }
|
481
|
+
//
|
482
|
+
const ticker = this.safeValue (response, 'result', {});
|
483
|
+
return this.parseTicker (ticker, market);
|
484
|
+
}
|
485
|
+
|
486
|
+
parseTicker (ticker, market = undefined) {
|
487
|
+
//
|
488
|
+
// FetchTicker (v1)
|
489
|
+
//
|
490
|
+
// {
|
491
|
+
// "bid": "0.021979",
|
492
|
+
// "ask": "0.021996",
|
493
|
+
// "open": "0.02182",
|
494
|
+
// "high": "0.022039",
|
495
|
+
// "low": "0.02161",
|
496
|
+
// "last": "0.021987",
|
497
|
+
// "volume": "2810.267",
|
498
|
+
// "deal": "61.383565474",
|
499
|
+
// "change": "0.76",
|
500
|
+
// }
|
501
|
+
//
|
502
|
+
// FetchTickers (v4)
|
503
|
+
//
|
504
|
+
// "BCH_RUB": {
|
505
|
+
// "base_id": 1831,
|
506
|
+
// "quote_id": 0,
|
507
|
+
// "last_price": "32830.21",
|
508
|
+
// "quote_volume": "1494659.8024096",
|
509
|
+
// "base_volume": "46.1083",
|
510
|
+
// "isFrozen": false,
|
511
|
+
// "change": "2.12" // in percent
|
512
|
+
// }
|
513
|
+
//
|
514
|
+
market = this.safeMarket (undefined, market);
|
515
|
+
const last = this.safeString (ticker, 'last_price');
|
516
|
+
return this.safeTicker ({
|
517
|
+
'symbol': market['symbol'],
|
518
|
+
'timestamp': undefined,
|
519
|
+
'datetime': undefined,
|
520
|
+
'high': this.safeString (ticker, 'high'),
|
521
|
+
'low': this.safeString (ticker, 'low'),
|
522
|
+
'bid': this.safeString (ticker, 'bid'),
|
523
|
+
'bidVolume': undefined,
|
524
|
+
'ask': this.safeString (ticker, 'ask'),
|
525
|
+
'askVolume': undefined,
|
526
|
+
'vwap': undefined,
|
527
|
+
'open': this.safeString (ticker, 'open'),
|
528
|
+
'close': last,
|
529
|
+
'last': last,
|
530
|
+
'previousClose': undefined,
|
531
|
+
'change': undefined,
|
532
|
+
'percentage': this.safeString (ticker, 'change'),
|
533
|
+
'average': undefined,
|
534
|
+
'baseVolume': this.safeString2 (ticker, 'base_volume', 'volume'),
|
535
|
+
'quoteVolume': this.safeString2 (ticker, 'quote_volume', 'deal'),
|
536
|
+
'info': ticker,
|
537
|
+
}, market, false);
|
538
|
+
}
|
539
|
+
|
540
|
+
async fetchTickers (symbols = undefined, params = {}) {
|
541
|
+
await this.loadMarkets ();
|
542
|
+
const response = await this.v4PublicGetTicker (params);
|
543
|
+
//
|
544
|
+
// "BCH_RUB": {
|
545
|
+
// "base_id":1831,
|
546
|
+
// "quote_id":0,
|
547
|
+
// "last_price":"32830.21",
|
548
|
+
// "quote_volume":"1494659.8024096",
|
549
|
+
// "base_volume":"46.1083",
|
550
|
+
// "isFrozen":false,
|
551
|
+
// "change":"2.12"
|
552
|
+
// },
|
553
|
+
//
|
554
|
+
const marketIds = Object.keys (response);
|
555
|
+
const result = {};
|
556
|
+
for (let i = 0; i < marketIds.length; i++) {
|
557
|
+
const marketId = marketIds[i];
|
558
|
+
const market = this.safeMarket (marketId);
|
559
|
+
const ticker = this.parseTicker (response[marketId], market);
|
560
|
+
const symbol = ticker['symbol'];
|
561
|
+
result[symbol] = ticker;
|
562
|
+
}
|
563
|
+
return this.filterByArray (result, 'symbol', symbols);
|
564
|
+
}
|
565
|
+
|
566
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
567
|
+
await this.loadMarkets ();
|
568
|
+
const market = this.market (symbol);
|
569
|
+
const request = {
|
570
|
+
'market': market['id'],
|
571
|
+
};
|
572
|
+
if (limit !== undefined) {
|
573
|
+
request['depth'] = limit; // default = 50, maximum = 100
|
574
|
+
}
|
575
|
+
const response = await this.v4PublicGetOrderbookMarket (this.extend (request, params));
|
576
|
+
//
|
577
|
+
// {
|
578
|
+
// "timestamp": 1594391413,
|
579
|
+
// "asks": [
|
580
|
+
// [
|
581
|
+
// "9184.41",
|
582
|
+
// "0.773162"
|
583
|
+
// ],
|
584
|
+
// [ ... ]
|
585
|
+
// ],
|
586
|
+
// "bids": [
|
587
|
+
// [
|
588
|
+
// "9181.19",
|
589
|
+
// "0.010873"
|
590
|
+
// ],
|
591
|
+
// [ ... ]
|
592
|
+
// ]
|
593
|
+
// }
|
594
|
+
//
|
595
|
+
const timestamp = this.safeString (response, 'timestamp');
|
596
|
+
return this.parseOrderBook (response, symbol, timestamp);
|
597
|
+
}
|
598
|
+
|
599
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
600
|
+
await this.loadMarkets ();
|
601
|
+
const market = this.market (symbol);
|
602
|
+
const request = {
|
603
|
+
'market': market['id'],
|
604
|
+
};
|
605
|
+
const response = await this.v4PublicGetTradesMarket (this.extend (request, params));
|
606
|
+
//
|
607
|
+
// [
|
608
|
+
// {
|
609
|
+
// "tradeID": 158056419,
|
610
|
+
// "price": "9186.13",
|
611
|
+
// "quote_volume": "0.0021",
|
612
|
+
// "base_volume": "9186.13",
|
613
|
+
// "trade_timestamp": 1594391747,
|
614
|
+
// "type": "sell"
|
615
|
+
// },
|
616
|
+
// ],
|
617
|
+
//
|
618
|
+
return this.parseTrades (response, market, since, limit);
|
619
|
+
}
|
620
|
+
|
621
|
+
parseTrade (trade, market = undefined) {
|
622
|
+
// fetchTradesV4
|
623
|
+
// {
|
624
|
+
// "tradeID": 158056419,
|
625
|
+
// "price": "9186.13",
|
626
|
+
// "quote_volume": "0.0021",
|
627
|
+
// "base_volume": "9186.13",
|
628
|
+
// "trade_timestamp": 1594391747,
|
629
|
+
// "type": "sell"
|
630
|
+
// },
|
631
|
+
//
|
632
|
+
// orderTrades (v4Private)
|
633
|
+
//
|
634
|
+
// {
|
635
|
+
// "time": 1593342324.613711,
|
636
|
+
// "fee": "0.00000419198",
|
637
|
+
// "price": "0.00000701",
|
638
|
+
// "amount": "598",
|
639
|
+
// "id": 149156519, // trade id
|
640
|
+
// "dealOrderId": 3134995325, // orderId
|
641
|
+
// "clientOrderId": "customId11",
|
642
|
+
// "role": 2, // 1 = maker, 2 = taker
|
643
|
+
// "deal": "0.00419198" // amount in money
|
644
|
+
// }
|
645
|
+
//
|
646
|
+
const timestamp = this.safeTimestamp2 (trade, 'time', 'trade_timestamp');
|
647
|
+
const orderId = this.safeString (trade, 'dealOrderId');
|
648
|
+
const cost = this.safeString (trade, 'deal');
|
649
|
+
const price = this.safeString (trade, 'price');
|
650
|
+
const amount = this.safeString2 (trade, 'amount', 'base_volume');
|
651
|
+
const id = this.safeString2 (trade, 'id', 'tradeID');
|
652
|
+
const side = this.safeString (trade, 'type');
|
653
|
+
const symbol = this.safeSymbol (undefined, market);
|
654
|
+
const role = this.safeInteger (trade, 'role');
|
655
|
+
let takerOrMaker = undefined;
|
656
|
+
if (role !== undefined) {
|
657
|
+
takerOrMaker = (role === 1) ? 'maker' : 'taker';
|
658
|
+
}
|
659
|
+
let fee = undefined;
|
660
|
+
const feeCost = this.safeString (trade, 'fee');
|
661
|
+
if (feeCost !== undefined) {
|
662
|
+
const safeMarket = this.safeMarket (undefined, market);
|
663
|
+
const quote = safeMarket['quote'];
|
664
|
+
fee = {
|
665
|
+
'cost': feeCost,
|
666
|
+
'currency': quote,
|
667
|
+
};
|
668
|
+
}
|
669
|
+
return this.safeTrade ({
|
670
|
+
'info': trade,
|
671
|
+
'timestamp': timestamp,
|
672
|
+
'datetime': this.iso8601 (timestamp),
|
673
|
+
'symbol': symbol,
|
674
|
+
'id': id,
|
675
|
+
'order': orderId,
|
676
|
+
'type': undefined,
|
677
|
+
'takerOrMaker': takerOrMaker,
|
678
|
+
'side': side,
|
679
|
+
'price': price,
|
680
|
+
'amount': amount,
|
681
|
+
'cost': cost,
|
682
|
+
'fee': fee,
|
683
|
+
}, market);
|
684
|
+
}
|
685
|
+
|
686
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
687
|
+
await this.loadMarkets ();
|
688
|
+
const market = this.market (symbol);
|
689
|
+
const request = {
|
690
|
+
'market': market['id'],
|
691
|
+
'interval': this.timeframes[timeframe],
|
692
|
+
};
|
693
|
+
if (since !== undefined) {
|
694
|
+
const maxLimit = 1440;
|
695
|
+
if (limit === undefined) {
|
696
|
+
limit = maxLimit;
|
697
|
+
}
|
698
|
+
limit = Math.min (limit, maxLimit);
|
699
|
+
const start = parseInt (since / 1000);
|
700
|
+
const duration = this.parseTimeframe (timeframe);
|
701
|
+
const end = this.sum (start, duration * limit);
|
702
|
+
request['start'] = start;
|
703
|
+
request['end'] = end;
|
704
|
+
}
|
705
|
+
if (limit !== undefined) {
|
706
|
+
request['limit'] = limit; // max 1440
|
707
|
+
}
|
708
|
+
const response = await this.v1PublicGetKline (this.extend (request, params));
|
709
|
+
//
|
710
|
+
// {
|
711
|
+
// "success":true,
|
712
|
+
// "message":"",
|
713
|
+
// "result":[
|
714
|
+
// [1591488000,"0.025025","0.025025","0.025029","0.025023","6.181","0.154686629"],
|
715
|
+
// [1591488060,"0.025028","0.025033","0.025035","0.025026","8.067","0.201921167"],
|
716
|
+
// [1591488120,"0.025034","0.02505","0.02505","0.025034","20.089","0.503114696"],
|
717
|
+
// ]
|
718
|
+
// }
|
719
|
+
//
|
720
|
+
const result = this.safeValue (response, 'result', []);
|
721
|
+
return this.parseOHLCVs (result, market, timeframe, since, limit);
|
722
|
+
}
|
723
|
+
|
724
|
+
parseOHLCV (ohlcv, market = undefined) {
|
725
|
+
//
|
726
|
+
// [
|
727
|
+
// 1591488000,
|
728
|
+
// "0.025025",
|
729
|
+
// "0.025025",
|
730
|
+
// "0.025029",
|
731
|
+
// "0.025023",
|
732
|
+
// "6.181",
|
733
|
+
// "0.154686629"
|
734
|
+
// ]
|
735
|
+
//
|
736
|
+
return [
|
737
|
+
this.safeTimestamp (ohlcv, 0), // timestamp
|
738
|
+
this.safeNumber (ohlcv, 1), // open
|
739
|
+
this.safeNumber (ohlcv, 3), // high
|
740
|
+
this.safeNumber (ohlcv, 4), // low
|
741
|
+
this.safeNumber (ohlcv, 2), // close
|
742
|
+
this.safeNumber (ohlcv, 5), // volume
|
743
|
+
];
|
744
|
+
}
|
745
|
+
|
746
|
+
async fetchStatus (params = {}) {
|
747
|
+
const response = await this.v4PublicGetPing (params);
|
748
|
+
//
|
749
|
+
// [
|
750
|
+
// "pong"
|
751
|
+
// ]
|
752
|
+
//
|
753
|
+
const status = this.safeString (response, 0);
|
754
|
+
return {
|
755
|
+
'status': (status === 'pong') ? 'ok' : status,
|
756
|
+
'updated': this.milliseconds (),
|
757
|
+
'eta': undefined,
|
758
|
+
'url': undefined,
|
759
|
+
'info': response,
|
760
|
+
};
|
761
|
+
}
|
762
|
+
|
763
|
+
async fetchTime (params = {}) {
|
764
|
+
const response = await this.v4PublicGetTime (params);
|
765
|
+
//
|
766
|
+
// {
|
767
|
+
// "time":1635467280514
|
768
|
+
// }
|
769
|
+
//
|
770
|
+
return this.safeInteger (response, 'time');
|
771
|
+
}
|
772
|
+
|
773
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
774
|
+
let method = undefined;
|
775
|
+
await this.loadMarkets ();
|
776
|
+
const market = this.market (symbol);
|
777
|
+
const request = {
|
778
|
+
'market': market['id'],
|
779
|
+
'side': side,
|
780
|
+
'amount': this.amountToPrecision (symbol, amount),
|
781
|
+
};
|
782
|
+
const stopPrice = this.safeNumber2 (params, 'stopPrice', 'activationPrice');
|
783
|
+
if (stopPrice !== undefined) {
|
784
|
+
// it's a stop order
|
785
|
+
request['activation_price'] = this.priceToPrecision (symbol, stopPrice);
|
786
|
+
if (type === 'limit' || type === 'stopLimit') {
|
787
|
+
// it's a stop-limit-order
|
788
|
+
method = 'v4PrivateOPostOrderStopLimit';
|
789
|
+
} else if (type === 'market' || type === 'stopMarket') {
|
790
|
+
// it's a stop-market-order
|
791
|
+
method = 'v4PrivatePostOrderStopMarket';
|
792
|
+
}
|
793
|
+
} else {
|
794
|
+
if (type === 'market') {
|
795
|
+
// it's a regular market order
|
796
|
+
method = 'v4PrivatePostOrderMarket';
|
797
|
+
}
|
798
|
+
if (type === 'limit') {
|
799
|
+
// it's a regular limit order
|
800
|
+
method = 'v4PrivatePostOrderNew';
|
801
|
+
}
|
802
|
+
}
|
803
|
+
// aggregate common assignments regardless stop or not
|
804
|
+
if (type === 'limit' || type === 'stopLimit') {
|
805
|
+
if (price === undefined) {
|
806
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires a price argument for a stopLimit order');
|
807
|
+
}
|
808
|
+
const convertedPrice = this.priceToPrecision (symbol, price);
|
809
|
+
request['price'] = convertedPrice;
|
810
|
+
}
|
811
|
+
if (type === 'market' || type === 'stopMarket') {
|
812
|
+
if (side === 'buy') {
|
813
|
+
let cost = this.safeNumber (params, 'cost');
|
814
|
+
const createMarketBuyOrderRequiresPrice = this.safeValue (this.options, 'createMarketBuyOrderRequiresPrice', true);
|
815
|
+
if (createMarketBuyOrderRequiresPrice) {
|
816
|
+
if (price !== undefined) {
|
817
|
+
if (cost === undefined) {
|
818
|
+
cost = amount * price;
|
819
|
+
}
|
820
|
+
} else if (cost === undefined) {
|
821
|
+
throw new InvalidOrder (this.id + " createOrder() requires the price argument for market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options['createMarketBuyOrderRequiresPrice'] = false and supply the total cost value in the 'amount' argument or in the 'cost' extra parameter (the exchange-specific behaviour)");
|
822
|
+
}
|
823
|
+
} else {
|
824
|
+
cost = (cost === undefined) ? amount : cost;
|
825
|
+
}
|
826
|
+
request['amount'] = this.costToPrecision (symbol, cost);
|
827
|
+
}
|
828
|
+
}
|
829
|
+
if (method === undefined) {
|
830
|
+
throw new ArgumentsRequired (this.id + ' createOrder() requires one of the following order types: market, limit, stopLimit or stopMarket');
|
831
|
+
}
|
832
|
+
const response = await this[method] (this.extend (request, params));
|
833
|
+
return this.parseOrder (response);
|
834
|
+
}
|
835
|
+
|
836
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
837
|
+
if (symbol === undefined) {
|
838
|
+
throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
|
839
|
+
}
|
840
|
+
await this.loadMarkets ();
|
841
|
+
const market = this.market (symbol);
|
842
|
+
const request = {
|
843
|
+
'market': market['id'],
|
844
|
+
'orderId': parseInt (id),
|
845
|
+
};
|
846
|
+
return await this.v4PrivatePostOrderCancel (this.extend (request, params));
|
847
|
+
}
|
848
|
+
|
849
|
+
parseBalance (response) {
|
850
|
+
const balanceKeys = Object.keys (response);
|
851
|
+
const result = { };
|
852
|
+
for (let i = 0; i < balanceKeys.length; i++) {
|
853
|
+
const id = balanceKeys[i];
|
854
|
+
const balance = response[id];
|
855
|
+
const code = this.safeCurrencyCode (id);
|
856
|
+
const account = this.account ();
|
857
|
+
account['free'] = this.safeString (balance, 'available');
|
858
|
+
account['used'] = this.safeString (balance, 'freeze');
|
859
|
+
result[code] = account;
|
860
|
+
}
|
861
|
+
return this.safeBalance (result);
|
862
|
+
}
|
863
|
+
|
864
|
+
async fetchBalance (params = {}) {
|
865
|
+
await this.loadMarkets ();
|
866
|
+
const response = await this.v4PrivatePostTradeAccountBalance (params);
|
867
|
+
//
|
868
|
+
// {
|
869
|
+
// "BTC": { "available": "0.123", "freeze": "1" },
|
870
|
+
// "XMR": { "available": "3013", "freeze": "100" },
|
871
|
+
// }
|
872
|
+
//
|
873
|
+
return this.parseBalance (response);
|
874
|
+
}
|
875
|
+
|
876
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
877
|
+
if (symbol === undefined) {
|
878
|
+
throw new ArgumentsRequired (this.id + ' fetchOpenOrders() requires a symbol argument');
|
879
|
+
}
|
880
|
+
await this.loadMarkets ();
|
881
|
+
const market = this.market (symbol);
|
882
|
+
const request = {
|
883
|
+
'market': market['id'],
|
884
|
+
};
|
885
|
+
if (limit !== undefined) {
|
886
|
+
request['limit'] = limit; // default 50 max 100
|
887
|
+
}
|
888
|
+
const response = await this.v4PrivatePostOrders (this.extend (request, params));
|
889
|
+
//
|
890
|
+
// [
|
891
|
+
// {
|
892
|
+
// "orderId": 3686033640,
|
893
|
+
// "clientOrderId": "customId11",
|
894
|
+
// "market": "BTC_USDT",
|
895
|
+
// "side": "buy",
|
896
|
+
// "type": "limit",
|
897
|
+
// "timestamp": 1594605801.49815, // current timestamp of unexecuted order
|
898
|
+
// "dealMoney": "0", // executed amount in money
|
899
|
+
// "dealStock": "0", // executed amount in stock
|
900
|
+
// "amount": "2.241379", // active order amount
|
901
|
+
// "takerFee": "0.001",
|
902
|
+
// "makerFee": "0.001",
|
903
|
+
// "left": "2.241379", // unexecuted amount in stock
|
904
|
+
// "dealFee": "0", // executed fee by deal
|
905
|
+
// "price": "40000"
|
906
|
+
// },
|
907
|
+
// ]
|
908
|
+
//
|
909
|
+
return this.parseOrders (response, market, since, limit, { 'status': 'open' });
|
910
|
+
}
|
911
|
+
|
912
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
913
|
+
await this.loadMarkets ();
|
914
|
+
const request = {};
|
915
|
+
let market = undefined;
|
916
|
+
if (symbol !== undefined) {
|
917
|
+
market = this.market (symbol);
|
918
|
+
symbol = market['symbol'];
|
919
|
+
request['market'] = market['id'];
|
920
|
+
}
|
921
|
+
if (limit !== undefined) {
|
922
|
+
request['limit'] = limit; // default 50 max 100
|
923
|
+
}
|
924
|
+
const response = await this.v4PrivatePostTradeAccountOrderHistory (this.extend (request, params));
|
925
|
+
//
|
926
|
+
// {
|
927
|
+
// "BTC_USDT": [
|
928
|
+
// {
|
929
|
+
// "id": 160305483,
|
930
|
+
// "clientOrderId": "customId11",
|
931
|
+
// "time": 1594667731.724403,
|
932
|
+
// "side": "sell",
|
933
|
+
// "role": 2, // 1 = maker, 2 = taker
|
934
|
+
// "amount": "0.000076",
|
935
|
+
// "price": "9264.21",
|
936
|
+
// "deal": "0.70407996",
|
937
|
+
// "fee": "0.00070407996"
|
938
|
+
// },
|
939
|
+
// ],
|
940
|
+
// }
|
941
|
+
//
|
942
|
+
const marketIds = Object.keys (response);
|
943
|
+
let results = [];
|
944
|
+
for (let i = 0; i < marketIds.length; i++) {
|
945
|
+
const marketId = marketIds[i];
|
946
|
+
const market = this.safeMarket (marketId, undefined, '_');
|
947
|
+
const orders = response[marketId];
|
948
|
+
for (let j = 0; j < orders.length; j++) {
|
949
|
+
const order = this.parseOrder (orders[j], market);
|
950
|
+
results.push (this.extend (order, { 'status': 'filled' }));
|
951
|
+
}
|
952
|
+
}
|
953
|
+
results = this.sortBy (results, 'timestamp');
|
954
|
+
results = this.filterBySymbolSinceLimit (results, symbol, since, limit, since === undefined);
|
955
|
+
return results;
|
956
|
+
}
|
957
|
+
|
958
|
+
parseOrder (order, market = undefined) {
|
959
|
+
//
|
960
|
+
// createOrder, fetchOpenOrders
|
961
|
+
//
|
962
|
+
// {
|
963
|
+
// "orderId": 4180284841,
|
964
|
+
// "clientOrderId": "order1987111",
|
965
|
+
// "market": "BTC_USDT",
|
966
|
+
// "side": "buy",
|
967
|
+
// "type": "stop limit",
|
968
|
+
// "timestamp": 1595792396.165973,
|
969
|
+
// "dealMoney": "0", // if order finished - amount in money currency that finished
|
970
|
+
// "dealStock": "0", // if order finished - amount in stock currency that finished
|
971
|
+
// "amount": "0.001",
|
972
|
+
// "takerFee": "0.001",
|
973
|
+
// "makerFee": "0.001",
|
974
|
+
// "left": "0.001", // remaining amount
|
975
|
+
// "dealFee": "0", // fee in money that you pay if order is finished
|
976
|
+
// "price": "40000",
|
977
|
+
// "activation_price": "40000" // activation price -> only for stopLimit, stopMarket
|
978
|
+
// }
|
979
|
+
//
|
980
|
+
// fetchClosedOrders
|
981
|
+
//
|
982
|
+
// {
|
983
|
+
// "market": "BTC_USDT"
|
984
|
+
// "amount": "0.0009",
|
985
|
+
// "price": "40000",
|
986
|
+
// "type": "limit",
|
987
|
+
// "id": 4986126152,
|
988
|
+
// "clientOrderId": "customId11",
|
989
|
+
// "side": "sell",
|
990
|
+
// "ctime": 1597486960.311311, // timestamp of order creation
|
991
|
+
// "takerFee": "0.001",
|
992
|
+
// "ftime": 1597486960.311332, // executed order timestamp
|
993
|
+
// "makerFee": "0.001",
|
994
|
+
// "dealFee": "0.041258268", // paid fee if order is finished
|
995
|
+
// "dealStock": "0.0009", // amount in stock currency that finished
|
996
|
+
// "dealMoney": "41.258268" // amount in money currency that finished
|
997
|
+
// }
|
998
|
+
//
|
999
|
+
const marketId = this.safeString (order, 'market');
|
1000
|
+
market = this.safeMarket (marketId, market, '_');
|
1001
|
+
const symbol = market['symbol'];
|
1002
|
+
const side = this.safeString (order, 'side');
|
1003
|
+
const filled = this.safeString (order, 'dealStock');
|
1004
|
+
const remaining = this.safeString (order, 'left');
|
1005
|
+
let clientOrderId = this.safeString (order, 'clientOrderId');
|
1006
|
+
if (clientOrderId === '') {
|
1007
|
+
clientOrderId = undefined;
|
1008
|
+
}
|
1009
|
+
let price = this.safeString (order, 'price');
|
1010
|
+
const stopPrice = this.safeString (order, 'activation_price');
|
1011
|
+
const orderId = this.safeString2 (order, 'orderId', 'id');
|
1012
|
+
const type = this.safeString (order, 'type');
|
1013
|
+
let amount = this.safeString (order, 'amount');
|
1014
|
+
let cost = undefined;
|
1015
|
+
if (price === '0') {
|
1016
|
+
// api error to be solved
|
1017
|
+
price = undefined;
|
1018
|
+
}
|
1019
|
+
if (side === 'buy' && type.indexOf ('market') >= 0) {
|
1020
|
+
// in these cases the amount is in the quote currency meaning it's the cost
|
1021
|
+
cost = amount;
|
1022
|
+
amount = undefined;
|
1023
|
+
if (price !== undefined) {
|
1024
|
+
// if the price is available we can do this conversion
|
1025
|
+
// from amount in quote currency to base currency
|
1026
|
+
amount = Precise.stringDiv (cost, price);
|
1027
|
+
}
|
1028
|
+
}
|
1029
|
+
const dealFee = this.safeString (order, 'dealFee');
|
1030
|
+
let fee = undefined;
|
1031
|
+
if (dealFee !== undefined) {
|
1032
|
+
fee = {
|
1033
|
+
'cost': this.parseNumber (dealFee),
|
1034
|
+
'currency': market['quote'],
|
1035
|
+
};
|
1036
|
+
}
|
1037
|
+
const timestamp = this.safeTimestamp2 (order, 'ctime', 'timestamp');
|
1038
|
+
const lastTradeTimestamp = this.safeTimestamp (order, 'ftime');
|
1039
|
+
return this.safeOrder ({
|
1040
|
+
'info': order,
|
1041
|
+
'id': orderId,
|
1042
|
+
'symbol': symbol,
|
1043
|
+
'clientOrderId': clientOrderId,
|
1044
|
+
'timestamp': timestamp,
|
1045
|
+
'datetime': this.iso8601 (timestamp),
|
1046
|
+
'lastTradeTimestamp': lastTradeTimestamp,
|
1047
|
+
'timeInForce': undefined,
|
1048
|
+
'postOnly': undefined,
|
1049
|
+
'status': undefined,
|
1050
|
+
'side': side,
|
1051
|
+
'price': price,
|
1052
|
+
'type': type,
|
1053
|
+
'stopPrice': stopPrice,
|
1054
|
+
'amount': amount,
|
1055
|
+
'filled': filled,
|
1056
|
+
'remaining': remaining,
|
1057
|
+
'average': undefined,
|
1058
|
+
'cost': cost,
|
1059
|
+
'fee': fee,
|
1060
|
+
'trades': undefined,
|
1061
|
+
}, market);
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
1065
|
+
await this.loadMarkets ();
|
1066
|
+
const request = {
|
1067
|
+
'orderId': parseInt (id),
|
1068
|
+
};
|
1069
|
+
let market = undefined;
|
1070
|
+
if (symbol !== undefined) {
|
1071
|
+
market = this.market (symbol);
|
1072
|
+
request['market'] = market['id'];
|
1073
|
+
}
|
1074
|
+
if (limit !== undefined) {
|
1075
|
+
request['limit'] = limit; // default 50, max 100
|
1076
|
+
}
|
1077
|
+
const response = await this.v4PrivatePostTradeAccountOrder (this.extend (request, params));
|
1078
|
+
//
|
1079
|
+
// {
|
1080
|
+
// "records": [
|
1081
|
+
// {
|
1082
|
+
// "time": 1593342324.613711,
|
1083
|
+
// "fee": "0.00000419198",
|
1084
|
+
// "price": "0.00000701",
|
1085
|
+
// "amount": "598",
|
1086
|
+
// "id": 149156519, // trade id
|
1087
|
+
// "dealOrderId": 3134995325, // orderId
|
1088
|
+
// "clientOrderId": "customId11", // empty string if not specified
|
1089
|
+
// "role": 2, // 1 = maker, 2 = taker
|
1090
|
+
// "deal": "0.00419198"
|
1091
|
+
// }
|
1092
|
+
// ],
|
1093
|
+
// "offset": 0,
|
1094
|
+
// "limit": 100
|
1095
|
+
// }
|
1096
|
+
//
|
1097
|
+
const data = this.safeValue (response, 'records', []);
|
1098
|
+
return this.parseTrades (data, market);
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
async fetchDepositAddress (code, params = {}) {
|
1102
|
+
await this.loadMarkets ();
|
1103
|
+
const currency = this.currency (code);
|
1104
|
+
const request = {
|
1105
|
+
'ticker': currency['id'],
|
1106
|
+
};
|
1107
|
+
let method = 'v4PrivatePostMainAccountAddress';
|
1108
|
+
if (this.isFiat (code)) {
|
1109
|
+
method = 'v4PrivatePostMainAccountFiatDepositUrl';
|
1110
|
+
const provider = this.safeNumber (params, 'provider');
|
1111
|
+
if (provider === undefined) {
|
1112
|
+
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() requires a provider when the ticker is fiat');
|
1113
|
+
}
|
1114
|
+
request['provider'] = provider;
|
1115
|
+
const amount = this.safeNumber (params, 'amount');
|
1116
|
+
if (amount === undefined) {
|
1117
|
+
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() requires an amount when the ticker is fiat');
|
1118
|
+
}
|
1119
|
+
request['amount'] = amount;
|
1120
|
+
const uniqueId = this.safeValue (params, 'uniqueId');
|
1121
|
+
if (uniqueId === undefined) {
|
1122
|
+
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() requires an uniqueId when the ticker is fiat');
|
1123
|
+
}
|
1124
|
+
}
|
1125
|
+
const response = await this[method] (this.extend (request, params));
|
1126
|
+
//
|
1127
|
+
// fiat
|
1128
|
+
//
|
1129
|
+
// {
|
1130
|
+
// "url": "https://someaddress.com"
|
1131
|
+
// }
|
1132
|
+
//
|
1133
|
+
// crypto
|
1134
|
+
//
|
1135
|
+
// {
|
1136
|
+
// "account": {
|
1137
|
+
// "address": "GDTSOI56XNVAKJNJBLJGRNZIVOCIZJRBIDKTWSCYEYNFAZEMBLN75RMN",
|
1138
|
+
// "memo": "48565488244493"
|
1139
|
+
// },
|
1140
|
+
// "required": {
|
1141
|
+
// "fixedFee": "0",
|
1142
|
+
// "flexFee": {
|
1143
|
+
// "maxFee": "0",
|
1144
|
+
// "minFee": "0",
|
1145
|
+
// "percent": "0"
|
1146
|
+
// },
|
1147
|
+
// "maxAmount": "0",
|
1148
|
+
// "minAmount": "1"
|
1149
|
+
// }
|
1150
|
+
// }
|
1151
|
+
//
|
1152
|
+
const url = this.safeString (response, 'url');
|
1153
|
+
const account = this.safeValue (response, 'account', {});
|
1154
|
+
const address = this.safeString (account, 'address', url);
|
1155
|
+
const tag = this.safeString (account, 'memo');
|
1156
|
+
this.checkAddress (address);
|
1157
|
+
return {
|
1158
|
+
'currency': code,
|
1159
|
+
'address': address,
|
1160
|
+
'tag': tag,
|
1161
|
+
'network': undefined,
|
1162
|
+
'info': response,
|
1163
|
+
};
|
1164
|
+
}
|
1165
|
+
|
1166
|
+
async transfer (code, amount, fromAccount, toAccount, params = {}) {
|
1167
|
+
await this.loadMarkets ();
|
1168
|
+
const currency = this.currency (code);
|
1169
|
+
const accountsByType = this.safeValue (this.options, 'accountsByType');
|
1170
|
+
const fromAccountId = this.safeString (accountsByType, fromAccount, fromAccount);
|
1171
|
+
const toAccountId = this.safeString (accountsByType, toAccount, toAccount);
|
1172
|
+
let type = undefined;
|
1173
|
+
if (fromAccountId === 'main' && toAccountId === 'trade') {
|
1174
|
+
type = 'deposit';
|
1175
|
+
} else if (fromAccountId === 'trade' && toAccountId === 'main') {
|
1176
|
+
type = 'withdraw';
|
1177
|
+
}
|
1178
|
+
if (type === undefined) {
|
1179
|
+
throw new ExchangeError (this.id + ' transfer() only allows transfers between main account and spot account');
|
1180
|
+
}
|
1181
|
+
const request = {
|
1182
|
+
'ticker': currency['id'],
|
1183
|
+
'method': type,
|
1184
|
+
'amount': this.currencyToPrecision (code, amount),
|
1185
|
+
};
|
1186
|
+
const response = await this.v4PrivatePostMainAccountTransfer (this.extend (request, params));
|
1187
|
+
//
|
1188
|
+
// []
|
1189
|
+
//
|
1190
|
+
const transfer = this.parseTransfer (response, currency);
|
1191
|
+
const transferOptions = this.safeValue (this.options, 'transfer', {});
|
1192
|
+
const fillTransferResponseFromRequest = this.safeValue (transferOptions, 'fillTransferResponseFromRequest', true);
|
1193
|
+
if (fillTransferResponseFromRequest) {
|
1194
|
+
transfer['amount'] = amount;
|
1195
|
+
transfer['fromAccount'] = fromAccount;
|
1196
|
+
transfer['toAccount'] = toAccount;
|
1197
|
+
}
|
1198
|
+
return transfer;
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
parseTransfer (transfer, currency) {
|
1202
|
+
//
|
1203
|
+
// []
|
1204
|
+
//
|
1205
|
+
return {
|
1206
|
+
'info': transfer,
|
1207
|
+
'id': undefined,
|
1208
|
+
'timestamp': undefined,
|
1209
|
+
'datetime': undefined,
|
1210
|
+
'currency': this.safeCurrencyCode (undefined, currency),
|
1211
|
+
'amount': undefined,
|
1212
|
+
'fromAccount': undefined,
|
1213
|
+
'toAccount': undefined,
|
1214
|
+
'status': 'pending',
|
1215
|
+
};
|
1216
|
+
}
|
1217
|
+
|
1218
|
+
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
1219
|
+
await this.loadMarkets ();
|
1220
|
+
const currency = this.currency (code); // check if it has canDeposit
|
1221
|
+
const request = {
|
1222
|
+
'ticker': currency['id'],
|
1223
|
+
'amount': this.currencyToPrecision (code, amount),
|
1224
|
+
'address': address,
|
1225
|
+
};
|
1226
|
+
let uniqueId = this.safeValue (params, 'uniqueId');
|
1227
|
+
if (uniqueId === undefined) {
|
1228
|
+
uniqueId = this.uuid22 ();
|
1229
|
+
}
|
1230
|
+
request['uniqueId'] = uniqueId;
|
1231
|
+
if (tag !== undefined) {
|
1232
|
+
request['memo'] = tag;
|
1233
|
+
}
|
1234
|
+
if (this.isFiat (code)) {
|
1235
|
+
const provider = this.safeValue (params, 'provider');
|
1236
|
+
if (provider === undefined) {
|
1237
|
+
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() requires a provider when the ticker is fiat');
|
1238
|
+
}
|
1239
|
+
request['provider'] = provider;
|
1240
|
+
}
|
1241
|
+
const response = await this.v4PrivatePostMainAccountWithdraw (this.extend (request, params));
|
1242
|
+
//
|
1243
|
+
// empty array with a success status
|
1244
|
+
// go to deposit/withdraw history and check you request status by uniqueId
|
1245
|
+
//
|
1246
|
+
// []
|
1247
|
+
//
|
1248
|
+
return this.extend ({ 'id': uniqueId }, this.parseTransaction (response, currency));
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
parseTransaction (transaction, currency = undefined) {
|
1252
|
+
//
|
1253
|
+
// withdraw
|
1254
|
+
//
|
1255
|
+
// []
|
1256
|
+
//
|
1257
|
+
currency = this.safeCurrency (undefined, currency);
|
1258
|
+
return {
|
1259
|
+
'id': undefined,
|
1260
|
+
'txid': undefined,
|
1261
|
+
'timestamp': undefined,
|
1262
|
+
'datetime': undefined,
|
1263
|
+
'network': undefined,
|
1264
|
+
'addressFrom': undefined,
|
1265
|
+
'address': undefined,
|
1266
|
+
'addressTo': undefined,
|
1267
|
+
'amount': undefined,
|
1268
|
+
'type': undefined,
|
1269
|
+
'currency': currency['code'],
|
1270
|
+
'status': undefined,
|
1271
|
+
'updated': undefined,
|
1272
|
+
'tagFrom': undefined,
|
1273
|
+
'tag': undefined,
|
1274
|
+
'tagTo': undefined,
|
1275
|
+
'comment': undefined,
|
1276
|
+
'fee': undefined,
|
1277
|
+
'info': transaction,
|
1278
|
+
};
|
1279
|
+
}
|
1280
|
+
|
1281
|
+
isFiat (currency) {
|
1282
|
+
const fiatCurrencies = this.safeValue (this.options, 'fiatCurrencies', []);
|
1283
|
+
return this.inArray (currency, fiatCurrencies);
|
1284
|
+
}
|
1285
|
+
|
1286
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
1287
|
+
const query = this.omit (params, this.extractParams (path));
|
1288
|
+
const version = this.safeValue (api, 0);
|
1289
|
+
const accessibility = this.safeValue (api, 1);
|
1290
|
+
const pathWithParams = '/' + this.implodeParams (path, params);
|
1291
|
+
let url = this.urls['api'][version][accessibility] + pathWithParams;
|
1292
|
+
if (accessibility === 'public') {
|
1293
|
+
if (Object.keys (query).length) {
|
1294
|
+
url += '?' + this.urlencode (query);
|
1295
|
+
}
|
1296
|
+
}
|
1297
|
+
if (accessibility === 'private') {
|
1298
|
+
this.checkRequiredCredentials ();
|
1299
|
+
const nonce = this.nonce ().toString ();
|
1300
|
+
const secret = this.stringToBinary (this.encode (this.secret));
|
1301
|
+
const request = '/' + 'api' + '/' + version + pathWithParams;
|
1302
|
+
body = this.json (this.extend ({ 'request': request, 'nonce': nonce }, params));
|
1303
|
+
const payload = this.stringToBase64 (body);
|
1304
|
+
const signature = this.hmac (payload, secret, 'sha512');
|
1305
|
+
headers = {
|
1306
|
+
'Content-Type': 'application/json',
|
1307
|
+
'X-TXC-APIKEY': this.apiKey,
|
1308
|
+
'X-TXC-PAYLOAD': payload,
|
1309
|
+
'X-TXC-SIGNATURE': signature,
|
1310
|
+
};
|
1311
|
+
}
|
1312
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
1313
|
+
}
|
1314
|
+
|
1315
|
+
handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
1316
|
+
if ((code === 418) || (code === 429)) {
|
1317
|
+
throw new DDoSProtection (this.id + ' ' + code.toString () + ' ' + reason + ' ' + body);
|
1318
|
+
}
|
1319
|
+
if (code === 404) {
|
1320
|
+
throw new ExchangeError (this.id + ' ' + code.toString () + ' endpoint not found');
|
1321
|
+
}
|
1322
|
+
if (response !== undefined) {
|
1323
|
+
// For cases where we have a meaningful status
|
1324
|
+
// {"response":null,"status":422,"errors":{"orderId":["Finished order id 435453454535 not found on your account"]},"notification":null,"warning":"Finished order id 435453454535 not found on your account","_token":null}
|
1325
|
+
const status = this.safeInteger (response, 'status');
|
1326
|
+
// {"code":10,"message":"Unauthorized request."}
|
1327
|
+
const message = this.safeString (response, 'message');
|
1328
|
+
// For these cases where we have a generic code variable error key
|
1329
|
+
// {"code":0,"message":"Validation failed","errors":{"amount":["Amount must be greater than 0"]}}
|
1330
|
+
const code = this.safeInteger (response, 'code');
|
1331
|
+
const hasErrorStatus = status !== undefined && status !== '200';
|
1332
|
+
if (hasErrorStatus || code !== undefined) {
|
1333
|
+
const feedback = this.id + ' ' + body;
|
1334
|
+
let errorInfo = message;
|
1335
|
+
if (hasErrorStatus) {
|
1336
|
+
errorInfo = status;
|
1337
|
+
} else {
|
1338
|
+
const errorObject = this.safeValue (response, 'errors');
|
1339
|
+
if (errorObject !== undefined) {
|
1340
|
+
const errorKey = Object.keys (errorObject)[0];
|
1341
|
+
const errorMessageArray = this.safeValue (errorObject, errorKey, []);
|
1342
|
+
const errorMessageLength = errorMessageArray.length;
|
1343
|
+
errorInfo = (errorMessageLength > 0) ? errorMessageArray[0] : body;
|
1344
|
+
}
|
1345
|
+
}
|
1346
|
+
this.throwExactlyMatchedException (this.exceptions['exact'], errorInfo, feedback);
|
1347
|
+
this.throwBroadlyMatchedException (this.exceptions['broad'], body, feedback);
|
1348
|
+
throw new ExchangeError (feedback);
|
1349
|
+
}
|
1350
|
+
}
|
1351
|
+
}
|
1352
|
+
};
|