diff --git a/packages/embark-accounts-manager/src/index.ts b/packages/embark-accounts-manager/src/index.ts index 64ebde3c5..c1aa61b3e 100644 --- a/packages/embark-accounts-manager/src/index.ts +++ b/packages/embark-accounts-manager/src/index.ts @@ -1,11 +1,13 @@ import {Embark, Events, Logger} /* supplied by @types/embark in packages/embark-typings */ from "embark"; import {AccountParser, dappPath} from "embark-utils"; const Web3 = require("web3"); +const ethUtil = require("ethereumjs-util"); export default class AccountsManager { private readonly logger: Logger; private readonly events: Events; private accounts: any[]; + private web3: any; constructor(private readonly embark: Embark, _options: any) { this.logger = embark.logger; @@ -20,22 +22,49 @@ export default class AccountsManager { 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) { + if (!this.accounts.length) { + return callback(null, params); + } + if (params.reqData.method === "eth_sendTransaction") { + // 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)); + if (account) { + return this.web3.eth.accounts.signTransaction(params.reqData.params[0], account.privateKey , (err: any, result: any) => { + if (err) { + return callback(err, null); + } + params.reqData.method = "eth_sendRawTransaction"; + params.reqData.params = [result.rawTransaction] ; + callback(err, params); + }); + } + } + callback(null, params); + } + private async checkBlockchainResponse(params: any, callback: (error: any, result: any) => void) { - // TODO add TX support for wallet - if (params.reqData.method === "eth_accounts" && this.accounts.length) { - params.respData.data = this.accounts.map((acc) => acc.address); + if (!this.accounts.length) { + return callback(null, params); + } + if (params.reqData.method === "eth_accounts") { + params.respData.result = this.accounts.map((acc) => acc.address); return callback(null, params); } callback(null, params); } private async parseAccounts() { - const provider = await this.events.request2("blockchain:client:provider", "ethereum"); - const web3 = new Web3(provider); - const nodeAccounts = await web3.eth.getAccounts(); - this.accounts = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, web3, dappPath(), this.logger, nodeAccounts); + if (!this.web3) { + const provider = await this.events.request2("blockchain:client:provider", "ethereum"); + this.web3 = new Web3(provider); + } + // TODO add fund account + const nodeAccounts = await this.web3.eth.getAccounts(); + this.accounts = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, this.web3, dappPath(), this.logger, nodeAccounts); } } diff --git a/packages/embark-proxy/src/index.ts b/packages/embark-proxy/src/index.ts index 95b70a04e..dd80f9b1e 100644 --- a/packages/embark-proxy/src/index.ts +++ b/packages/embark-proxy/src/index.ts @@ -71,13 +71,14 @@ export default class ProxyManager { const addresses = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, false, dappPath(), this.logger); - this.proxy = await new Proxy(this.proxyIpc, this.events, this.plugins).serve( - this.embark.config.blockchainConfig.endpoint, - this.host, - this.rpcPort, - false, - null, - ); + this.proxy = await new Proxy({ipc: this.proxyIpc, events: this.events, plugins: this.plugins, logger: this.logger}) + .serve( + this.embark.config.blockchainConfig.endpoint, + this.host, + this.rpcPort, + false, + null, + ); return; } diff --git a/packages/embark-proxy/src/proxy.js b/packages/embark-proxy/src/proxy.js index 42800a46a..284f51f60 100644 --- a/packages/embark-proxy/src/proxy.js +++ b/packages/embark-proxy/src/proxy.js @@ -1,40 +1,20 @@ /* global Buffer exports require */ +import {__} from 'embark-i18n'; import axios from "axios"; - -require('./httpProxyOverride'); -const Asm = require('stream-json/Assembler'); import {canonicalHost, timer, pingEndpoint, deconstructUrl} from 'embark-utils'; - -const {parser: jsonParser} = require('stream-json'); -const pump = require('pump'); -const express = require('express'); -const bodyParser = require('body-parser'); +import express from 'express'; export class Proxy { - constructor(ipc, events, plugins) { - this.ipc = ipc; + constructor(options) { + this.ipc = options.ipc; this.commList = {}; this.receipts = {}; this.transactions = {}; this.toModifyPayloads = {}; this.timeouts = {}; - this.events = events; - this.plugins = plugins; - } - - modifyPayload(toModifyPayloads, body) { - // this.plugins.emitAndRunActionsForEvent('proxy:redponse:received', {body: body}, () => { - // - // }) - - // switch (toModifyPayloads[body.id]) { - // case METHODS_TO_MODIFY.accounts: - // delete toModifyPayloads[body.id]; - // body.result = Array.isArray(body.result) && body.result.concat(accounts); - // break; - // default: - // } - // return body; + this.events = options.events; + this.plugins = options.plugins; + this.logger = options.logger; } @@ -67,18 +47,39 @@ export class Proxy { app.use((req, res) => { - axios.post(endpoint, req.body) - .then((response) => { - // handle success - this.plugins.emitAndRunActionsForEvent('blockchain:proxy:response', - {respData: response.data, reqData: req.body}, - (err, resp) => { - res.send(resp.respData); - }); - }) - .catch((error) => { - res.status(500); - res.send(error.message); + // Modify request + this.plugins.emitAndRunActionsForEvent('blockchain:proxy:request', + {reqData: req.body}, + (err, resp) => { + if (err) { + this.logger.error(__('Error parsing the request in the proxy')); + this.logger.error(err); + // Reset the data to the original request so that it can be used anyway + resp = {reqData: req.body}; + } + + // Send the possibly modified request to the Node + axios.post(endpoint, resp.reqData) + .then((response) => { + + // Send to plugins to possibly modify the response + this.plugins.emitAndRunActionsForEvent('blockchain:proxy:response', + {respData: response.data, reqData: req.body}, + (err, resp) => { + if (err) { + this.logger.error(__('Error parsing the response in the proxy')); + this.logger.error(err); + // Reset the data to the original response so that it can be used anyway + resp = {respData: response.data}; + } + // Send back to the caller (web3) + res.send(resp.respData); + }); + }) + .catch((error) => { + res.status(500); + res.send(error.message); + }); }); }); diff --git a/packages/embark/src/lib/core/engine.js b/packages/embark/src/lib/core/engine.js index 9cad47607..89bfd9e0d 100644 --- a/packages/embark/src/lib/core/engine.js +++ b/packages/embark/src/lib/core/engine.js @@ -204,9 +204,10 @@ class Engine { // }); this.registerModule('ethereum-blockchain-client'); - this.registerModulePackage('embark-proxy'); + this.registerModulePackage('embark-proxy', {plugins: this.plugins}); // this.registerModule('web3', { plugins: this.plugins }); this.registerModulePackage('embark-web3', {plugins: this.plugins}); + this.registerModulePackage('embark-accounts-manager'); this.registerModulePackage('embark-specialconfigs', {plugins: this.plugins}); this.registerModulePackage('embark-console-listener', {ipc: this.ipc}); }