add fund account so that custom accounts can now deploy!!

This commit is contained in:
Jonathan Rainville 2019-08-08 15:14:37 -04:00 committed by Iuri Matias
parent 82c50d3570
commit 7ed393d38c
5 changed files with 119 additions and 14 deletions

View File

@ -45,6 +45,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime-corejs2": "7.3.1", "@babel/runtime-corejs2": "7.3.1",
"async": "2.6.1",
"embark-i18n": "^4.1.0-beta.3",
"embark-utils": "^4.1.0-beta.5", "embark-utils": "^4.1.0-beta.5",
"web3": "1.0.0-beta.37" "web3": "1.0.0-beta.37"
}, },

View File

@ -0,0 +1,75 @@
const async = require('async');
const TARGET = 0x7FFFFFFFFFFFFFFF;
const ALREADY_FUNDED = 'alreadyFunded';
export default function fundAccount(web3, accountAddress, hexBalance, callback) {
if (!hexBalance) {
hexBalance = TARGET;
}
const targetBalance = web3.utils.toBN(hexBalance);
let accountBalance;
let coinbaseAddress;
let lastNonce;
let gasPrice;
async.waterfall([
function getAccountBalance(next) {
web3.eth.getBalance(accountAddress, (err, balance) => {
if (err) {
return next(err);
}
balance = web3.utils.toBN(balance);
if (balance.gte(targetBalance)) {
return next(ALREADY_FUNDED);
}
accountBalance = balance;
next();
});
},
function getNeededParams(next) {
async.parallel([
function getCoinbaseAddress(paraCb) {
web3.eth.getCoinbase()
.then((address) => {
coinbaseAddress = address;
paraCb();
}).catch(paraCb);
},
function getGasPrice(paraCb) {
web3.eth.getGasPrice((err, price) => {
if (err) {
return paraCb(err);
}
gasPrice = price;
paraCb();
});
}
], (err, _result) => {
next(err);
});
},
function getNonce(next) {
web3.eth.getTransactionCount(coinbaseAddress, (err, nonce) => {
if (err) {
return next(err);
}
lastNonce = nonce;
next();
});
},
function sendTransaction(next) {
web3.eth.sendTransaction({
from: coinbaseAddress,
to: accountAddress,
value: targetBalance.sub(accountBalance),
gasPrice: gasPrice,
nonce: lastNonce
}, next);
}
], (err) => {
if (err && err !== ALREADY_FUNDED) {
return callback(err);
}
callback();
});
}

View File

