dev_funds.js
1 const async = require('async'); 2 const Web3 = require('web3'); 3 const {buildUrl} = require('../../utils/utils.js'); 4 const {readFileSync, dappPath} = require('../../core/fs'); 5 6 class DevFunds { 7 constructor(options) { 8 this.blockchainConfig = options.blockchainConfig; 9 this.accounts = []; 10 this.numAccounts = this.blockchainConfig.account.numAccounts || 0; 11 this.password = this.blockchainConfig.account.password ? readFileSync(dappPath(this.blockchainConfig.account.password), 'utf8').replace('\n', '') : 'dev_password'; 12 this.networkId = null; 13 this.balance = Web3.utils.toWei("1", "ether"); 14 this.provider = options.provider || new Web3.providers.WebsocketProvider(buildUrl('ws', this.blockchainConfig.wsHost, this.blockchainConfig.wsPort), {headers: {Origin: "http://embark"}}); 15 this.web3 = new Web3(this.provider); 16 if (this.blockchainConfig.account.balance) { 17 this.balance = this.blockchainConfig.account.balance; 18 } 19 this.logger = options.logger || console; 20 } 21 22 static async new(options) { 23 const df = new DevFunds(options); 24 await df._init(); 25 return df; 26 } 27 28 async _init() { 29 const accounts = await this.web3.eth.getAccounts(); 30 this.web3.eth.defaultAccount = accounts[0]; 31 if (accounts.length > 1) { 32 this.accounts = accounts.slice(1); 33 } 34 } 35 36 _sendTx() { 37 // Send TXs only in dev networks 38 if (this.networkId !== 1337 && this.networkId !== 17) { 39 return; 40 } 41 this.web3.eth.sendTransaction({value: "1000000000000000", to: "0xA2817254cb8E7b6269D1689c3E0eBadbB78889d1", from: this.web3.eth.defaultAccount}); 42 } 43 44 _regularTxs(cb) { 45 const self = this; 46 self.web3.eth.net.getId().then((networkId) => { 47 self.networkId = networkId; 48 if (self.networkId !== 1337) { 49 return; 50 } 51 setInterval(function() { self._sendTx(); }, 1500); 52 if (cb) { 53 cb(); 54 } 55 }); 56 } 57 58 _fundAccounts(balance, cb) { 59 async.each(this.accounts, (account, next) => { 60 this.web3.eth.getBalance(account).then(currBalance => { 61 const remainingBalance = balance - currBalance; 62 if (remainingBalance <= 0) return next(); 63 this.web3.eth.sendTransaction({to: account, value: remainingBalance}).catch(console.error); 64 next(); // don't wait for the tx receipt as it never comes! 65 }).catch(console.error); 66 }, cb); 67 } 68 69 // TOCHECK: 70 // This function is not used anymore, but I leave because it is used for testing purpose (see test/devFunds.js) 71 // I suggest to remove this function and the corresponding test case 72 createAccounts(numAccounts, password, cb) { 73 const numAccountsToCreate = numAccounts - (this.accounts.length + 1); 74 if (numAccountsToCreate === 0) return cb(); 75 async.timesLimit(numAccountsToCreate, 1, (_, next) => { 76 this.web3.eth.personal.newAccount(password, next); 77 }, (err, accounts) => { 78 if (err) return cb(err); 79 this.accounts = accounts; 80 cb(); 81 }); 82 } 83 84 // TOCHECK: 85 // This function is not used anymore, but I leave because it is used for testing purpose (see test/devFunds.js) 86 // I suggest to remove this function and the corresponding test case 87 unlockAccounts(password, cb) { 88 async.each(this.accounts, (account, next) => { 89 this.web3.eth.personal.unlockAccount(account, password).then((_result) => { 90 next(); 91 }).catch(next); 92 }, cb); 93 } 94 95 fundAccounts(pingForever = false, cb) { 96 if (!this.web3) { 97 return cb(); 98 } 99 async.waterfall([ 100 (next) => { 101 if (pingForever) this._regularTxs(); 102 this._fundAccounts(this.balance, next); 103 } 104 ], cb); 105 } 106 } 107 108 module.exports = DevFunds;