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
@@ -0,0 +1,520 @@
|
|
1
|
+
// ----------------------------------------------------------------------------
|
2
|
+
// Usage:
|
3
|
+
//
|
4
|
+
// npm run export-exchanges
|
5
|
+
// ----------------------------------------------------------------------------
|
6
|
+
|
7
|
+
"use strict";
|
8
|
+
|
9
|
+
const fs = require ('fs')
|
10
|
+
, countries = require ('./countries')
|
11
|
+
, asTable = require ('as-table').configure ({
|
12
|
+
delimiter: '|',
|
13
|
+
print: (x) => ' ' + x + ' '
|
14
|
+
})
|
15
|
+
, execSync = require ('child_process').execSync
|
16
|
+
, log = require ('ololog').unlimited
|
17
|
+
, ansi = require ('ansicolor').nice
|
18
|
+
, { keys, values, entries, fromEntries } = Object
|
19
|
+
, { replaceInFile } = require ('./fs.js')
|
20
|
+
|
21
|
+
// ----------------------------------------------------------------------------
|
22
|
+
|
23
|
+
function cloneGitHubWiki (gitWikiPath) {
|
24
|
+
|
25
|
+
if (!fs.existsSync (gitWikiPath)) {
|
26
|
+
log.bright.cyan ('Cloning ccxt.wiki...')
|
27
|
+
execSync ('git clone https://github.com/ccxt/ccxt.wiki.git ' + gitWikiPath)
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
// ----------------------------------------------------------------------------
|
32
|
+
|
33
|
+
function logExportExchanges (filename, regex, replacement) {
|
34
|
+
log.bright.cyan ('Exporting exchanges →', filename.yellow)
|
35
|
+
replaceInFile (filename, regex, replacement)
|
36
|
+
}
|
37
|
+
|
38
|
+
// ----------------------------------------------------------------------------
|
39
|
+
|
40
|
+
function getIncludedExchangeIds () {
|
41
|
+
|
42
|
+
const includedIds = fs.readFileSync ('exchanges.cfg')
|
43
|
+
.toString () // Buffer → String
|
44
|
+
.split ('\n') // String → Array
|
45
|
+
.map (line => line.split ('#')[0].trim ()) // trim comments
|
46
|
+
.filter (exchange => exchange); // filter empty lines
|
47
|
+
|
48
|
+
const isIncluded = (id) => ((includedIds.length === 0) || includedIds.includes (id))
|
49
|
+
|
50
|
+
const ids = fs.readdirSync ('./js/')
|
51
|
+
.filter (file => file.match (/[a-zA-Z0-9_-]+.js$/))
|
52
|
+
.map (file => file.slice (0, -3))
|
53
|
+
.filter (isIncluded);
|
54
|
+
|
55
|
+
return ids
|
56
|
+
}
|
57
|
+
|
58
|
+
// ----------------------------------------------------------------------------
|
59
|
+
|
60
|
+
function exportExchanges (replacements) {
|
61
|
+
|
62
|
+
log.bright.yellow ('Exporting exchanges...')
|
63
|
+
|
64
|
+
replacements.forEach (({ file, regex, replacement }) => {
|
65
|
+
logExportExchanges (file, regex, replacement)
|
66
|
+
})
|
67
|
+
|
68
|
+
log.bright.green ('Base sources updated successfully.')
|
69
|
+
}
|
70
|
+
|
71
|
+
// ----------------------------------------------------------------------------
|
72
|
+
|
73
|
+
function createExchanges (ids) {
|
74
|
+
|
75
|
+
const ccxt = require ('../ccxt.js')
|
76
|
+
|
77
|
+
const createExchange = (id) => {
|
78
|
+
ccxt[id].prototype.checkRequiredDependencies = () => {} // suppress it
|
79
|
+
return new (ccxt)[id] ()
|
80
|
+
}
|
81
|
+
|
82
|
+
return ccxt.indexBy (ids.map (createExchange), 'id')
|
83
|
+
}
|
84
|
+
|
85
|
+
// ----------------------------------------------------------------------------
|
86
|
+
|
87
|
+
const ccxtCertifiedBadge = '[](https://github.com/ccxt/ccxt/wiki/Certification)'
|
88
|
+
, ccxtProBadge = '[](https://ccxt.pro)'
|
89
|
+
|
90
|
+
// ----------------------------------------------------------------------------
|
91
|
+
|
92
|
+
function getFirstWebsiteUrl (exchange) {
|
93
|
+
return Array.isArray (exchange.urls.www) ? exchange.urls.www[0] : exchange.urls.www
|
94
|
+
}
|
95
|
+
|
96
|
+
// ----------------------------------------------------------------------------
|
97
|
+
|
98
|
+
function getReferralUrlOrWebsiteUrl (exchange) {
|
99
|
+
return exchange.urls.referral ?
|
100
|
+
(exchange.urls.referral.url ? exchange.urls.referral.url : exchange.urls.referral) :
|
101
|
+
getFirstWebsiteUrl (exchange)
|
102
|
+
}
|
103
|
+
|
104
|
+
// ----------------------------------------------------------------------------
|
105
|
+
|
106
|
+
function getReferralDiscountBadgeLink (exchange) {
|
107
|
+
const url = getReferralUrlOrWebsiteUrl (exchange)
|
108
|
+
if (exchange.urls.referral && exchange.urls.referral.discount) {
|
109
|
+
const discountPercentage = parseInt (exchange.urls.referral.discount * 100)
|
110
|
+
|
111
|
+
// this badge does not work with a minus sign
|
112
|
+
// const badge = '(https://img.shields.io/badge/fee-%2D' + discountPercentage.toString () + '%25-yellow)'
|
113
|
+
|
114
|
+
const badge = '(https://img.shields.io/static/v1?label=Fee&message=%2d' + discountPercentage.toString () + '%25&color=orange)'
|
115
|
+
const alt = "![Sign up with " + exchange.name + " using CCXT's referral link for a " + discountPercentage.toString () + "% discount!]"
|
116
|
+
return '[' + alt + badge + '](' + url + ')'
|
117
|
+
} else {
|
118
|
+
return ''
|
119
|
+
}
|
120
|
+
}
|
121
|
+
|
122
|
+
// ----------------------------------------------------------------------------
|
123
|
+
|
124
|
+
function getFirstDocUrl (exchange) {
|
125
|
+
return Array.isArray (exchange.urls.doc) ? exchange.urls.doc[0] : exchange.urls.doc
|
126
|
+
}
|
127
|
+
|
128
|
+
// ----------------------------------------------------------------------------
|
129
|
+
|
130
|
+
|
131
|
+
function getVersion (exchange) {
|
132
|
+
return exchange.version ? exchange.version.replace (/[^0-9\.]+/, '') : '\*'
|
133
|
+
}
|
134
|
+
|
135
|
+
// ----------------------------------------------------------------------------
|
136
|
+
|
137
|
+
function getVersionLink (exchange) {
|
138
|
+
const version = getVersion (exchange)
|
139
|
+
, doc = getFirstDocUrl (exchange)
|
140
|
+
return '[' + version + '](' + doc + ')'
|
141
|
+
}
|
142
|
+
|
143
|
+
// ----------------------------------------------------------------------------
|
144
|
+
|
145
|
+
function getVersionBadge (exchange) {
|
146
|
+
const version = getVersion (exchange)
|
147
|
+
, doc = getFirstDocUrl (exchange)
|
148
|
+
return '[](' + doc + ')'
|
149
|
+
}
|
150
|
+
|
151
|
+
// ----------------------------------------------------------------------------
|
152
|
+
|
153
|
+
function createMarkdownExchange (exchange) {
|
154
|
+
const url = getReferralUrlOrWebsiteUrl (exchange)
|
155
|
+
return {
|
156
|
+
'logo': '[](' + url + ')',
|
157
|
+
'id': exchange.id,
|
158
|
+
'name': '[' + exchange.name + '](' + url + ')',
|
159
|
+
'ver': getVersionBadge (exchange),
|
160
|
+
'certified': exchange.certified ? ccxtCertifiedBadge : '',
|
161
|
+
'pro': exchange.pro ? ccxtProBadge : '',
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
// ----------------------------------------------------------------------------
|
166
|
+
|
167
|
+
function createMarkdownListOfExchanges (exchanges) {
|
168
|
+
return exchanges.map ((exchange) => createMarkdownExchange (exchange))
|
169
|
+
}
|
170
|
+
|
171
|
+
// ----------------------------------------------------------------------------
|
172
|
+
|
173
|
+
function createMarkdownListOfCertifiedExchanges (exchanges) {
|
174
|
+
return exchanges.map ((exchange) => {
|
175
|
+
const discount = getReferralDiscountBadgeLink (exchange)
|
176
|
+
return { ... createMarkdownExchange (exchange), discount }
|
177
|
+
})
|
178
|
+
}
|
179
|
+
|
180
|
+
// ----------------------------------------------------------------------------
|
181
|
+
|
182
|
+
const sortByCountry = (a, b) => {
|
183
|
+
if (a['country / region'] > b['country / region']) {
|
184
|
+
return 1
|
185
|
+
} else if (a['country / region'] < b['country / region']) {
|
186
|
+
return -1;
|
187
|
+
} else {
|
188
|
+
if (a['id'] > b['id']) {
|
189
|
+
return 1;
|
190
|
+
} else if (a['id'] < b['id']) {
|
191
|
+
return -1;
|
192
|
+
} else {
|
193
|
+
return 0;
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
// ----------------------------------------------------------------------------
|
199
|
+
|
200
|
+
function createMarkdownListOfExchangesByCountries (exchanges) {
|
201
|
+
|
202
|
+
const exchangesByCountries = []
|
203
|
+
|
204
|
+
keys (countries).forEach (code => {
|
205
|
+
|
206
|
+
exchanges.forEach (exchange => {
|
207
|
+
|
208
|
+
const exchangeInCountry =
|
209
|
+
(Array.isArray (exchange.countries) && exchange.countries.includes (code)) ||
|
210
|
+
(code === exchange.countries)
|
211
|
+
|
212
|
+
if (exchangeInCountry) {
|
213
|
+
|
214
|
+
const { logo, id, name, ver } = createMarkdownExchange (exchange)
|
215
|
+
|
216
|
+
exchangesByCountries.push ({
|
217
|
+
'country / region': countries[code],
|
218
|
+
logo,
|
219
|
+
id,
|
220
|
+
name,
|
221
|
+
ver,
|
222
|
+
})
|
223
|
+
}
|
224
|
+
})
|
225
|
+
});
|
226
|
+
|
227
|
+
return exchangesByCountries.sort (sortByCountry)
|
228
|
+
}
|
229
|
+
|
230
|
+
// ----------------------------------------------------------------------------
|
231
|
+
|
232
|
+
function createMarkdownTable (array, markdownMethod, centeredColumns) {
|
233
|
+
|
234
|
+
array = markdownMethod (array)
|
235
|
+
|
236
|
+
const table = asTable (array)
|
237
|
+
const lines = table.split ("\n")
|
238
|
+
|
239
|
+
//
|
240
|
+
// asTable creates a header underline like
|
241
|
+
//
|
242
|
+
// logo | id | name | version | certified | pro
|
243
|
+
// ----------------------------------------------
|
244
|
+
//
|
245
|
+
// we fix it to match markdown underline like
|
246
|
+
//
|
247
|
+
// logo | id | name | version | certified | pro
|
248
|
+
// ------|----|------|---------|-----------|-----
|
249
|
+
//
|
250
|
+
|
251
|
+
const underline = lines[0].replace (/[^\|]/g, '-')
|
252
|
+
|
253
|
+
//
|
254
|
+
// ver and doc columns should be centered so we convert it to
|
255
|
+
//
|
256
|
+
// logo | id | name | version | certified | pro
|
257
|
+
// ------|----|------|:-------:|-----------|-----
|
258
|
+
//
|
259
|
+
|
260
|
+
const columns = underline.split ('|')
|
261
|
+
for (const i of centeredColumns) {
|
262
|
+
columns[i] = ':' + columns[i].slice (1, columns[i].length - 1) + ':'
|
263
|
+
}
|
264
|
+
|
265
|
+
lines.splice (1, 1, columns.join ('|'))
|
266
|
+
|
267
|
+
//
|
268
|
+
// prepend and append a vertical bar to each line
|
269
|
+
//
|
270
|
+
// | logo | id | name | version | certified | pro |
|
271
|
+
// |------|----|------|:-------:|-----------|-----|
|
272
|
+
//
|
273
|
+
|
274
|
+
return lines.map (line => '|' + line + '|').join ("\n")
|
275
|
+
}
|
276
|
+
|
277
|
+
// ----------------------------------------------------------------------------
|
278
|
+
|
279
|
+
function exportSupportedAndCertifiedExchanges (exchanges, { allExchangesPaths, certifiedExchangesPaths, exchangesByCountriesPaths, proExchangesPaths }) {
|
280
|
+
|
281
|
+
// const aliases = [ 'hitbtc2', 'huobipro' ] // aliases are not shown tables for deduplication
|
282
|
+
|
283
|
+
const arrayOfExchanges = values (exchanges).filter (exchange => !exchange.alias)
|
284
|
+
const numExchanges = arrayOfExchanges.length
|
285
|
+
|
286
|
+
if (allExchangesPaths && numExchanges) {
|
287
|
+
const supportedExchangesMarkdownTable = createMarkdownTable (arrayOfExchanges, createMarkdownListOfExchanges, [ 3 ])
|
288
|
+
, beginning = "The CCXT library currently supports the following "
|
289
|
+
, ending = " cryptocurrency exchange markets and trading APIs:\n\n"
|
290
|
+
, totalString = beginning + numExchanges + ending
|
291
|
+
, allExchangesReplacement = totalString + supportedExchangesMarkdownTable + "$1"
|
292
|
+
, allExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\| logo[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
|
293
|
+
for (const path of allExchangesPaths) {
|
294
|
+
logExportExchanges (path, allExchangesRegex, allExchangesReplacement)
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
const proExchanges = arrayOfExchanges.filter (exchange => exchange.pro)
|
299
|
+
const numProExchanges = proExchanges.length
|
300
|
+
if (proExchangesPaths && numProExchanges) {
|
301
|
+
const proExchangesMarkdownTable = createMarkdownTable (proExchanges, createMarkdownListOfExchanges, [ 3 ])
|
302
|
+
, beginning = "The CCXT Pro library currently supports the following "
|
303
|
+
, ending = " cryptocurrency exchange markets and WebSocket trading APIs:\n\n"
|
304
|
+
, totalString = beginning + numProExchanges + ending
|
305
|
+
, proExchangesReplacement = totalString + proExchangesMarkdownTable + "$1"
|
306
|
+
, proExchangesRegex = new RegExp ("[^\n]+[\n]{2}\\|[^`]+\\|([\n][\n]|[\n]$|$)", 'm')
|
307
|
+
for (const path of proExchangesPaths) {
|
308
|
+
logExportExchanges (path, proExchangesRegex, proExchangesReplacement)
|
309
|
+
}
|
310
|
+
}
|
311
|
+
|
312
|
+
const certifiedExchanges = arrayOfExchanges.filter (exchange => exchange.certified)
|
313
|
+
if (certifiedExchangesPaths && certifiedExchanges.length) {
|
314
|
+
const certifiedExchangesMarkdownTable = createMarkdownTable (certifiedExchanges, createMarkdownListOfCertifiedExchanges, [ 3, 6 ])
|
315
|
+
, certifiedExchangesReplacement = '$1' + certifiedExchangesMarkdownTable + "\n"
|
316
|
+
, certifiedExchangesRegex = new RegExp ("^(## Certified Cryptocurrency Exchanges\n{3})(?:\\|.+\\|$\n)+", 'm')
|
317
|
+
for (const path of certifiedExchangesPaths) {
|
318
|
+
logExportExchanges (path, certifiedExchangesRegex, certifiedExchangesReplacement)
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
if (exchangesByCountriesPaths) {
|
323
|
+
const exchangesByCountriesMarkdownTable = createMarkdownTable (arrayOfExchanges, createMarkdownListOfExchangesByCountries, [ 4 ])
|
324
|
+
const result = "# Exchanges By Country\n\nThe ccxt library currently supports the following cryptocurrency exchange markets and trading APIs:\n\n" + exchangesByCountriesMarkdownTable + "\n\n"
|
325
|
+
for (const path of exchangesByCountriesPaths) {
|
326
|
+
fs.truncateSync (path)
|
327
|
+
fs.writeFileSync (path, result)
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
// ----------------------------------------------------------------------------
|
333
|
+
|
334
|
+
function exportExchangeIdsToExchangesJson (exchanges) {
|
335
|
+
log.bright ('Exporting exchange ids to'.cyan, 'exchanges.json'.yellow)
|
336
|
+
const ids = keys (exchanges)
|
337
|
+
console.log (ids)
|
338
|
+
fs.writeFileSync ('exchanges.json', JSON.stringify ({ ids }, null, 4))
|
339
|
+
}
|
340
|
+
|
341
|
+
// ----------------------------------------------------------------------------
|
342
|
+
|
343
|
+
function exportWikiToGitHub (wikiPath, gitWikiPath) {
|
344
|
+
|
345
|
+
log.bright.cyan ('Exporting wiki to GitHub')
|
346
|
+
|
347
|
+
const ccxtWikiFiles = {
|
348
|
+
'README.md': 'Home.md',
|
349
|
+
'Install.md': 'Install.md',
|
350
|
+
'Manual.md': 'Manual.md',
|
351
|
+
'Exchange-Markets.md': 'Exchange-Markets.md',
|
352
|
+
'Exchange-Markets-By-Country.md': 'Exchange-Markets-By-Country.md',
|
353
|
+
'ccxt.pro.md': 'ccxt.pro.md',
|
354
|
+
'ccxt.pro.install.md': 'ccxt.pro.install.md',
|
355
|
+
'ccxt.pro.manual.md': 'ccxt.pro.manual.md',
|
356
|
+
}
|
357
|
+
|
358
|
+
for (const [ sourceFile, destinationFile ] of entries (ccxtWikiFiles)) {
|
359
|
+
|
360
|
+
const sourcePath = wikiPath + '/' + sourceFile
|
361
|
+
const destinationPath = gitWikiPath + '/' + destinationFile
|
362
|
+
log.bright.cyan ('Exporting', sourcePath.yellow, '→', destinationPath.yellow)
|
363
|
+
fs.writeFileSync (destinationPath, fs.readFileSync (sourcePath))
|
364
|
+
}
|
365
|
+
}
|
366
|
+
|
367
|
+
// ----------------------------------------------------------------------------
|
368
|
+
|
369
|
+
function exportKeywordsToPackageJson (exchanges) {
|
370
|
+
|
371
|
+
log.bright ('Exporting exchange keywords to'.cyan, 'package.json'.yellow)
|
372
|
+
|
373
|
+
// const packageJSON = require ('../package.json')
|
374
|
+
const packageJSON = JSON.parse (fs.readFileSync ('./package.json'))
|
375
|
+
const keywords = new Set (packageJSON.keywords)
|
376
|
+
|
377
|
+
for (const ex of values (exchanges)) {
|
378
|
+
for (const url of Array.isArray (ex.urls.www) ? ex.urls.www : [ex.urls.www]) {
|
379
|
+
keywords.add (url.replace (/(http|https):\/\/(www\.)?/, '').replace (/\/.*/, ''))
|
380
|
+
}
|
381
|
+
keywords.add (ex.name)
|
382
|
+
}
|
383
|
+
|
384
|
+
packageJSON.keywords = values (fromEntries ([ ... keywords ].map (s => [ s.toLowerCase (), s ])));
|
385
|
+
fs.writeFileSync ('./package.json', JSON.stringify (packageJSON, null, 2) + "\n")
|
386
|
+
}
|
387
|
+
|
388
|
+
// ----------------------------------------------------------------------------
|
389
|
+
|
390
|
+
function flatten (nested, result = []) {
|
391
|
+
for (const key in nested) {
|
392
|
+
result.push (key)
|
393
|
+
if (Object.keys (nested[key]).length)
|
394
|
+
flatten (nested[key], result)
|
395
|
+
}
|
396
|
+
return result
|
397
|
+
}
|
398
|
+
|
399
|
+
// ----------------------------------------------------------------------------
|
400
|
+
|
401
|
+
function exportEverything () {
|
402
|
+
const ids = getIncludedExchangeIds ()
|
403
|
+
const errorHierarchy = require ('../js/base/errorHierarchy.js')
|
404
|
+
const flat = flatten (errorHierarchy)
|
405
|
+
flat.push ('error_hierarchy')
|
406
|
+
|
407
|
+
const replacements = [
|
408
|
+
{
|
409
|
+
file: './ccxt.js',
|
410
|
+
regex: /(?:const|var)\s+exchanges\s+\=\s+\{[^\}]+\}/,
|
411
|
+
replacement: "const exchanges = {\n" + ids.map (id => (" '" + id + "':").padEnd (30) + " require ('./js/" + id + ".js'),").join ("\n") + " \n}",
|
412
|
+
},
|
413
|
+
{
|
414
|
+
file: './python/ccxt/__init__.py',
|
415
|
+
regex: /exchanges \= \[[^\]]+\]/,
|
416
|
+
replacement: "exchanges = [\n" + " '" + ids.join ("',\n '") + "'," + "\n]",
|
417
|
+
},
|
418
|
+
{
|
419
|
+
file: './python/ccxt/__init__.py',
|
420
|
+
regex: /(?:from ccxt\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
|
421
|
+
replacement: ids.map (id => ('from ccxt.' + id + ' import ' + id).padEnd (60) + '# noqa: F401').join ("\n") + "\n\nexchanges",
|
422
|
+
},
|
423
|
+
{
|
424
|
+
file: './python/ccxt/__init__.py',
|
425
|
+
regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
|
426
|
+
replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
|
427
|
+
},
|
428
|
+
{
|
429
|
+
file: './python/ccxt/async_support/__init__.py',
|
430
|
+
regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
|
431
|
+
replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
|
432
|
+
},
|
433
|
+
{
|
434
|
+
file: './python/ccxt/async_support/__init__.py',
|
435
|
+
regex: /(?:from ccxt\.async_support\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
|
436
|
+
replacement: ids.map (id => ('from ccxt.async_support.' + id + ' import ' + id).padEnd (74) + '# noqa: F401').join ("\n") + "\n\nexchanges",
|
437
|
+
},
|
438
|
+
{
|
439
|
+
file: './python/ccxt/async_support/__init__.py',
|
440
|
+
regex: /exchanges \= \[[^\]]+\]/,
|
441
|
+
replacement: "exchanges = [\n" + " '" + ids.join ("',\n '") + "'," + "\n]",
|
442
|
+
},
|
443
|
+
{
|
444
|
+
file: './php/Exchange.php',
|
445
|
+
regex: /public static \$exchanges \= array\s*\([^\)]+\)/,
|
446
|
+
replacement: "public static $exchanges = array(\n '" + ids.join ("',\n '") + "',\n )",
|
447
|
+
},
|
448
|
+
]
|
449
|
+
|
450
|
+
exportExchanges (replacements)
|
451
|
+
|
452
|
+
// strategically placed exactly here (we can require it AFTER the export)
|
453
|
+
const exchanges = createExchanges (ids)
|
454
|
+
|
455
|
+
const wikiPath = 'wiki'
|
456
|
+
, gitWikiPath = 'build/ccxt.wiki'
|
457
|
+
|
458
|
+
cloneGitHubWiki (gitWikiPath)
|
459
|
+
|
460
|
+
exportSupportedAndCertifiedExchanges (exchanges, {
|
461
|
+
allExchangesPaths: [
|
462
|
+
'README.md',
|
463
|
+
wikiPath + '/Manual.md',
|
464
|
+
wikiPath + '/Exchange-Markets.md'
|
465
|
+
],
|
466
|
+
certifiedExchangesPaths: [
|
467
|
+
'README.md',
|
468
|
+
],
|
469
|
+
exchangesByCountriesPaths: [
|
470
|
+
wikiPath + '/Exchange-Markets-By-Country.md'
|
471
|
+
],
|
472
|
+
proExchangesPaths: [
|
473
|
+
wikiPath + '/ccxt.pro.manual.md',
|
474
|
+
],
|
475
|
+
})
|
476
|
+
|
477
|
+
exportExchangeIdsToExchangesJson (exchanges)
|
478
|
+
exportWikiToGitHub (wikiPath, gitWikiPath)
|
479
|
+
exportKeywordsToPackageJson (exchanges)
|
480
|
+
|
481
|
+
log.bright.green ('Exported successfully.')
|
482
|
+
}
|
483
|
+
|
484
|
+
// ============================================================================
|
485
|
+
// main entry point
|
486
|
+
|
487
|
+
if (require.main === module) {
|
488
|
+
|
489
|
+
// if called directly like `node module`
|
490
|
+
|
491
|
+
exportEverything ()
|
492
|
+
|
493
|
+
} else {
|
494
|
+
|
495
|
+
// do nothing if required as a module
|
496
|
+
}
|
497
|
+
|
498
|
+
// ============================================================================
|
499
|
+
|
500
|
+
module.exports = {
|
501
|
+
cloneGitHubWiki,
|
502
|
+
createExchanges,
|
503
|
+
createMarkdownExchange,
|
504
|
+
createMarkdownListOfExchanges,
|
505
|
+
createMarkdownListOfCertifiedExchanges,
|
506
|
+
createMarkdownListOfExchangesByCountries,
|
507
|
+
getFirstWebsiteUrl,
|
508
|
+
getReferralUrlOrWebsiteUrl,
|
509
|
+
getFirstDocUrl,
|
510
|
+
getVersion,
|
511
|
+
getVersionLink,
|
512
|
+
getVersionBadge,
|
513
|
+
getIncludedExchangeIds,
|
514
|
+
exportExchanges,
|
515
|
+
exportSupportedAndCertifiedExchanges,
|
516
|
+
exportExchangeIdsToExchangesJson,
|
517
|
+
exportWikiToGitHub,
|
518
|
+
exportKeywordsToPackageJson,
|
519
|
+
exportEverything,
|
520
|
+
}
|
package/build/fs.js
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
const fs = require ('fs')
|
4
|
+
, path = require ('path')
|
5
|
+
|
6
|
+
function replaceInFile (filename, regex, replacement) {
|
7
|
+
const contents = fs.readFileSync (filename, 'utf8')
|
8
|
+
const newContents = contents.replace (regex, replacement)
|
9
|
+
fs.truncateSync (filename)
|
10
|
+
fs.writeFileSync (filename, newContents)
|
11
|
+
}
|
12
|
+
|
13
|
+
function copyFile (oldName, newName) {
|
14
|
+
const contents = fs.readFileSync (oldName, 'utf8')
|
15
|
+
if (fs.existsSync (newName)) {
|
16
|
+
fs.truncateSync (newName)
|
17
|
+
}
|
18
|
+
fs.writeFileSync (newName, contents)
|
19
|
+
}
|
20
|
+
|
21
|
+
function overwriteFile (filename, contents) {
|
22
|
+
// log.cyan ('Overwriting → ' + filename.yellow)
|
23
|
+
fs.closeSync (fs.openSync (filename, 'a'));
|
24
|
+
fs.truncateSync (filename)
|
25
|
+
fs.writeFileSync (filename, contents)
|
26
|
+
}
|
27
|
+
|
28
|
+
function createFolder (folder) {
|
29
|
+
try {
|
30
|
+
fs.mkdirSync (folder)
|
31
|
+
} catch (err) {
|
32
|
+
if (err.code !== 'EEXIST') {
|
33
|
+
throw err
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
function createFolderRecursively (folder) {
|
39
|
+
const parts = folder.split (path.sep)
|
40
|
+
for (let i = 1; i <= parts.length; i++) {
|
41
|
+
createFolder (path.join.apply (null, parts.slice (0, i)))
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
module.exports = {
|
46
|
+
replaceInFile,
|
47
|
+
copyFile,
|
48
|
+
overwriteFile,
|
49
|
+
createFolder,
|
50
|
+
createFolderRecursively,
|
51
|
+
}
|