@ -1,19 +1,30 @@
import async from "async";
import {Embark, Events, Logger} /* supplied by @types/embark in packages/embark-typings */ from "embark"; import {Embark, Events, Logger} /* supplied by @types/embark in packages/embark-typings */ from "embark";
import {__} from "embark-i18n";
import {AccountParser, dappPath} from "embark-utils"; import {AccountParser, dappPath} from "embark-utils";
const Web3 = require("web3"); import Web3 from "web3";
const ethUtil = require("ethereumjs-util");
import fundAccount from "./fundAccount";
export default class AccountsManager { export default class AccountsManager {
private readonly logger: Logger; private readonly logger: Logger;
private readonly events: Events; private readonly events: Events;
private accounts: any[]; private accounts: any[];
private web3: any; private web3: any;
private ready: boolean;
constructor(private readonly embark: Embark, _options: any) { constructor(private readonly embark: Embark, _options: any) {
this.logger = embark.logger; this.logger = embark.logger;
this.events = embark.events; this.events = embark.events;
this.accounts = []; this.accounts = [];
this.ready = false;
this.events.setCommandHandler("accounts-manager:onReady", (cb) => {
if (this.ready) {
return cb();
}
this.events.once("accounts-manager:ready", cb);
});
this.events.request("proxy:onReady", () => { this.events.request("proxy:onReady", () => {
this.parseAccounts(); this.parseAccounts();
}); });
@ -21,16 +32,10 @@ export default class AccountsManager {
this.events.setCommandHandler("accounts:get", (cb: any) => { this.events.setCommandHandler("accounts:get", (cb: any) => {
cb(null, this.accounts); cb(null, this.accounts);
}); });
this.embark.registerActionForEvent("blockchain:proxy:request", this.checkBlockchainRequest.bind(this));
this.embark.registerActionForEvent("blockchain:proxy:response", this.checkBlockchainResponse.bind(this));
} }
private async checkBlockchainRequest(params: any, callback: (error: any, result: any) => void) { private async checkBlockchainRequest(params: any, callback: (error: any, result: any) => void) {
if (!this.accounts.length) { if (params.reqData.method === "eth_sendTransaction" && this.accounts.length) {
return callback(null, params);
}
if (params.reqData.method === "eth_sendTransaction") {
// Check if we have that account in our wallet // Check if we have that account in our wallet
const account = this.accounts.find((acc) => Web3.utils.toChecksumAddress(acc.address) === Web3.utils.toChecksumAddress(params.reqData.params[0].from)); const account = this.accounts.find((acc) => Web3.utils.toChecksumAddress(acc.address) === Web3.utils.toChecksumAddress(params.reqData.params[0].from));
if (account) { if (account) {
@ -48,16 +53,23 @@ export default class AccountsManager {
} }
private async checkBlockchainResponse(params: any, callback: (error: any, result: any) => void) { private async checkBlockchainResponse(params: any, callback: (error: any, result: any) => void) {
if (!this.accounts.length) { if (params.reqData.method === "eth_accounts" && this.accounts.length) {
return callback(null, params);
}
if (params.reqData.method === "eth_accounts") {
params.respData.result = this.accounts.map((acc) => acc.address); params.respData.result = this.accounts.map((acc) => acc.address);
return callback(null, params); return callback(null, params);
} }
callback(null, params); callback(null, params);
} }
private setReady() {
if (this.ready) {
return;
}
this.embark.registerActionForEvent("blockchain:proxy:request", this.checkBlockchainRequest.bind(this));
this.embark.registerActionForEvent("blockchain:proxy:response", this.checkBlockchainResponse.bind(this));
this.ready = true;
this.events.emit("accounts-manager:ready");
}
private async parseAccounts() { private async parseAccounts() {
if (!this.web3) { if (!this.web3) {
const provider = await this.events.request2("blockchain:client:provider", "ethereum"); const provider = await this.events.request2("blockchain:client:provider", "ethereum");
@ -66,5 +78,20 @@ export default class AccountsManager {
// TODO add fund account // TODO add fund account
const nodeAccounts = await this.web3.eth.getAccounts(); const nodeAccounts = await this.web3.eth.getAccounts();
this.accounts = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, this.web3, dappPath(), this.logger, nodeAccounts); this.accounts = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, this.web3, dappPath(), this.logger, nodeAccounts);
if (!this.accounts.length || !this.embark.config.blockchainConfig.isDev) {
return this.setReady();
}
async.eachLimit(this.accounts, 1, (account, eachCb) => {
if (!account.address) {
return eachCb();
}
fundAccount(this.web3, account.address, account.hexBalance, eachCb);
}, (err) => {
if (err) {
this.logger.error(__("Error funding accounts"), err.message || err);
}
this.setReady();
});
} }
} }

View File

@ -1,4 +1,4 @@
import { __ } from 'embark-i18n'; import {__} from 'embark-i18n';
const async = require('async'); const async = require('async');
const { AccountParser, dappPath } = require('embark-utils'); const { AccountParser, dappPath } = require('embark-utils');
const fundAccount = require('./fundAccount'); const fundAccount = require('./fundAccount');

View File

@ -36,6 +36,7 @@ export interface Config {
wsOrigins: string; wsOrigins: string;
rpcCorsDomain: string; rpcCorsDomain: string;
wsRPC: boolean; wsRPC: boolean;
isDev: boolean;
}; };
webServerConfig: { webServerConfig: {
certOptions: { certOptions: {