2019-08-09 22:46:58 +00:00
|
|
|
const fs = require('fs')
|
|
|
|
const axios = require('axios')
|
|
|
|
const path = require('path')
|
2019-09-03 02:16:18 +00:00
|
|
|
const assert = require('assert')
|
2019-08-09 22:46:58 +00:00
|
|
|
|
|
|
|
const pngExp = /\.png$/
|
2019-09-03 02:16:18 +00:00
|
|
|
const uppercaseExp = /[A-F]/
|
2019-08-09 22:46:58 +00:00
|
|
|
|
2019-09-03 02:16:18 +00:00
|
|
|
const isEthereumAddress = address => /^(0x)?[0-9a-f]{40}$/i.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)
|
2019-08-09 22:46:58 +00:00
|
|
|
const isFilePng = name => pngExp.test(name)
|
|
|
|
const readDirSync = path => fs.readdirSync(path)
|
2019-09-03 02:16:18 +00:00
|
|
|
const isLowerCase = str => str.toLowerCase() === str
|
2019-09-11 02:03:55 +00:00
|
|
|
const isPathExistsSync = path => fs.existsSync(path)
|
2019-09-03 02:16:18 +00:00
|
|
|
const blockchainsFolderPath = './blockchains'
|
2019-08-09 22:46:58 +00:00
|
|
|
|
|
|
|
checkRootDir()
|
|
|
|
function checkRootDir () {
|
|
|
|
readDirSync('.').forEach(file => {
|
|
|
|
if(isFilePng(file)) {
|
|
|
|
exitWithMsg(`Move ${file} to ./tokens folder`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2019-09-03 02:16:18 +00:00
|
|
|
if(isPathExistsSync(`./images`)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`Adding to ./image folder is restricted, please update your fork`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
checkBlockhainsFolder()
|
|
|
|
|
|
|
|
function checkBlockhainsFolder(){
|
2019-09-20 18:12:16 +00:00
|
|
|
const currentBlockchains = 63;
|
2019-09-06 19:22:24 +00:00
|
|
|
|
2019-09-03 02:16:18 +00:00
|
|
|
const foundBlockchains = readDirSync(blockchainsFolderPath)
|
2019-08-09 22:46:58 +00:00
|
|
|
|
|
|
|
if (foundBlockchains.length !== currentBlockchains) {
|
|
|
|
exitWithMsg(`Expected amount of chains in "./blockchains" = ${currentBlockchains}, found ${foundBlockchains.length}. Add tests for new folder`)
|
|
|
|
}
|
|
|
|
|
|
|
|
foundBlockchains.forEach(folder => {
|
|
|
|
commonChainCheck(folder)
|
|
|
|
|
|
|
|
//Check Ethereum sidechains folders
|
|
|
|
const ethereumSidechains = ["ethereum", "classic", "poa", "tomochain", "gochain", "wanchain", "callisto", "thundertoken"]
|
|
|
|
if (ethereumSidechains.indexOf(folder) !== -1) {
|
|
|
|
const assetsPath = `./blockchains/${folder}/assets`
|
|
|
|
const assets = readDirSync(assetsPath)
|
|
|
|
assets.forEach(asset => {
|
2019-09-03 02:16:18 +00:00
|
|
|
if (uppercaseExp.test(asset)) {
|
2019-08-22 20:30:51 +00:00
|
|
|
exitWithMsg(`${asset} folder must be in lowercase`)
|
|
|
|
}
|
2019-09-06 19:22:24 +00:00
|
|
|
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isEthereumAddress(asset)) {
|
2019-09-10 16:17:44 +00:00
|
|
|
exitWithMsg(`Invalid asset ${asset} naming "${assetsPath}"`)
|
2019-08-09 22:46:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check if asset folder contains logo.png image
|
|
|
|
const assetLogoPath = `${assetsPath}/${asset}/logo.png`
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isPathExistsSync(assetLogoPath)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`${assetLogoPath} mush have logo.png`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (folder === "binance") {
|
|
|
|
checkBinance()
|
|
|
|
}
|
|
|
|
|
|
|
|
if (folder === "tron") {
|
|
|
|
checkTron()
|
|
|
|
}
|
|
|
|
|
2019-09-11 02:03:55 +00:00
|
|
|
// Check POS chains
|
|
|
|
const posChains = ["cosmos", "tezos"]
|
|
|
|
if (posChains.indexOf(folder) !== -1) {
|
|
|
|
checkValidatorFolder(folder)
|
2019-09-03 02:16:18 +00:00
|
|
|
}
|
|
|
|
|
2019-08-09 22:46:58 +00:00
|
|
|
|
|
|
|
console.log(`Folder ${folder} passed all checks`)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function commonChainCheck(folder) {
|
2019-09-03 02:16:18 +00:00
|
|
|
if (uppercaseExp.test(folder)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`"${folder}" must be in lowercase register`)
|
|
|
|
}
|
|
|
|
|
|
|
|
const pathToInfo = path.join(__dirname, '..', `blockchains/${folder}/info/logo.png`)
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isPathExistsSync(pathToInfo)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`Can't find coin image inside "${pathToInfo}"`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function checkBinance() {
|
|
|
|
const tokenSymbols = await getBinanceTokenSymbols()
|
|
|
|
const path = `./blockchains/binance/assets`
|
|
|
|
const assets = readDirSync(path)
|
|
|
|
|
|
|
|
assets.forEach(asset => {
|
2019-09-03 02:16:18 +00:00
|
|
|
if (uppercaseExp.test(asset)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`${asset} folder must be in lowercase`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tokenSymbols.indexOf(asset.toUpperCase()) == -1) {
|
|
|
|
exitWithMsg(`${asset} does not exist on chain`)
|
|
|
|
}
|
|
|
|
|
|
|
|
const assetLogoPath = `${path}/${asset}/logo.png`
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isPathExistsSync(assetLogoPath)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`Path ${assetLogoPath} mush have logo.png`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
function checkTron() {
|
|
|
|
const path = `./blockchains/tron/assets`
|
|
|
|
|
2019-09-11 02:03:55 +00:00
|
|
|
readDirSync(path).forEach(asset => {
|
|
|
|
if (isTRC10(asset)) {
|
|
|
|
} else {
|
|
|
|
isTRC20(asset)
|
2019-08-09 22:46:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const assetLogoPath = `${path}/${asset}/logo.png`
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isPathExistsSync(assetLogoPath)) {
|
2019-08-09 22:46:58 +00:00
|
|
|
exitWithMsg(`Path ${assetLogoPath} mush have logo.png`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-09-11 02:03:55 +00:00
|
|
|
function isTRC10(id) {
|
|
|
|
return (/^\d+$/.test(id))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check address to match TRC20 criteria
|
|
|
|
function isTRC20(address) {
|
|
|
|
if (!isLowerCase(address) ||
|
|
|
|
address.length !== 34
|
|
|
|
) {
|
|
|
|
exitWithMsg(`TRC20 ${address} fail to match criteria`)
|
|
|
|
}
|
2019-09-03 02:16:18 +00:00
|
|
|
|
2019-09-11 02:03:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function checkValidatorFolder(folder) {
|
|
|
|
const folderPath = `${blockchainsFolderPath}/${folder}`
|
|
|
|
const validatorsFolderPath = `${folderPath}/validators`
|
|
|
|
|
|
|
|
// Check validators folder existence
|
2019-09-03 02:16:18 +00:00
|
|
|
if (!isPathExistsSync(validatorsFolderPath)) {
|
|
|
|
exitWithMsg(`Validators folder doesn't exists at path ${networkPath}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
const validatorsAssetsFolderPath = validatorsFolderPath + `/assets`
|
|
|
|
if (!isPathExistsSync(validatorsAssetsFolderPath)) {
|
|
|
|
exitWithMsg(`Validators assets folder doesn't exists at path ${validatorsAssetsFolderPath}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
readDirSync(validatorsAssetsFolderPath).forEach(address => {
|
2019-09-11 02:03:55 +00:00
|
|
|
switch (folder) {
|
|
|
|
case "cosmos":
|
|
|
|
testCosmosAddress(address)
|
|
|
|
case "tezos":
|
|
|
|
testTezosAddress(address)
|
|
|
|
default:
|
|
|
|
}
|
2019-09-03 02:16:18 +00:00
|
|
|
|
|
|
|
const validatoAssetLogo = `${validatorsAssetsFolderPath}/${address}/logo.png`
|
|
|
|
if (!isPathExistsSync(validatoAssetLogo)) {
|
|
|
|
exitWithMsg(`Path ${validatoAssetLogo} mush have logo.png`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
fs.readFile(validatorsFolderPath + `/list.json`, (err, data) => {
|
|
|
|
if (err) throw err
|
|
|
|
const validators = JSON.parse(data)
|
|
|
|
|
|
|
|
validators.forEach(validator => {
|
|
|
|
const keys = Object.keys(validator)
|
|
|
|
if (keys.length !== 4) {
|
|
|
|
exitWithMsg(`Add test for new validator object key: ${keys.length}`)
|
|
|
|
}
|
2019-09-06 19:22:24 +00:00
|
|
|
|
2019-09-03 02:16:18 +00:00
|
|
|
keys.forEach(key => {
|
|
|
|
const keyType = typeof key
|
|
|
|
if (keyType !== "string") {
|
|
|
|
exitWithMsg(`Key ${key} must be "string" type, actual ${keyType}`)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2019-08-09 22:46:58 +00:00
|
|
|
})
|
2019-09-03 02:16:18 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function testCosmosAddress(address) {
|
|
|
|
if (!isLowerCase(address)) {
|
2019-09-11 02:03:55 +00:00
|
|
|
exitWithMsg(`Cosmos ${address} folder must be in lowercase`)
|
2019-09-03 02:16:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-11 02:03:55 +00:00
|
|
|
function testTezosAddress(address) {
|
|
|
|
if (!isLowerCase(address)) {
|
|
|
|
exitWithMsg(`Tezos ${address} folder must be in lowercase`)
|
|
|
|
}
|
2019-09-03 02:16:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getBinanceTokenSymbols() {
|
|
|
|
return axios.get(`https://dex-atlantic.binance.org/api/v1/tokens?limit=1000`).then(res => res.data.map(token => token.symbol))
|
2019-08-09 22:46:58 +00:00
|
|
|
}
|
|
|
|
|
2019-08-12 05:36:49 +00:00
|
|
|
function exitWithMsg (msg) {
|
2019-08-09 22:46:58 +00:00
|
|
|
console.log(msg)
|
|
|
|
process.exit(1)
|
|
|
|
}
|
|
|
|
|
2019-09-06 19:22:24 +00:00
|
|
|
console.log(`\nPassed all tests`)
|