/ lib / modules / blockchain_process / dev_funds.js
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;