further dev funding

This commit is contained in:
emizzle 2018-07-16 18:48:32 +02:00
parent f2213970f7
commit 11d6980f70
10 changed files with 3053 additions and 2939 deletions

View File

@ -164,7 +164,8 @@ Blockchain.prototype.run = function() {
data = data.toString(); data = data.toString();
if (self.onReadyCallback && !self.readyCalled && data.indexOf('WebSocket endpoint opened') > -1) { if (self.onReadyCallback && !self.readyCalled && data.indexOf('WebSocket endpoint opened') > -1) {
if (self.isDev) { if (self.isDev) {
return self.createFundAndUnlockAccounts(() => { return self.createFundAndUnlockAccounts((err) => {
if(err) console.error('Error creating, unlocking, and funding accounts', err);
self.readyCalled = true; self.readyCalled = true;
self.onReadyCallback(); self.onReadyCallback();
}); });
@ -185,12 +186,12 @@ Blockchain.prototype.run = function() {
Blockchain.prototype.createFundAndUnlockAccounts = function(cb) { Blockchain.prototype.createFundAndUnlockAccounts = function(cb) {
console.dir('createFundAndUnlockAccounts'); console.dir('createFundAndUnlockAccounts');
let devFunds = new DevFunds(this.config); let devFunds = new DevFunds(this.config);
devFunds.createFundAndUnlockAccounts(() => { devFunds.createFundAndUnlockAccounts((err) => {
console.dir("=====> done!"); console.dir("=====> done!");
console.dir(arguments); console.dir(arguments);
cb(); cb(err);
}); });
} };
Blockchain.prototype.kill = function() { Blockchain.prototype.kill = function() {
if (this.child) { if (this.child) {

View File

@ -1,6 +1,7 @@
const async = require('async'); const async = require('async');
var Web3 = require('web3'); const Web3 = require('web3');
var utils = require('../../utils/utils.js'); const {getWeiBalanceFromString, buildUrl} = require('../../utils/utils.js');
const {readFileSync, dappPath} = require('../../core/fs');
class DevFunds { class DevFunds {
constructor(blockchainConfig) { constructor(blockchainConfig) {
@ -8,28 +9,36 @@ class DevFunds {
this.blockchainConfig = blockchainConfig; this.blockchainConfig = blockchainConfig;
this.accounts = []; this.accounts = [];
this.numAccounts = this.blockchainConfig.account.numAccounts || 0; this.numAccounts = this.blockchainConfig.account.numAccounts || 0;
//this.balance = this.blockchainConfig.account.balance || Web3.utils.toWei("1", "ether"); this.password = readFileSync(dappPath('config/development/password'));
this.password = 'dev_password';
this.existingNumAccounts = 0;
this.web3 = new Web3();
this.balance = Web3.utils.toWei("1", "ether"); this.balance = Web3.utils.toWei("1", "ether");
this.password = "dev_password" if(this.blockchainConfig.account.balance){
console.dir('[blockchain/dev_funds]: converting balance from ' + this.blockchainConfig.account.balance);
this.balance = getWeiBalanceFromString(this.blockchainConfig.account.balance, this.web3);
console.dir('[blockchain/dev_funds]: converted balance to ' + this.balance);
}
} }
connectToNode(cb) { connectToNode(cb) {
const self = this;
this.web3 = new Web3(); this.web3.setProvider(new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://localhost:8000"}}));
this.web3.setProvider(new Web3.providers.WebsocketProvider(utils.buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://localhost:8000"}}));
this.web3.eth.getAccounts().then((accounts) => { this.web3.eth.getAccounts().then((accounts) => {
self.web3.eth.defaultAccount = accounts[0]; this.web3.eth.defaultAccount = accounts[0];
this.existingNumAccounts = accounts.length;
cb(); cb();
}); });
} }
createAccounts(numAccounts, password, cb) { createAccounts(numAccounts, password, cb) {
console.dir("creating " + numAccounts + " with password " + password); console.dir("creating " + (numAccounts - this.existingNumAccounts) + " new accounts with password " + password);
const self = this; async.timesLimit((numAccounts - this.existingNumAccounts), 1, (_, next) => {
async.timesLimit(numAccounts, 1, (_, next) => {
console.dir("--- creating new account"); console.dir("--- creating new account");
self.web3.eth.personal.newAccount(password, next); this.web3.eth.personal.newAccount(password, next);
}, (err, accounts) => { }, (err, accounts) => {
if(err) console.error(err);
console.dir("-- accounts created are "); console.dir("-- accounts created are ");
console.dir(accounts); console.dir(accounts);
this.accounts = accounts; this.accounts = accounts;
@ -38,37 +47,62 @@ class DevFunds {
} }
unlockAccounts(password, cb) { unlockAccounts(password, cb) {
const self = this;
async.each(this.accounts, (account, next) => { async.each(this.accounts, (account, next) => {
self.web3.eth.personal.unlockAccount(account, password).then(() => { next() }); console.dir('-- unlocking account ' + account + ' with password ' + password);
this.web3.eth.personal.unlockAccount(account, password).then(() => next()).catch(next);
}, cb); }, cb);
} }
fundAccounts(balance, cb) { fundAccounts(balance, cb) {
const self = this; console.dir('-- funding accounts...');
async.each(this.accounts, (account, next) => { async.each(this.accounts, (account, next) => {
self.web3.eth.sendTransaction({to: account, value: balance}).then(() => { console.dir("-- funding account " + account + " with balance " + balance);
this.web3.eth.sendTransaction({to: account, value: balance}).then((result) => {
console.dir('FUNDING ACCT result: ' + JSON.stringify(result));
next(); next();
}).catch(next);
}, (err) => {
console.dir('-- FINISHED FUNDING ACCOUNTS, err= ' + err);
cb(err);
}); });
}, cb);
} }
createFundAndUnlockAccounts(cb) { createFundAndUnlockAccounts(cb) {
const self = this;
async.waterfall([ async.waterfall([
function connect(next) { (next) => {
self.connectToNode(next); console.dir('--- CONNECTING TO NODE');
this.connectToNode(next);
}, },
function create(next) { (next) => {
self.createAccounts(self.numAccounts, self.password, next) console.dir('--- CREATING THE ACCOUNTS');
this.createAccounts(this.numAccounts, this.password, next);
}, },
function unlock(next) { (next) => {
self.unlockAccounts(self.password, next); console.dir('--- UNLOCKING THE ACCOUNTS');
this.unlockAccounts(this.password, next);
}, },
function fund(next) { (next) => {
self.fundAccounts(self.balance, next); console.dir('--- FUNDING THE ACCOUNTS');
}, this.fundAccounts(this.balance, next);
], cb); }
], (err) => {
console.trace(`--- COMPLETED THE ACCOUNTS (${this.accounts.join(', ')} and funded with ${this.balance} wei)`);
if(err) console.error('Error creating, unlocking, and funding accounts', err);
// this.web3.eth.getAccounts().then((accounts) => {
// let numAccts = accounts.length;
// accounts.forEach((account) => {
// this.web3.eth.getBalance(account).then((balance) => {
// console.dir('[contracts/dev_funds]: account ' + account + ' has balance of ' + balance);
// if(--numAccts === 0) cb(err);
// });
// });
// });
cb(err);
});
} }
} }

View File

@ -1,6 +1,7 @@
const bip39 = require("bip39"); const bip39 = require("bip39");
const hdkey = require('ethereumjs-wallet/hdkey'); const hdkey = require('ethereumjs-wallet/hdkey');
const fs = require('../core/fs'); const fs = require('../core/fs');
const {getHexBalanceFromString} = require('../utils/utils');
class AccountParser { class AccountParser {
static parseAccountsConfig(accountsConfig, web3, logger) { static parseAccountsConfig(accountsConfig, web3, logger) {
@ -21,31 +22,15 @@ class AccountParser {
return accounts; return accounts;
} }
static getHexBalance(balanceString, web3) {
if (!balanceString) {
return 0xFFFFFFFFFFFFFFFFFF;
}
if (web3.utils.isHexStrict(balanceString)) {
return balanceString;
}
const match = balanceString.match(/([0-9]+) ?([a-zA-Z]*)/);
if (!match) {
throw new Error(__('Unrecognized balance string "%s"', balanceString));
}
if (!match[2]) {
return web3.utils.toHex(parseInt(match[1], 10));
}
return web3.utils.toHex(web3.utils.toWei(match[1], match[2]));
}
static getAccount(accountConfig, web3, logger) { static getAccount(accountConfig, web3, logger) {
if (!logger) { if (!logger) {
logger = console; logger = console;
} }
let hexBalance = null; let hexBalance = null;
if (accountConfig.balance) { if (accountConfig.balance) {
hexBalance = AccountParser.getHexBalance(accountConfig.balance, web3); hexBalance = getHexBalanceFromString(accountConfig.balance, web3);
//hexBalance = getHexBalanceFromString(accountConfig.balance, web3);
console.dir('[contracts/accountParser]: balance ' + accountConfig.balance + ' converted to hex ' + hexBalance);
} }
if (accountConfig.privateKey) { if (accountConfig.privateKey) {
if (!accountConfig.privateKey.startsWith('0x')) { if (!accountConfig.privateKey.startsWith('0x')) {

View File

@ -50,7 +50,7 @@ class Blockchain {
const protocol = (this.contractsConfig.deployment.type === "rpc") ? this.contractsConfig.deployment.protocol : 'ws'; const protocol = (this.contractsConfig.deployment.type === "rpc") ? this.contractsConfig.deployment.protocol : 'ws';
let provider; let provider;
this.web3Endpoint = utils.buildUrl(protocol, this.contractsConfig.deployment.host, this.contractsConfig.deployment.port);//`${protocol}://${this.contractsConfig.deployment.host}:${this.contractsConfig.deployment.port}`; this.web3Endpoint = utils.buildUrl(protocol, this.contractsConfig.deployment.host, this.contractsConfig.deployment.port);//`${protocol}://${this.contractsConfig.deployment.host}:${this.contractsConfig.deployment.port}`;
console.dir('[blockchain/contracts]: web3 endpoint: ' + this.web3Endpoint);
const providerOptions = { const providerOptions = {
web3: this.web3, web3: this.web3,
accountsConfig: this.contractsConfig.deployment.accounts, accountsConfig: this.contractsConfig.deployment.accounts,
@ -64,6 +64,7 @@ class Blockchain {
async.waterfall([ async.waterfall([
function checkNode(next) { function checkNode(next) {
console.dir('[blockchain/contracts]: check node');
self.assertNodeConnection(true, (err) => { self.assertNodeConnection(true, (err) => {
if (err && self.web3StartedInProcess) { if (err && self.web3StartedInProcess) {
// Already started blockchain in another node, we really have a node problem // Already started blockchain in another node, we really have a node problem
@ -77,6 +78,7 @@ class Blockchain {
} }
self.web3StartedInProcess = true; self.web3StartedInProcess = true;
self.startBlockchainNode(() => { self.startBlockchainNode(() => {
console.dir('[blockchain/contracts]: starting blockchain node');
// Need to re-initialize web3 to connect to the new blockchain node // Need to re-initialize web3 to connect to the new blockchain node
provider.stop(); provider.stop();
self.initWeb3(cb); self.initWeb3(cb);
@ -84,9 +86,11 @@ class Blockchain {
}); });
}, },
function startProvider(next) { function startProvider(next) {
console.dir('[blockchain/contracts]: starting web3 provider');
provider.startWeb3Provider(next); provider.startWeb3Provider(next);
}, },
function fundAccountsIfNeeded(next) { function fundAccountsIfNeeded(next) {
console.dir('[blockchain/contracts]: funding accounts');
provider.fundAccounts(next); provider.fundAccounts(next);
} }
], (err) => { ], (err) => {
@ -178,7 +182,11 @@ class Blockchain {
}); });
this.events.setCommandHandler("blockchain:gasPrice", function(cb) { this.events.setCommandHandler("blockchain:gasPrice", function(cb) {
self.getGasPrice(cb); console.dir('[blockchain/contracts]: getting gas price...');
self.getGasPrice((gp) => {
console.dir('[blockchain/contracts]: got gasPrice of ' + gp);
cb(gp);
});
}); });
} }
@ -277,7 +285,16 @@ class Blockchain {
} }
let accountConfig = self.blockchainConfig.account; let accountConfig = self.blockchainConfig.account;
let selectedAccount = accountConfig && accountConfig.address; let selectedAccount = accountConfig && accountConfig.address;
console.dir('[contracts/blockchain]: setting default account of ' + (selectedAccount || accounts[0]));
self.setDefaultAccount(selectedAccount || accounts[0]); self.setDefaultAccount(selectedAccount || accounts[0]);
console.dir('[contracts/blockchain]: accounts on node = ');
//let numAccts = accounts.length;
self.web3.eth.getAccounts().then((accounts) => {
accounts.forEach((account) => {
self.web3.eth.getBalance(account).then((balance) => console.dir('[contracts/blockchain]: account ' + account + ' has balance of ' + balance));
//if(--numAccts === 0) cb();
});
});
cb(); cb();
}); });
} }

View File

@ -54,18 +54,21 @@ class ContractsManager {
self.contracts = {}; self.contracts = {};
async.waterfall([ async.waterfall([
function loadContractFiles(callback) { function loadContractFiles(callback) {
console.dir('[contracts/contracts]: load contract files');
self.events.request("config:contractsFiles", (contractsFiles) => { self.events.request("config:contractsFiles", (contractsFiles) => {
self.contractsFiles = contractsFiles; self.contractsFiles = contractsFiles;
callback(); callback();
}); });
}, },
function loadContractConfigs(callback) { function loadContractConfigs(callback) {
console.dir('[contracts/contracts]: load contract configs');
self.events.request("config:contractsConfig", (contractsConfig) => { self.events.request("config:contractsConfig", (contractsConfig) => {
self.contractsConfig = cloneDeep(contractsConfig); self.contractsConfig = cloneDeep(contractsConfig);
callback(); callback();
}); });
}, },
function compileContracts(callback) { function compileContracts(callback) {
console.dir('[contracts/contracts]: compile contracts');
self.events.emit("status", __("Compiling...")); self.events.emit("status", __("Compiling..."));
if (process.env.isTest && self.compiledContracts && Object.keys(self.compiledContracts).length) { if (process.env.isTest && self.compiledContracts && Object.keys(self.compiledContracts).length) {
// Only compile once for tests // Only compile once for tests
@ -77,6 +80,7 @@ class ContractsManager {
}); });
}, },
function prepareContractsFromConfig(callback) { function prepareContractsFromConfig(callback) {
console.dir('[contracts/contracts]: prepare contracts from config');
self.events.emit("status", __("Building...")); self.events.emit("status", __("Building..."));
let className, contract; let className, contract;
for (className in self.contractsConfig.contracts) { for (className in self.contractsConfig.contracts) {
@ -90,12 +94,17 @@ class ContractsManager {
callback(); callback();
}, },
function getGasPriceForNetwork(callback) { function getGasPriceForNetwork(callback) {
console.dir('[contracts/contracts]: gas price for network, passed in gasPrice from config: ' + self.contractsConfig.gasPrice);
if (self.contractsConfig.gasPrice) { if (self.contractsConfig.gasPrice) {
return callback(null, self.contractsConfig.gasPrice); return callback(null, self.contractsConfig.gasPrice);
} }
self.events.request("blockchain:gasPrice", callback); self.events.request("blockchain:gasPrice", (gasprice) => {
console.dir('[contracts/contracts]: got gasPrice of ' + gasprice);
callback(gasprice);
});
}, },
function prepareContractsFromCompilation(gasPrice, callback) { function prepareContractsFromCompilation(gasPrice, callback) {
console.dir('[contracts/contracts]: using gasprice ' + gasPrice + ', prepare contracts from compilation');
let className, compiledContract, contractConfig, contract; let className, compiledContract, contractConfig, contract;
for (className in self.compiledContracts) { for (className in self.compiledContracts) {
compiledContract = self.compiledContracts[className]; compiledContract = self.compiledContracts[className];
@ -123,6 +132,7 @@ class ContractsManager {
callback(); callback();
}, },
function setDeployIntention(callback) { function setDeployIntention(callback) {
console.dir('[contracts/contracts]: set deploy intention');
let className, contract; let className, contract;
for (className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];
@ -140,6 +150,7 @@ class ContractsManager {
}, },
/*eslint complexity: ["error", 11]*/ /*eslint complexity: ["error", 11]*/
function dealWithSpecialConfigs(callback) { function dealWithSpecialConfigs(callback) {
console.dir('[contracts/contracts]: deal with special configs');
let className, contract, parentContractName, parentContract; let className, contract, parentContractName, parentContract;
let dictionary = Object.keys(self.contracts); let dictionary = Object.keys(self.contracts);
@ -189,6 +200,7 @@ class ContractsManager {
callback(); callback();
}, },
function removeContractsWithNoCode(callback) { function removeContractsWithNoCode(callback) {
console.dir('[contracts/contracts]: remove Contracts with no code');
let className, contract; let className, contract;
let dictionary = Object.keys(self.contracts); let dictionary = Object.keys(self.contracts);
for (className in self.contracts) { for (className in self.contracts) {
@ -210,6 +222,7 @@ class ContractsManager {
/*eslint complexity: ["error", 16]*/ /*eslint complexity: ["error", 16]*/
/*eslint max-depth: ["error", 16]*/ /*eslint max-depth: ["error", 16]*/
function determineDependencies(callback) { function determineDependencies(callback) {
console.dir('[contracts/contracts]: determining dependencies');
let className, contract; let className, contract;
for (className in self.contracts) { for (className in self.contracts) {
contract = self.contracts[className]; contract = self.contracts[className];

View File

@ -67,6 +67,7 @@ class DeployManager {
async.waterfall([ async.waterfall([
function buildContracts(callback) { function buildContracts(callback) {
self.events.request("contracts:build", self.deployOnlyOnConfig, (err) => { self.events.request("contracts:build", self.deployOnlyOnConfig, (err) => {
console.dir('[contracts/deploy_manager]: done building contracts');
callback(err); callback(err);
}); });
}, },
@ -82,8 +83,11 @@ class DeployManager {
// TODO: could be implemented as an event (beforeDeployAll) // TODO: could be implemented as an event (beforeDeployAll)
function checkIsConnectedToBlockchain(callback) { function checkIsConnectedToBlockchain(callback) {
console.dir('[contracts/deploy_manager]: checking connection to blockchain');
self.blockchain.onReady(() => { self.blockchain.onReady(() => {
console.dir('[contracts/deploy_manager]: onReady called, asserting node connection');
self.blockchain.assertNodeConnection((err) => { self.blockchain.assertNodeConnection((err) => {
console.dir('[contracts/deploy_manager]: node connection asserted, err: ' + JSON.stringify(err));
callback(err); callback(err);
}); });
}); });
@ -91,13 +95,16 @@ class DeployManager {
// TODO: this can be done on the fly or as part of the initialization // TODO: this can be done on the fly or as part of the initialization
function determineDefaultAccount(callback) { function determineDefaultAccount(callback) {
console.dir('[contracts/deploy_manager]: determining default acct');
self.blockchain.determineDefaultAccount((err) => { self.blockchain.determineDefaultAccount((err) => {
callback(err); callback(err);
}); });
}, },
function deployAllContracts(callback) { function deployAllContracts(callback) {
console.dir('[contracts/deploy_manager]: deploying all contracts');
self.deployAll(function (err) { self.deployAll(function (err) {
console.dir('[contracts/deploy_manager]: done deploying all contracts, err: ' + JSON.stringify(err));
if (!err) { if (!err) {
self.events.emit('contractsDeployed'); self.events.emit('contractsDeployed');
} }
@ -108,6 +115,7 @@ class DeployManager {
}); });
}, },
function runAfterDeploy(callback) { function runAfterDeploy(callback) {
console.dir('[contracts/deploy_manager]: emitting and running actions for event "contracts:deploy:afterAll"');
self.plugins.emitAndRunActionsForEvent('contracts:deploy:afterAll', callback); self.plugins.emitAndRunActionsForEvent('contracts:deploy:afterAll', callback);
} }
], function (err, _result) { ], function (err, _result) {

View File

@ -2,14 +2,13 @@ const async = require('async');
const TARGET = 0x7FFFFFFFFFFFFFFF; const TARGET = 0x7FFFFFFFFFFFFFFF;
const ALREADY_FUNDED = 'alreadyFunded'; const ALREADY_FUNDED = 'alreadyFunded';
function fundAccount(web3, accountAddress, hexBalance, callback) { function fundAccount(web3, accountAddress, hexBalance, nonce, callback) {
if (!hexBalance) { if (!hexBalance) {
hexBalance = TARGET; hexBalance = TARGET;
} }
const targetBalance = (typeof hexBalance === 'string') ? parseInt(hexBalance, 16) : hexBalance; const targetBalance = (typeof hexBalance === 'string') ? parseInt(hexBalance, 16) : hexBalance;
let accountBalance; let accountBalance;
let coinbaseAddress; let coinbaseAddress;
let lastNonce;
let gasPrice; let gasPrice;
async.waterfall([ async.waterfall([
@ -52,17 +51,23 @@ function fundAccount(web3, accountAddress, hexBalance, callback) {
if (err) { if (err) {
return next(err); return next(err);
} }
lastNonce = nonce;
next(); next();
}); });
}, },
function sendTransaction(next) { function sendTransaction(next) {
console.dir('[contracts/fundAccount]: sending tx ' + JSON.stringify({
from: coinbaseAddress,
to: accountAddress,
value: targetBalance - accountBalance,
gasPrice: gasPrice,
nonce: nonce
}));
web3.eth.sendTransaction({ web3.eth.sendTransaction({
from: coinbaseAddress, from: coinbaseAddress,
to: accountAddress, to: accountAddress,
value: targetBalance - accountBalance, value: targetBalance - accountBalance,
gasPrice: gasPrice, gasPrice: gasPrice,
nonce: lastNonce nonce: nonce
}, next); }, next);
} }
], (err) => { ], (err) => {

View File

@ -78,8 +78,12 @@ class Provider {
if (!self.isDev) { if (!self.isDev) {
return callback(); return callback();
} }
let nonce = 0;
async.each(self.accounts, (account, eachCb) => { async.each(self.accounts, (account, eachCb) => {
fundAccount(self.web3, account.address, account.hexBalance, eachCb); console.dir('[contracts/provider]: nonce is ' + nonce);
fundAccount(self.web3, account.address, account.hexBalance, nonce++, (err) => {
eachCb(err);
});
}, callback); }, callback);
} }

View File

@ -1,6 +1,8 @@
let http = require('follow-redirects').http; let http = require('follow-redirects').http;
let https = require('follow-redirects').https; let https = require('follow-redirects').https;
const balanceRegex = /([0-9]+) ?([a-zA-Z]*)/;
function joinPath() { function joinPath() {
const path = require('path'); const path = require('path');
return path.join.apply(path.join, arguments); return path.join.apply(path.join, arguments);
@ -297,6 +299,45 @@ function buildUrlFromConfig (configObj){
return this.buildUrl(configObj.protocol, configObj.host, configObj.port); return this.buildUrl(configObj.protocol, configObj.host, configObj.port);
} }
function getWeiBalanceFromString(balanceString, web3){
if(!web3){
throw new Error(__('[utils.getWeiBalanceFromString]: Missing parameter \'web3\''));
}
if (!balanceString) {
return 0;
}
const match = balanceString.match(balanceRegex);
if (!match) {
throw new Error(__('Unrecognized balance string "%s"', balanceString));
}
if (!match[2]) {
return web3.utils.toHex(parseInt(match[1], 10));
}
return web3.utils.toWei(match[1], match[2]);
}
function getHexBalanceFromString(balanceString, web3) {
if(!web3){
throw new Error(__('[utils.getWeiBalanceFromString]: Missing parameter \'web3\''));
}
if (!balanceString) {
return 0xFFFFFFFFFFFFFFFFFF;
}
if (web3.utils.isHexStrict(balanceString)) {
return balanceString;
}
const match = balanceString.match(balanceRegex);
if (!match) {
throw new Error(__('Unrecognized balance string "%s"', balanceString));
}
if (!match[2]) {
return web3.utils.toHex(parseInt(match[1], 10));
}
return web3.utils.toHex(web3.utils.toWei(match[1], match[2]));
}
module.exports = { module.exports = {
joinPath: joinPath, joinPath: joinPath,
filesMatchingPattern: filesMatchingPattern, filesMatchingPattern: filesMatchingPattern,
@ -323,5 +364,7 @@ module.exports = {
sha3: sha3, sha3: sha3,
normalizeInput, normalizeInput,
buildUrl, buildUrl,
buildUrlFromConfig buildUrlFromConfig,
getWeiBalanceFromString,
getHexBalanceFromString
}; };

5760
package-lock.json generated

File diff suppressed because it is too large Load Diff