2019-03-27 15:08:17 -04:00
|
|
|
const http = require('follow-redirects').http;
|
|
|
|
const https = require('follow-redirects').https;
|
2019-04-26 11:13:36 +02:00
|
|
|
const shelljs = require('shelljs');
|
2019-04-29 13:02:45 -04:00
|
|
|
const clipboardy = require('clipboardy');
|
2019-03-27 15:08:17 -04:00
|
|
|
|
2019-03-27 13:15:46 -04:00
|
|
|
const {canonicalHost, defaultCorsHost, defaultHost, dockerHostSwap, isDocker} = require('./host');
|
2019-03-27 15:12:46 -04:00
|
|
|
const {findNextPort} = require('./network');
|
2019-04-25 12:20:46 -04:00
|
|
|
const logUtils = require('./log-utils');
|
2019-04-29 16:49:28 -05:00
|
|
|
const toposortGraph = require('./toposort');
|
2019-04-30 13:32:10 +02:00
|
|
|
import { unitRegex } from './constants';
|
2019-04-30 12:54:48 +02:00
|
|
|
import * as AddressUtils from './addressUtils';
|
|
|
|
const web3 = require("web3");
|
2019-04-30 13:32:10 +02:00
|
|
|
import { getWeiBalanceFromString, getHexBalanceFromString } from './web3Utils';
|
2019-04-30 12:54:48 +02:00
|
|
|
|
|
|
|
const { extendZeroAddressShorthand, replaceZeroAddressShorthand } = AddressUtils;
|
2019-03-27 09:44:51 -04:00
|
|
|
|
2019-04-29 12:43:08 +02:00
|
|
|
import { last, recursiveMerge } from './collections';
|
2019-04-26 14:20:05 +02:00
|
|
|
|
2019-04-29 16:18:00 +02:00
|
|
|
function timer(ms) {
|
|
|
|
const then = Date.now();
|
|
|
|
return new Promise(resolve => (
|
|
|
|
setTimeout(() => resolve(Date.now() - then), ms)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2019-03-27 15:08:17 -04:00
|
|
|
function checkIsAvailable(url, callback) {
|
|
|
|
const protocol = url.split(':')[0];
|
|
|
|
const httpObj = (protocol === 'https') ? https : http;
|
|
|
|
|
|
|
|
httpObj.get(url, function (_res) {
|
|
|
|
callback(true);
|
|
|
|
}).on('error', function (_res) {
|
|
|
|
callback(false);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-03-29 17:56:29 -04:00
|
|
|
function isHex(hex) {
|
|
|
|
const Web3 = require('web3');
|
|
|
|
return Web3.utils.isHex(hex);
|
|
|
|
}
|
|
|
|
|
|
|
|
function hashTo32ByteHexString(hash) {
|
|
|
|
if (isHex(hash)) {
|
|
|
|
if (!hash.startsWith('0x')) {
|
|
|
|
hash = '0x' + hash;
|
|
|
|
}
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
const multihash = require('multihashes');
|
|
|
|
let buf = multihash.fromB58String(hash);
|
|
|
|
let digest = multihash.decode(buf).digest;
|
|
|
|
return '0x' + multihash.toHexString(digest);
|
|
|
|
}
|
|
|
|
|
2019-03-29 18:04:24 -04:00
|
|
|
function soliditySha3(arg) {
|
|
|
|
const Web3 = require('web3');
|
|
|
|
return Web3.utils.soliditySha3(arg);
|
|
|
|
}
|
|
|
|
|
2019-04-24 16:58:47 +02:00
|
|
|
function sha512(arg) {
|
|
|
|
if (typeof arg !== 'string') {
|
|
|
|
throw new TypeError('argument must be a string');
|
|
|
|
}
|
|
|
|
const crypto = require('crypto');
|
|
|
|
const hash = crypto.createHash('sha512');
|
|
|
|
return hash.update(arg).digest('hex');
|
|
|
|
}
|
|
|
|
|
2019-04-26 11:13:36 +02:00
|
|
|
function exit(code) {
|
|
|
|
process.exit(code);
|
|
|
|
}
|
|
|
|
|
|
|
|
function runCmd(cmd, options, callback) {
|
|
|
|
options = Object.assign({silent: true, exitOnError: true, async: true}, options || {});
|
|
|
|
const outputToConsole = !options.silent;
|
|
|
|
options.silent = true;
|
|
|
|
let result = shelljs.exec(cmd, options, function (code, stdout) {
|
|
|
|
if(code !== 0) {
|
|
|
|
if (options.exitOnError) {
|
|
|
|
return exit();
|
|
|
|
}
|
|
|
|
if(typeof callback === 'function') {
|
|
|
|
callback(`shell returned code ${code}`);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(typeof callback === 'function') {
|
|
|
|
return callback(null, stdout);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
result.stdout.on('data', function(data) {
|
|
|
|
if(outputToConsole) {
|
|
|
|
console.log(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
result.stderr.on('data', function(data) {
|
|
|
|
if (outputToConsole) {
|
|
|
|
console.log(data);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-04-29 13:02:45 -04:00
|
|
|
function copyToClipboard(text) {
|
|
|
|
clipboardy.writeSync(text);
|
|
|
|
}
|
|
|
|
|
2019-04-29 16:49:28 -05:00
|
|
|
function proposeAlternative(word, _dictionary, _exceptions) {
|
|
|
|
const propose = require('propose');
|
|
|
|
let exceptions = _exceptions || [];
|
|
|
|
let dictionary = _dictionary.filter((entry) => {
|
|
|
|
return exceptions.indexOf(entry) < 0;
|
|
|
|
});
|
|
|
|
return propose(word, dictionary, {threshold: 0.3});
|
|
|
|
}
|
|
|
|
|
|
|
|
function toposort(graph) {
|
|
|
|
return toposortGraph(graph);
|
|
|
|
}
|
2019-04-26 11:13:36 +02:00
|
|
|
|
2019-04-29 16:18:00 +02:00
|
|
|
function deconstructUrl(endpoint) {
|
|
|
|
const matches = endpoint.match(/(ws|https?):\/\/([a-zA-Z0-9_.-]*):?([0-9]*)?/);
|
|
|
|
return {
|
|
|
|
protocol: matches[1],
|
|
|
|
host: matches[2],
|
|
|
|
port: matches[3],
|
|
|
|
type: matches[1] === 'ws' ? 'ws' : 'rpc'
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-04-30 12:54:48 +02:00
|
|
|
function prepareContractsConfig(config) {
|
|
|
|
Object.keys(config.contracts).forEach((contractName) => {
|
|
|
|
const gas = config.contracts[contractName].gas;
|
|
|
|
const gasPrice = config.contracts[contractName].gasPrice;
|
|
|
|
const address = config.contracts[contractName].address;
|
|
|
|
const args = config.contracts[contractName].args;
|
|
|
|
const onDeploy = config.contracts[contractName].onDeploy;
|
|
|
|
|
|
|
|
if (gas && gas.toString().match(unitRegex)) {
|
|
|
|
config.contracts[contractName].gas = getWeiBalanceFromString(gas, web3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gasPrice && gasPrice.toString().match(unitRegex)) {
|
|
|
|
config.contracts[contractName].gasPrice = getWeiBalanceFromString(gasPrice, web3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (address) {
|
|
|
|
config.contracts[contractName].address = extendZeroAddressShorthand(address);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args && args.length) {
|
|
|
|
config.contracts[contractName].args = args.map((val) => {
|
|
|
|
if (typeof val === "string") {
|
|
|
|
return extendZeroAddressShorthand(val);
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(onDeploy)) {
|
|
|
|
config.contracts[contractName].onDeploy = onDeploy.map(replaceZeroAddressShorthand);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return config;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-03-27 13:15:46 -04:00
|
|
|
const Utils = {
|
|
|
|
joinPath: function() {
|
2019-03-27 09:44:51 -04:00
|
|
|
const path = require('path');
|
|
|
|
return path.join.apply(path.join, arguments);
|
2019-03-27 13:15:46 -04:00
|
|
|
},
|
|
|
|
canonicalHost,
|
2019-04-29 13:02:45 -04:00
|
|
|
copyToClipboard,
|
2019-04-29 16:18:00 +02:00
|
|
|
deconstructUrl,
|
2019-03-27 13:15:46 -04:00
|
|
|
defaultCorsHost,
|
|
|
|
defaultHost,
|
|
|
|
dockerHostSwap,
|
2019-04-26 11:13:36 +02:00
|
|
|
exit,
|
2019-03-27 15:08:17 -04:00
|
|
|
isDocker,
|
2019-03-27 15:12:46 -04:00
|
|
|
checkIsAvailable,
|
2019-03-29 17:56:29 -04:00
|
|
|
findNextPort,
|
|
|
|
hashTo32ByteHexString,
|
2019-03-29 18:04:24 -04:00
|
|
|
isHex,
|
2019-04-26 14:20:05 +02:00
|
|
|
last,
|
2019-03-29 18:14:33 -04:00
|
|
|
soliditySha3,
|
2019-04-24 16:58:47 +02:00
|
|
|
recursiveMerge,
|
2019-04-30 12:54:48 +02:00
|
|
|
prepareContractsConfig,
|
|
|
|
getWeiBalanceFromString,
|
2019-04-30 13:17:24 +02:00
|
|
|
getHexBalanceFromString,
|
2019-04-25 12:19:20 -04:00
|
|
|
sha512,
|
2019-04-29 16:18:00 +02:00
|
|
|
timer,
|
2019-04-29 16:26:20 +02:00
|
|
|
unitRegex,
|
2019-04-26 11:13:36 +02:00
|
|
|
runCmd,
|
2019-04-25 12:20:46 -04:00
|
|
|
escapeHtml: logUtils.escapeHtml,
|
|
|
|
normalizeInput: logUtils.normalizeInput,
|
2019-04-26 15:37:58 -04:00
|
|
|
LogHandler: require('./logHandler'),
|
2019-04-29 16:49:28 -05:00
|
|
|
proposeAlternative,
|
2019-04-30 12:54:48 +02:00
|
|
|
toposort,
|
|
|
|
AddressUtils
|
2019-03-27 13:15:46 -04:00
|
|
|
};
|
2019-03-27 09:44:51 -04:00
|
|
|
|
|
|
|
module.exports = Utils;
|