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/buda.js
ADDED
@@ -0,0 +1,946 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
// ---------------------------------------------------------------------------
|
4
|
+
|
5
|
+
const Exchange = require ('./base/Exchange');
|
6
|
+
const { AddressPending, AuthenticationError, ExchangeError, NotSupported, PermissionDenied, ArgumentsRequired } = require ('./base/errors');
|
7
|
+
const Precise = require ('./base/Precise');
|
8
|
+
|
9
|
+
// ---------------------------------------------------------------------------
|
10
|
+
|
11
|
+
module.exports = class buda extends Exchange {
|
12
|
+
describe () {
|
13
|
+
return this.deepExtend (super.describe (), {
|
14
|
+
'id': 'buda',
|
15
|
+
'name': 'Buda',
|
16
|
+
'countries': [ 'AR', 'CL', 'CO', 'PE' ],
|
17
|
+
'rateLimit': 1000,
|
18
|
+
'version': 'v2',
|
19
|
+
'has': {
|
20
|
+
'CORS': undefined,
|
21
|
+
'spot': true,
|
22
|
+
'margin': false,
|
23
|
+
'swap': false,
|
24
|
+
'future': false,
|
25
|
+
'option': false,
|
26
|
+
'addMargin': false,
|
27
|
+
'cancelOrder': true,
|
28
|
+
'createDepositAddress': true,
|
29
|
+
'createOrder': true,
|
30
|
+
'createReduceOnlyOrder': false,
|
31
|
+
'fetchBalance': true,
|
32
|
+
'fetchBorrowRate': false,
|
33
|
+
'fetchBorrowRateHistories': false,
|
34
|
+
'fetchBorrowRateHistory': false,
|
35
|
+
'fetchBorrowRates': false,
|
36
|
+
'fetchBorrowRatesPerSymbol': false,
|
37
|
+
'fetchClosedOrders': true,
|
38
|
+
'fetchCurrencies': true,
|
39
|
+
'fetchDepositAddress': true,
|
40
|
+
'fetchDeposits': true,
|
41
|
+
'fetchFundingFees': true,
|
42
|
+
'fetchFundingHistory': false,
|
43
|
+
'fetchFundingRate': false,
|
44
|
+
'fetchFundingRateHistory': false,
|
45
|
+
'fetchFundingRates': false,
|
46
|
+
'fetchIndexOHLCV': false,
|
47
|
+
'fetchLeverage': false,
|
48
|
+
'fetchMarkets': true,
|
49
|
+
'fetchMarkOHLCV': false,
|
50
|
+
'fetchMyTrades': undefined,
|
51
|
+
'fetchOHLCV': true,
|
52
|
+
'fetchOpenOrders': true,
|
53
|
+
'fetchOrder': true,
|
54
|
+
'fetchOrderBook': true,
|
55
|
+
'fetchOrders': true,
|
56
|
+
'fetchPosition': false,
|
57
|
+
'fetchPositions': false,
|
58
|
+
'fetchPositionsRisk': false,
|
59
|
+
'fetchPremiumIndexOHLCV': false,
|
60
|
+
'fetchTicker': true,
|
61
|
+
'fetchTrades': true,
|
62
|
+
'fetchTradingFee': false,
|
63
|
+
'fetchTradingFees': false,
|
64
|
+
'fetchWithdrawals': true,
|
65
|
+
'reduceMargin': false,
|
66
|
+
'setLeverage': false,
|
67
|
+
'setMarginMode': false,
|
68
|
+
'setPositionMode': false,
|
69
|
+
'withdraw': true,
|
70
|
+
},
|
71
|
+
'urls': {
|
72
|
+
'logo': 'https://user-images.githubusercontent.com/1294454/47380619-8a029200-d706-11e8-91e0-8a391fe48de3.jpg',
|
73
|
+
'api': 'https://www.buda.com/api',
|
74
|
+
'www': 'https://www.buda.com',
|
75
|
+
'doc': 'https://api.buda.com',
|
76
|
+
'fees': 'https://www.buda.com/comisiones',
|
77
|
+
},
|
78
|
+
'status': {
|
79
|
+
'status': 'error',
|
80
|
+
'updated': undefined,
|
81
|
+
'eta': undefined,
|
82
|
+
'url': undefined,
|
83
|
+
},
|
84
|
+
'api': {
|
85
|
+
'public': {
|
86
|
+
'get': [
|
87
|
+
'pairs',
|
88
|
+
'markets',
|
89
|
+
'currencies',
|
90
|
+
'markets/{market}',
|
91
|
+
'markets/{market}/ticker',
|
92
|
+
'markets/{market}/volume',
|
93
|
+
'markets/{market}/order_book',
|
94
|
+
'markets/{market}/trades',
|
95
|
+
'currencies/{currency}/fees/deposit',
|
96
|
+
'currencies/{currency}/fees/withdrawal',
|
97
|
+
'tv/history',
|
98
|
+
],
|
99
|
+
'post': [
|
100
|
+
'markets/{market}/quotations',
|
101
|
+
],
|
102
|
+
},
|
103
|
+
'private': {
|
104
|
+
'get': [
|
105
|
+
'balances',
|
106
|
+
'balances/{currency}',
|
107
|
+
'currencies/{currency}/balances',
|
108
|
+
'orders',
|
109
|
+
'orders/{id}',
|
110
|
+
'markets/{market}/orders',
|
111
|
+
'deposits',
|
112
|
+
'currencies/{currency}/deposits',
|
113
|
+
'withdrawals',
|
114
|
+
'currencies/{currency}/withdrawals',
|
115
|
+
'currencies/{currency}/receive_addresses',
|
116
|
+
'currencies/{currency}/receive_addresses/{id}',
|
117
|
+
],
|
118
|
+
'post': [
|
119
|
+
'markets/{market}/orders',
|
120
|
+
'currencies/{currency}/deposits',
|
121
|
+
'currencies/{currency}/withdrawals',
|
122
|
+
'currencies/{currency}/simulated_withdrawals',
|
123
|
+
'currencies/{currency}/receive_addresses',
|
124
|
+
],
|
125
|
+
'put': [
|
126
|
+
'orders/{id}',
|
127
|
+
],
|
128
|
+
},
|
129
|
+
},
|
130
|
+
'timeframes': {
|
131
|
+
'1m': '1',
|
132
|
+
'5m': '5',
|
133
|
+
'30m': '30',
|
134
|
+
'1h': '60',
|
135
|
+
'2h': '120',
|
136
|
+
'1d': 'D',
|
137
|
+
'1w': 'W',
|
138
|
+
},
|
139
|
+
'fees': {
|
140
|
+
'trading': {
|
141
|
+
'tierBased': true,
|
142
|
+
'percentage': true,
|
143
|
+
'taker': 0.008, // 0.8%
|
144
|
+
'maker': 0.004, // 0.4%
|
145
|
+
'tiers': {
|
146
|
+
'taker': [
|
147
|
+
[ 0, 0.008 ], // 0.8%
|
148
|
+
[ 2000, 0.007 ], // 0.7%
|
149
|
+
[ 20000, 0.006 ], // 0.6%
|
150
|
+
[ 100000, 0.005 ], // 0.5%
|
151
|
+
[ 500000, 0.004 ], // 0.4%
|
152
|
+
[ 2500000, 0.003 ], // 0.3%
|
153
|
+
[ 12500000, 0.002 ], // 0.2%
|
154
|
+
],
|
155
|
+
'maker': [
|
156
|
+
[ 0, 0.004 ], // 0.4%
|
157
|
+
[ 2000, 0.0035 ], // 0.35%
|
158
|
+
[ 20000, 0.003 ], // 0.3%
|
159
|
+
[ 100000, 0.0025 ], // 0.25%
|
160
|
+
[ 500000, 0.002 ], // 0.2%
|
161
|
+
[ 2500000, 0.0015 ], // 0.15%
|
162
|
+
[ 12500000, 0.001 ], // 0.1%
|
163
|
+
],
|
164
|
+
},
|
165
|
+
},
|
166
|
+
},
|
167
|
+
'exceptions': {
|
168
|
+
'not_authorized': AuthenticationError, // { message: 'Invalid credentials', code: 'not_authorized' }
|
169
|
+
'forbidden': PermissionDenied, // { message: 'You dont have access to this resource', code: 'forbidden' }
|
170
|
+
'invalid_record': ExchangeError, // { message: 'Validation Failed', code: 'invalid_record', errors: [] }
|
171
|
+
'not_found': ExchangeError, // { message: 'Not found', code: 'not_found' }
|
172
|
+
'parameter_missing': ExchangeError, // { message: 'Parameter missing', code: 'parameter_missing' }
|
173
|
+
'bad_parameter': ExchangeError, // { message: 'Bad Parameter format', code: 'bad_parameter' }
|
174
|
+
},
|
175
|
+
});
|
176
|
+
}
|
177
|
+
|
178
|
+
async fetchCurrencyInfo (currency, currencies = undefined) {
|
179
|
+
if (!currencies) {
|
180
|
+
const response = await this.publicGetCurrencies ();
|
181
|
+
//
|
182
|
+
// {
|
183
|
+
// "currencies":[
|
184
|
+
// {
|
185
|
+
// "id":"BTC",
|
186
|
+
// "symbol":"฿",
|
187
|
+
// "managed":true,
|
188
|
+
// "input_decimals":8,
|
189
|
+
// "display_decimals":8,
|
190
|
+
// "timezone":"UTC",
|
191
|
+
// "deposit_minimum":["0.0","BTC"],
|
192
|
+
// "withdrawal_minimum":["0.00001","BTC"],
|
193
|
+
// "max_digits_for_decimals":6,
|
194
|
+
// "crypto":true,
|
195
|
+
// "address_explorer":"https://blockchair.com/bitcoin/address/",
|
196
|
+
// "tx_explorer":"https://blockchair.com/bitcoin/transaction/",
|
197
|
+
// "amount_to_micro_multiplier":1000000000000
|
198
|
+
// }
|
199
|
+
// ]
|
200
|
+
// }
|
201
|
+
//
|
202
|
+
currencies = this.safeValue (response, 'currencies');
|
203
|
+
}
|
204
|
+
for (let i = 0; i < currencies.length; i++) {
|
205
|
+
const currencyInfo = currencies[i];
|
206
|
+
if (currencyInfo['id'] === currency) {
|
207
|
+
return currencyInfo;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
return undefined;
|
211
|
+
}
|
212
|
+
|
213
|
+
async fetchMarkets (params = {}) {
|
214
|
+
const marketsResponse = await this.publicGetMarkets (params);
|
215
|
+
const markets = this.safeValue (marketsResponse, 'markets');
|
216
|
+
const currenciesResponse = await this.publicGetCurrencies ();
|
217
|
+
const currencies = this.safeValue (currenciesResponse, 'currencies');
|
218
|
+
const result = [];
|
219
|
+
for (let i = 0; i < markets.length; i++) {
|
220
|
+
const market = markets[i];
|
221
|
+
const baseId = this.safeString (market, 'base_currency');
|
222
|
+
const quoteId = this.safeString (market, 'quote_currency');
|
223
|
+
const base = this.safeCurrencyCode (baseId);
|
224
|
+
const quote = this.safeCurrencyCode (quoteId);
|
225
|
+
const baseInfo = await this.fetchCurrencyInfo (baseId, currencies);
|
226
|
+
const quoteInfo = await this.fetchCurrencyInfo (quoteId, currencies);
|
227
|
+
const pricePrecisionString = this.safeString (quoteInfo, 'input_decimals');
|
228
|
+
const minimumOrderAmount = this.safeValue (market, 'minimum_order_amount', []);
|
229
|
+
result.push ({
|
230
|
+
'id': this.safeString (market, 'id'),
|
231
|
+
'symbol': base + '/' + quote,
|
232
|
+
'base': base,
|
233
|
+
'quote': quote,
|
234
|
+
'settle': undefined,
|
235
|
+
'baseId': baseId,
|
236
|
+
'quoteId': quoteId,
|
237
|
+
'settleId': undefined,
|
238
|
+
'type': 'spot',
|
239
|
+
'spot': true,
|
240
|
+
'margin': false,
|
241
|
+
'swap': false,
|
242
|
+
'future': false,
|
243
|
+
'option': false,
|
244
|
+
'active': true,
|
245
|
+
'contract': false,
|
246
|
+
'linear': undefined,
|
247
|
+
'inverse': undefined,
|
248
|
+
'contractSize': undefined,
|
249
|
+
'expiry': undefined,
|
250
|
+
'expiryDatetime': undefined,
|
251
|
+
'strike': undefined,
|
252
|
+
'optionType': undefined,
|
253
|
+
'precision': {
|
254
|
+
'amount': this.safeInteger (baseInfo, 'input_decimals'),
|
255
|
+
'price': parseInt (pricePrecisionString),
|
256
|
+
},
|
257
|
+
'limits': {
|
258
|
+
'leverage': {
|
259
|
+
'min': undefined,
|
260
|
+
'max': undefined,
|
261
|
+
},
|
262
|
+
'amount': {
|
263
|
+
'min': this.safeNumber (minimumOrderAmount, 0),
|
264
|
+
'max': undefined,
|
265
|
+
},
|
266
|
+
'price': {
|
267
|
+
'min': undefined,
|
268
|
+
'max': undefined,
|
269
|
+
},
|
270
|
+
'cost': {
|
271
|
+
'min': undefined,
|
272
|
+
'max': undefined,
|
273
|
+
},
|
274
|
+
},
|
275
|
+
'info': market,
|
276
|
+
});
|
277
|
+
}
|
278
|
+
return result;
|
279
|
+
}
|
280
|
+
|
281
|
+
async fetchCurrencies (params = {}) {
|
282
|
+
const response = await this.publicGetCurrencies ();
|
283
|
+
//
|
284
|
+
// {
|
285
|
+
// "currencies":[
|
286
|
+
// {
|
287
|
+
// "id":"BTC",
|
288
|
+
// "symbol":"฿",
|
289
|
+
// "managed":true,
|
290
|
+
// "input_decimals":8,
|
291
|
+
// "display_decimals":8,
|
292
|
+
// "timezone":"UTC",
|
293
|
+
// "deposit_minimum":["0.0","BTC"],
|
294
|
+
// "withdrawal_minimum":["0.00001","BTC"],
|
295
|
+
// "max_digits_for_decimals":6,
|
296
|
+
// "crypto":true,
|
297
|
+
// "address_explorer":"https://blockchair.com/bitcoin/address/",
|
298
|
+
// "tx_explorer":"https://blockchair.com/bitcoin/transaction/",
|
299
|
+
// "amount_to_micro_multiplier":1000000000000
|
300
|
+
// }
|
301
|
+
// ]
|
302
|
+
// }
|
303
|
+
//
|
304
|
+
const currencies = response['currencies'];
|
305
|
+
const result = {};
|
306
|
+
for (let i = 0; i < currencies.length; i++) {
|
307
|
+
const currency = currencies[i];
|
308
|
+
const managed = this.safeValue (currency, 'managed', false);
|
309
|
+
if (!managed) {
|
310
|
+
continue;
|
311
|
+
}
|
312
|
+
const id = this.safeString (currency, 'id');
|
313
|
+
const code = this.safeCurrencyCode (id);
|
314
|
+
const precision = this.safeNumber (currency, 'input_decimals');
|
315
|
+
const minimum = Math.pow (10, -precision);
|
316
|
+
const depositMinimum = this.safeValue (currency, 'deposit_minimum', []);
|
317
|
+
const withdrawalMinimum = this.safeValue (currency, 'withdrawal_minimum', []);
|
318
|
+
const minDeposit = this.safeNumber (depositMinimum, 0);
|
319
|
+
const minWithdraw = this.safeNumber (withdrawalMinimum, 0);
|
320
|
+
result[code] = {
|
321
|
+
'id': id,
|
322
|
+
'code': code,
|
323
|
+
'info': currency,
|
324
|
+
'name': undefined,
|
325
|
+
'active': true,
|
326
|
+
'deposit': undefined,
|
327
|
+
'withdraw': undefined,
|
328
|
+
'fee': undefined,
|
329
|
+
'precision': precision,
|
330
|
+
'limits': {
|
331
|
+
'amount': {
|
332
|
+
'min': minimum,
|
333
|
+
'max': undefined,
|
334
|
+
},
|
335
|
+
'deposit': {
|
336
|
+
'min': minDeposit,
|
337
|
+
'max': undefined,
|
338
|
+
},
|
339
|
+
'withdraw': {
|
340
|
+
'min': minWithdraw,
|
341
|
+
},
|
342
|
+
},
|
343
|
+
};
|
344
|
+
}
|
345
|
+
return result;
|
346
|
+
}
|
347
|
+
|
348
|
+
async fetchFundingFees (codes = undefined, params = {}) {
|
349
|
+
// by default it will try load withdrawal fees of all currencies (with separate requests)
|
350
|
+
// however if you define codes = [ 'ETH', 'BTC' ] in args it will only load those
|
351
|
+
await this.loadMarkets ();
|
352
|
+
const withdrawFees = {};
|
353
|
+
const depositFees = {};
|
354
|
+
const info = {};
|
355
|
+
if (codes === undefined) {
|
356
|
+
codes = Object.keys (this.currencies);
|
357
|
+
}
|
358
|
+
for (let i = 0; i < codes.length; i++) {
|
359
|
+
const code = codes[i];
|
360
|
+
const currency = this.currency (code);
|
361
|
+
const request = { 'currency': currency['id'] };
|
362
|
+
const withdrawResponse = await this.publicGetCurrenciesCurrencyFeesWithdrawal (request);
|
363
|
+
const depositResponse = await this.publicGetCurrenciesCurrencyFeesDeposit (request);
|
364
|
+
withdrawFees[code] = this.parseFundingFee (withdrawResponse['fee']);
|
365
|
+
depositFees[code] = this.parseFundingFee (depositResponse['fee']);
|
366
|
+
info[code] = {
|
367
|
+
'withdraw': withdrawResponse,
|
368
|
+
'deposit': depositResponse,
|
369
|
+
};
|
370
|
+
}
|
371
|
+
return {
|
372
|
+
'withdraw': withdrawFees,
|
373
|
+
'deposit': depositFees,
|
374
|
+
'info': info,
|
375
|
+
};
|
376
|
+
}
|
377
|
+
|
378
|
+
parseFundingFee (fee, type = undefined) {
|
379
|
+
if (type === undefined) {
|
380
|
+
type = fee['name'];
|
381
|
+
}
|
382
|
+
if (type === 'withdrawal') {
|
383
|
+
type = 'withdraw';
|
384
|
+
}
|
385
|
+
return {
|
386
|
+
'type': type,
|
387
|
+
'currency': fee['base'][1],
|
388
|
+
'rate': fee['percent'],
|
389
|
+
'cost': parseFloat (fee['base'][0]),
|
390
|
+
};
|
391
|
+
}
|
392
|
+
|
393
|
+
async fetchTicker (symbol, params = {}) {
|
394
|
+
await this.loadMarkets ();
|
395
|
+
const market = this.market (symbol);
|
396
|
+
const request = {
|
397
|
+
'market': market['id'],
|
398
|
+
};
|
399
|
+
const response = await this.publicGetMarketsMarketTicker (this.extend (request, params));
|
400
|
+
//
|
401
|
+
// {
|
402
|
+
// "ticker":{
|
403
|
+
// "market_id":"ETH-BTC",
|
404
|
+
// "last_price":["0.07300001","BTC"],
|
405
|
+
// "min_ask":["0.07716895","BTC"],
|
406
|
+
// "max_bid":["0.0754966","BTC"],
|
407
|
+
// "volume":["0.168965697","ETH"],
|
408
|
+
// "price_variation_24h":"-0.046",
|
409
|
+
// "price_variation_7d":"-0.085"
|
410
|
+
// }
|
411
|
+
// }
|
412
|
+
//
|
413
|
+
const ticker = this.safeValue (response, 'ticker');
|
414
|
+
return this.parseTicker (ticker, market);
|
415
|
+
}
|
416
|
+
|
417
|
+
parseTicker (ticker, market = undefined) {
|
418
|
+
//
|
419
|
+
// fetchTicker
|
420
|
+
//
|
421
|
+
// {
|
422
|
+
// "market_id":"ETH-BTC",
|
423
|
+
// "last_price":["0.07300001","BTC"],
|
424
|
+
// "min_ask":["0.07716895","BTC"],
|
425
|
+
// "max_bid":["0.0754966","BTC"],
|
426
|
+
// "volume":["0.168965697","ETH"],
|
427
|
+
// "price_variation_24h":"-0.046",
|
428
|
+
// "price_variation_7d":"-0.085"
|
429
|
+
// }
|
430
|
+
//
|
431
|
+
const timestamp = this.milliseconds ();
|
432
|
+
const marketId = this.safeString (ticker, 'market_id');
|
433
|
+
const symbol = this.safeSymbol (marketId, market, '-');
|
434
|
+
const lastPrice = this.safeValue (ticker, 'last_price', []);
|
435
|
+
const last = this.safeString (lastPrice, 0);
|
436
|
+
let percentage = this.safeString (ticker, 'price_variation_24h');
|
437
|
+
percentage = Precise.stringMul (percentage, '100');
|
438
|
+
const maxBid = this.safeValue (ticker, 'max_bid', []);
|
439
|
+
const minAsk = this.safeValue (ticker, 'min_ask', []);
|
440
|
+
const baseVolume = this.safeValue (ticker, 'volume', []);
|
441
|
+
return this.safeTicker ({
|
442
|
+
'symbol': symbol,
|
443
|
+
'timestamp': timestamp,
|
444
|
+
'datetime': this.iso8601 (timestamp),
|
445
|
+
'high': undefined,
|
446
|
+
'low': undefined,
|
447
|
+
'bid': this.safeString (maxBid, 0),
|
448
|
+
'bidVolume': undefined,
|
449
|
+
'ask': this.safeString (minAsk, 0),
|
450
|
+
'askVolume': undefined,
|
451
|
+
'vwap': undefined,
|
452
|
+
'open': undefined,
|
453
|
+
'close': last,
|
454
|
+
'last': last,
|
455
|
+
'previousClose': undefined,
|
456
|
+
'change': undefined,
|
457
|
+
'percentage': percentage,
|
458
|
+
'average': undefined,
|
459
|
+
'baseVolume': this.safeString (baseVolume, 0),
|
460
|
+
'quoteVolume': undefined,
|
461
|
+
'info': ticker,
|
462
|
+
}, market, false);
|
463
|
+
}
|
464
|
+
|
465
|
+
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
|
466
|
+
await this.loadMarkets ();
|
467
|
+
const market = this.market (symbol);
|
468
|
+
const request = {
|
469
|
+
'market': market['id'],
|
470
|
+
};
|
471
|
+
// the since argument works backwards – returns trades up to the specified timestamp
|
472
|
+
// therefore not implemented here
|
473
|
+
// the method is still available for users to be able to traverse backwards in time
|
474
|
+
// by using the timestamp from the first received trade upon each iteration
|
475
|
+
if (limit !== undefined) {
|
476
|
+
request['limit'] = limit; // 50 max
|
477
|
+
}
|
478
|
+
const response = await this.publicGetMarketsMarketTrades (this.extend (request, params));
|
479
|
+
//
|
480
|
+
// { trades: { market_id: "ETH-BTC",
|
481
|
+
// timestamp: null,
|
482
|
+
// last_timestamp: "1536901277302",
|
483
|
+
// entries: [ [ "1540077456791", "0.0063767", "0.03", "sell", 479842 ],
|
484
|
+
// [ "1539916642772", "0.01888263", "0.03019563", "sell", 479438 ],
|
485
|
+
// [ "1539834081787", "0.023718648", "0.031001", "sell", 479069 ],
|
486
|
+
// ... ]
|
487
|
+
//
|
488
|
+
return this.parseTrades (response['trades']['entries'], market, since, limit);
|
489
|
+
}
|
490
|
+
|
491
|
+
parseTrade (trade, market = undefined) {
|
492
|
+
//
|
493
|
+
// fetchTrades (public)
|
494
|
+
// [ "1540077456791", "0.0063767", "0.03", "sell", 479842 ]
|
495
|
+
//
|
496
|
+
let timestamp = undefined;
|
497
|
+
let side = undefined;
|
498
|
+
const type = undefined;
|
499
|
+
let priceString = undefined;
|
500
|
+
let amountString = undefined;
|
501
|
+
let id = undefined;
|
502
|
+
const order = undefined;
|
503
|
+
const fee = undefined;
|
504
|
+
let symbol = undefined;
|
505
|
+
if (market) {
|
506
|
+
symbol = market['symbol'];
|
507
|
+
}
|
508
|
+
if (Array.isArray (trade)) {
|
509
|
+
timestamp = this.safeInteger (trade, 0);
|
510
|
+
priceString = this.safeString (trade, 1);
|
511
|
+
amountString = this.safeString (trade, 2);
|
512
|
+
side = this.safeString (trade, 3);
|
513
|
+
id = this.safeString (trade, 4);
|
514
|
+
}
|
515
|
+
return this.safeTrade ({
|
516
|
+
'id': id,
|
517
|
+
'order': order,
|
518
|
+
'info': trade,
|
519
|
+
'timestamp': timestamp,
|
520
|
+
'datetime': this.iso8601 (timestamp),
|
521
|
+
'symbol': symbol,
|
522
|
+
'type': type,
|
523
|
+
'side': side,
|
524
|
+
'takerOrMaker': undefined,
|
525
|
+
'price': priceString,
|
526
|
+
'amount': amountString,
|
527
|
+
'cost': undefined,
|
528
|
+
'fee': fee,
|
529
|
+
}, market);
|
530
|
+
}
|
531
|
+
|
532
|
+
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
533
|
+
await this.loadMarkets ();
|
534
|
+
const market = this.market (symbol);
|
535
|
+
const request = {
|
536
|
+
'market': market['id'],
|
537
|
+
};
|
538
|
+
const response = await this.publicGetMarketsMarketOrderBook (this.extend (request, params));
|
539
|
+
const orderbook = this.safeValue (response, 'order_book');
|
540
|
+
return this.parseOrderBook (orderbook, symbol);
|
541
|
+
}
|
542
|
+
|
543
|
+
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
544
|
+
await this.loadMarkets ();
|
545
|
+
const market = this.market (symbol);
|
546
|
+
if (since === undefined) {
|
547
|
+
since = this.milliseconds () - 86400000;
|
548
|
+
}
|
549
|
+
const request = {
|
550
|
+
'symbol': market['id'],
|
551
|
+
'resolution': this.timeframes[timeframe],
|
552
|
+
'from': since / 1000,
|
553
|
+
'to': this.seconds (),
|
554
|
+
};
|
555
|
+
const response = await this.publicGetTvHistory (this.extend (request, params));
|
556
|
+
return this.parseTradingViewOHLCV (response, market, timeframe, since, limit);
|
557
|
+
}
|
558
|
+
|
559
|
+
parseBalance (response) {
|
560
|
+
const result = { 'info': response };
|
561
|
+
const balances = this.safeValue (response, 'balances');
|
562
|
+
for (let i = 0; i < balances.length; i++) {
|
563
|
+
const balance = balances[i];
|
564
|
+
const currencyId = this.safeString (balance, 'id');
|
565
|
+
const code = this.safeCurrencyCode (currencyId);
|
566
|
+
const account = this.account ();
|
567
|
+
account['free'] = this.safeString (balance['available_amount'], 0);
|
568
|
+
account['total'] = this.safeString (balance['amount'], 0);
|
569
|
+
result[code] = account;
|
570
|
+
}
|
571
|
+
return this.safeBalance (result);
|
572
|
+
}
|
573
|
+
|
574
|
+
async fetchBalance (params = {}) {
|
575
|
+
await this.loadMarkets ();
|
576
|
+
const response = await this.privateGetBalances (params);
|
577
|
+
return this.parseBalance (response);
|
578
|
+
}
|
579
|
+
|
580
|
+
async fetchOrder (id, symbol = undefined, params = {}) {
|
581
|
+
await this.loadMarkets ();
|
582
|
+
const request = {
|
583
|
+
'id': parseInt (id),
|
584
|
+
};
|
585
|
+
const response = await this.privateGetOrdersId (this.extend (request, params));
|
586
|
+
const order = this.safeValue (response, 'order');
|
587
|
+
return this.parseOrder (order);
|
588
|
+
}
|
589
|
+
|
590
|
+
async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
591
|
+
await this.loadMarkets ();
|
592
|
+
let market = undefined;
|
593
|
+
if (symbol !== undefined) {
|
594
|
+
market = this.market (symbol);
|
595
|
+
}
|
596
|
+
const request = {
|
597
|
+
'market': market['id'],
|
598
|
+
'per': limit,
|
599
|
+
};
|
600
|
+
const response = await this.privateGetMarketsMarketOrders (this.extend (request, params));
|
601
|
+
const orders = this.safeValue (response, 'orders');
|
602
|
+
return this.parseOrders (orders, market, since, limit);
|
603
|
+
}
|
604
|
+
|
605
|
+
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
606
|
+
const request = {
|
607
|
+
'state': 'pending',
|
608
|
+
};
|
609
|
+
return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
|
610
|
+
}
|
611
|
+
|
612
|
+
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
613
|
+
const request = {
|
614
|
+
'state': 'traded',
|
615
|
+
};
|
616
|
+
return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
|
617
|
+
}
|
618
|
+
|
619
|
+
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
620
|
+
await this.loadMarkets ();
|
621
|
+
side = (side === 'buy') ? 'Bid' : 'Ask';
|
622
|
+
const request = {
|
623
|
+
'market': this.marketId (symbol),
|
624
|
+
'price_type': type,
|
625
|
+
'type': side,
|
626
|
+
'amount': this.amountToPrecision (symbol, amount),
|
627
|
+
};
|
628
|
+
if (type === 'limit') {
|
629
|
+
request['limit'] = this.priceToPrecision (symbol, price);
|
630
|
+
}
|
631
|
+
const response = await this.privatePostMarketsMarketOrders (this.extend (request, params));
|
632
|
+
const order = this.safeValue (response, 'order');
|
633
|
+
return this.parseOrder (order);
|
634
|
+
}
|
635
|
+
|
636
|
+
async cancelOrder (id, symbol = undefined, params = {}) {
|
637
|
+
await this.loadMarkets ();
|
638
|
+
const request = {
|
639
|
+
'id': parseInt (id),
|
640
|
+
'state': 'canceling',
|
641
|
+
};
|
642
|
+
const response = await this.privatePutOrdersId (this.extend (request, params));
|
643
|
+
const order = this.safeValue (response, 'order');
|
644
|
+
return this.parseOrder (order);
|
645
|
+
}
|
646
|
+
|
647
|
+
parseOrderStatus (status) {
|
648
|
+
const statuses = {
|
649
|
+
'traded': 'closed',
|
650
|
+
'received': 'open',
|
651
|
+
'canceling': 'canceled',
|
652
|
+
};
|
653
|
+
return this.safeString (statuses, status, status);
|
654
|
+
}
|
655
|
+
|
656
|
+
parseOrder (order, market = undefined) {
|
657
|
+
//
|
658
|
+
// {
|
659
|
+
// 'id': 63679183,
|
660
|
+
// 'uuid': 'f9697bee-627e-4175-983f-0d5a41963fec',
|
661
|
+
// 'market_id': 'ETH-CLP',
|
662
|
+
// 'account_id': 51590,
|
663
|
+
// 'type': 'Ask',
|
664
|
+
// 'state': 'received',
|
665
|
+
// 'created_at': '2021-01-04T08:29:52.730Z',
|
666
|
+
// 'fee_currency': 'CLP',
|
667
|
+
// 'price_type': 'limit',
|
668
|
+
// 'source': None,
|
669
|
+
// 'limit': ['741000.0', 'CLP'],
|
670
|
+
// 'amount': ['0.001', 'ETH'],
|
671
|
+
// 'original_amount': ['0.001', 'ETH'],
|
672
|
+
// 'traded_amount': ['0.0', 'ETH'],
|
673
|
+
// 'total_exchanged': ['0.0', 'CLP'],
|
674
|
+
// 'paid_fee': ['0.0', 'CLP']
|
675
|
+
// }
|
676
|
+
//
|
677
|
+
const id = this.safeString (order, 'id');
|
678
|
+
const timestamp = this.parse8601 (this.safeString (order, 'created_at'));
|
679
|
+
const datetime = this.iso8601 (timestamp);
|
680
|
+
const marketId = this.safeString (order, 'market_id');
|
681
|
+
const symbol = this.safeSymbol (marketId, market, '-');
|
682
|
+
const type = this.safeString (order, 'price_type');
|
683
|
+
const side = this.safeStringLower (order, 'type');
|
684
|
+
const status = this.parseOrderStatus (this.safeString (order, 'state'));
|
685
|
+
const originalAmount = this.safeValue (order, 'original_amount', []);
|
686
|
+
const amount = this.safeString (originalAmount, 0);
|
687
|
+
const remainingAmount = this.safeValue (order, 'amount', []);
|
688
|
+
const remaining = this.safeString (remainingAmount, 0);
|
689
|
+
const tradedAmount = this.safeValue (order, 'traded_amount', []);
|
690
|
+
const filled = this.safeString (tradedAmount, 0);
|
691
|
+
const totalExchanged = this.safeValue (order, 'totalExchanged', []);
|
692
|
+
const cost = this.safeString (totalExchanged, 0);
|
693
|
+
const limitPrice = this.safeValue (order, 'limit', []);
|
694
|
+
let price = this.safeString (limitPrice, 0);
|
695
|
+
if (price === undefined) {
|
696
|
+
if (limitPrice !== undefined) {
|
697
|
+
price = limitPrice;
|
698
|
+
}
|
699
|
+
}
|
700
|
+
const paidFee = this.safeValue (order, 'paid_fee', []);
|
701
|
+
const feeCost = this.safeString (paidFee, 0);
|
702
|
+
let fee = undefined;
|
703
|
+
if (feeCost !== undefined) {
|
704
|
+
const feeCurrencyId = this.safeString (paidFee, 1);
|
705
|
+
const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
|
706
|
+
fee = {
|
707
|
+
'cost': feeCost,
|
708
|
+
'code': feeCurrencyCode,
|
709
|
+
};
|
710
|
+
}
|
711
|
+
return this.safeOrder ({
|
712
|
+
'info': order,
|
713
|
+
'id': id,
|
714
|
+
'clientOrderId': undefined,
|
715
|
+
'datetime': datetime,
|
716
|
+
'timestamp': timestamp,
|
717
|
+
'lastTradeTimestamp': undefined,
|
718
|
+
'status': status,
|
719
|
+
'symbol': symbol,
|
720
|
+
'type': type,
|
721
|
+
'timeInForce': undefined,
|
722
|
+
'postOnly': undefined,
|
723
|
+
'side': side,
|
724
|
+
'price': price,
|
725
|
+
'stopPrice': undefined,
|
726
|
+
'average': undefined,
|
727
|
+
'cost': cost,
|
728
|
+
'amount': amount,
|
729
|
+
'filled': filled,
|
730
|
+
'remaining': remaining,
|
731
|
+
'trades': undefined,
|
732
|
+
'fee': fee,
|
733
|
+
}, market);
|
734
|
+
}
|
735
|
+
|
736
|
+
isFiat (code) {
|
737
|
+
const fiats = {
|
738
|
+
'ARS': true,
|
739
|
+
'CLP': true,
|
740
|
+
'COP': true,
|
741
|
+
'PEN': true,
|
742
|
+
};
|
743
|
+
return this.safeValue (fiats, code, false);
|
744
|
+
}
|
745
|
+
|
746
|
+
async fetchDepositAddress (code, params = {}) {
|
747
|
+
await this.loadMarkets ();
|
748
|
+
const currency = this.currency (code);
|
749
|
+
if (this.isFiat (code)) {
|
750
|
+
throw new NotSupported (this.id + ' fetchDepositAddress() for fiat ' + code + ' is not supported');
|
751
|
+
}
|
752
|
+
const request = {
|
753
|
+
'currency': currency['id'],
|
754
|
+
};
|
755
|
+
const response = await this.privateGetCurrenciesCurrencyReceiveAddresses (this.extend (request, params));
|
756
|
+
const receiveAddresses = this.safeValue (response, 'receive_addresses');
|
757
|
+
const addressPool = [];
|
758
|
+
for (let i = 1; i < receiveAddresses.length; i++) {
|
759
|
+
const receiveAddress = receiveAddresses[i];
|
760
|
+
if (receiveAddress['ready']) {
|
761
|
+
const address = receiveAddress['address'];
|
762
|
+
this.checkAddress (address);
|
763
|
+
addressPool.push (address);
|
764
|
+
}
|
765
|
+
}
|
766
|
+
const addressPoolLength = addressPool.length;
|
767
|
+
if (addressPoolLength < 1) {
|
768
|
+
throw new AddressPending (this.id + ': there are no addresses ready for receiving ' + code + ', retry again later)');
|
769
|
+
}
|
770
|
+
const address = addressPool[0];
|
771
|
+
return {
|
772
|
+
'currency': code,
|
773
|
+
'address': address,
|
774
|
+
'tag': undefined,
|
775
|
+
'network': undefined,
|
776
|
+
'info': receiveAddresses,
|
777
|
+
};
|
778
|
+
}
|
779
|
+
|
780
|
+
async createDepositAddress (code, params = {}) {
|
781
|
+
await this.loadMarkets ();
|
782
|
+
const currency = this.currency (code);
|
783
|
+
if (this.isFiat (code)) {
|
784
|
+
throw new NotSupported (this.id + ' fetchDepositAddress() of fiat for ' + code + ' is not supported');
|
785
|
+
}
|
786
|
+
const request = {
|
787
|
+
'currency': currency['id'],
|
788
|
+
};
|
789
|
+
const response = await this.privatePostCurrenciesCurrencyReceiveAddresses (this.extend (request, params));
|
790
|
+
const address = this.safeString (response['receive_address'], 'address'); // the creation is async and returns a null address, returns only the id
|
791
|
+
return {
|
792
|
+
'currency': code,
|
793
|
+
'address': address,
|
794
|
+
'tag': undefined,
|
795
|
+
'info': response,
|
796
|
+
};
|
797
|
+
}
|
798
|
+
|
799
|
+
parseTransactionStatus (status) {
|
800
|
+
const statuses = {
|
801
|
+
'rejected': 'failed',
|
802
|
+
'confirmed': 'ok',
|
803
|
+
'anulled': 'canceled',
|
804
|
+
'retained': 'canceled',
|
805
|
+
'pending_confirmation': 'pending',
|
806
|
+
};
|
807
|
+
return this.safeString (statuses, status, status);
|
808
|
+
}
|
809
|
+
|
810
|
+
parseTransaction (transaction, currency = undefined) {
|
811
|
+
const id = this.safeString (transaction, 'id');
|
812
|
+
const timestamp = this.parse8601 (this.safeString (transaction, 'created_at'));
|
813
|
+
const currencyId = this.safeString (transaction, 'currency');
|
814
|
+
const code = this.safeCurrencyCode (currencyId, currency);
|
815
|
+
const amount = parseFloat (transaction['amount'][0]);
|
816
|
+
const fee = parseFloat (transaction['fee'][0]);
|
817
|
+
const feeCurrency = transaction['fee'][1];
|
818
|
+
const status = this.parseTransactionStatus (this.safeString (transaction, 'state'));
|
819
|
+
const type = ('deposit_data' in transaction) ? 'deposit' : 'withdrawal';
|
820
|
+
const data = this.safeValue (transaction, type + '_data', {});
|
821
|
+
const address = this.safeValue (data, 'target_address');
|
822
|
+
const txid = this.safeString (data, 'tx_hash');
|
823
|
+
const updated = this.parse8601 (this.safeString (data, 'updated_at'));
|
824
|
+
return {
|
825
|
+
'info': transaction,
|
826
|
+
'id': id,
|
827
|
+
'txid': txid,
|
828
|
+
'timestamp': timestamp,
|
829
|
+
'datetime': this.iso8601 (timestamp),
|
830
|
+
'network': undefined,
|
831
|
+
'address': address,
|
832
|
+
'addressTo': undefined,
|
833
|
+
'addressFrom': undefined,
|
834
|
+
'tag': undefined,
|
835
|
+
'tagTo': undefined,
|
836
|
+
'tagFrom': undefined,
|
837
|
+
'type': type,
|
838
|
+
'amount': amount,
|
839
|
+
'currency': code,
|
840
|
+
'status': status,
|
841
|
+
'updated': updated,
|
842
|
+
'fee': {
|
843
|
+
'cost': fee,
|
844
|
+
'rate': feeCurrency,
|
845
|
+
},
|
846
|
+
};
|
847
|
+
}
|
848
|
+
|
849
|
+
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
850
|
+
await this.loadMarkets ();
|
851
|
+
if (code === undefined) {
|
852
|
+
throw new ArgumentsRequired (this.id + ' fetchDeposits() requires a currency code argument');
|
853
|
+
}
|
854
|
+
const currency = this.currency (code);
|
855
|
+
const request = {
|
856
|
+
'currency': currency['id'],
|
857
|
+
'per': limit,
|
858
|
+
};
|
859
|
+
const response = await this.privateGetCurrenciesCurrencyDeposits (this.extend (request, params));
|
860
|
+
const deposits = this.safeValue (response, 'deposits');
|
861
|
+
return this.parseTransactions (deposits, currency, since, limit);
|
862
|
+
}
|
863
|
+
|
864
|
+
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
865
|
+
await this.loadMarkets ();
|
866
|
+
if (code === undefined) {
|
867
|
+
throw new ArgumentsRequired (this.id + ' fetchDeposits() requires a currency code argument');
|
868
|
+
}
|
869
|
+
const currency = this.currency (code);
|
870
|
+
const request = {
|
871
|
+
'currency': currency['id'],
|
872
|
+
'per': limit,
|
873
|
+
};
|
874
|
+
const response = await this.privateGetCurrenciesCurrencyWithdrawals (this.extend (request, params));
|
875
|
+
const withdrawals = this.safeValue (response, 'withdrawals');
|
876
|
+
return this.parseTransactions (withdrawals, currency, since, limit);
|
877
|
+
}
|
878
|
+
|
879
|
+
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
880
|
+
[ tag, params ] = this.handleWithdrawTagAndParams (tag, params);
|
881
|
+
this.checkAddress (address);
|
882
|
+
await this.loadMarkets ();
|
883
|
+
const currency = this.currency (code);
|
884
|
+
const request = {
|
885
|
+
'currency': currency['id'],
|
886
|
+
'amount': amount,
|
887
|
+
'withdrawal_data': {
|
888
|
+
'target_address': address,
|
889
|
+
},
|
890
|
+
};
|
891
|
+
const response = await this.privatePostCurrenciesCurrencyWithdrawals (this.extend (request, params));
|
892
|
+
const withdrawal = this.safeValue (response, 'withdrawal');
|
893
|
+
return this.parseTransaction (withdrawal);
|
894
|
+
}
|
895
|
+
|
896
|
+
nonce () {
|
897
|
+
return this.microseconds ();
|
898
|
+
}
|
899
|
+
|
900
|
+
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
901
|
+
let request = this.implodeParams (path, params);
|
902
|
+
const query = this.omit (params, this.extractParams (path));
|
903
|
+
if (Object.keys (query).length) {
|
904
|
+
if (method === 'GET') {
|
905
|
+
request += '?' + this.urlencode (query);
|
906
|
+
} else {
|
907
|
+
body = this.json (query);
|
908
|
+
}
|
909
|
+
}
|
910
|
+
const url = this.urls['api'] + '/' + this.version + '/' + request;
|
911
|
+
if (api === 'private') {
|
912
|
+
this.checkRequiredCredentials ();
|
913
|
+
const nonce = this.nonce ().toString ();
|
914
|
+
const components = [ method, '/api/' + this.version + '/' + request ];
|
915
|
+
if (body) {
|
916
|
+
const base64Body = this.stringToBase64 (body);
|
917
|
+
components.push (this.decode (base64Body));
|
918
|
+
}
|
919
|
+
components.push (nonce);
|
920
|
+
const message = components.join (' ');
|
921
|
+
const signature = this.hmac (this.encode (message), this.encode (this.secret), 'sha384');
|
922
|
+
headers = {
|
923
|
+
'X-SBTC-APIKEY': this.apiKey,
|
924
|
+
'X-SBTC-SIGNATURE': signature,
|
925
|
+
'X-SBTC-NONCE': nonce,
|
926
|
+
'Content-Type': 'application/json',
|
927
|
+
};
|
928
|
+
}
|
929
|
+
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
930
|
+
}
|
931
|
+
|
932
|
+
handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
933
|
+
if (response === undefined) {
|
934
|
+
return; // fallback to default error handler
|
935
|
+
}
|
936
|
+
if (code >= 400) {
|
937
|
+
const errorCode = this.safeString (response, 'code');
|
938
|
+
const message = this.safeString (response, 'message', body);
|
939
|
+
const feedback = this.id + ' ' + message;
|
940
|
+
if (errorCode !== undefined) {
|
941
|
+
this.throwExactlyMatchedException (this.exceptions, errorCode, feedback);
|
942
|
+
throw new ExchangeError (feedback);
|
943
|
+
}
|
944
|
+
}
|
945
|
+
}
|
946
|
+
};
|