make proxy modify txs with the account manager wallet

This commit is contained in:
Jonathan Rainville 2019-08-08 12:22:36 -04:00 committed by Iuri Matias
parent c9d4c2a134
commit 82c50d3570
4 changed files with 86 additions and 54 deletions

View File

@ -1,11 +1,13 @@
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 {AccountParser, dappPath} from "embark-utils"; import {AccountParser, dappPath} from "embark-utils";
const Web3 = require("web3"); const Web3 = require("web3");
const ethUtil = require("ethereumjs-util");
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;
constructor(private readonly embark: Embark, _options: any) { constructor(private readonly embark: Embark, _options: any) {
this.logger = embark.logger; this.logger = embark.logger;
@ -20,22 +22,49 @@ export default class AccountsManager {
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)); 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) { private async checkBlockchainResponse(params: any, callback: (error: any, result: any) => void) {
// TODO add TX support for wallet if (!this.accounts.length) {
if (params.reqData.method === "eth_accounts" && this.accounts.length) { return callback(null, params);
params.respData.data = this.accounts.map((acc) => acc.address); }
if (params.reqData.method === "eth_accounts") {
params.respData.result = this.accounts.map((acc) => acc.address);
return callback(null, params); return callback(null, params);
} }
callback(null, params); callback(null, params);
} }
private async parseAccounts() { private async parseAccounts() {
const provider = await this.events.request2("blockchain:client:provider", "ethereum"); if (!this.web3) {
const web3 = new Web3(provider); const provider = await this.events.request2("blockchain:client:provider", "ethereum");
const nodeAccounts = await web3.eth.getAccounts(); this.web3 = new Web3(provider);
this.accounts = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, web3, dappPath(), this.logger, nodeAccounts); }
// 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);
} }
} }

View File

@ -71,13 +71,14 @@ export default class ProxyManager {
const addresses = AccountParser.parseAccountsConfig(this.embark.config.blockchainConfig.accounts, false, dappPath(), this.logger); 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.proxy = await new Proxy({ipc: this.proxyIpc, events: this.events, plugins: this.plugins, logger: this.logger})
this.embark.config.blockchainConfig.endpoint, .serve(
this.host, this.embark.config.blockchainConfig.endpoint,
this.rpcPort, this.host,
false, this.rpcPort,
null, false,
); null,
);
return; return;
} }

View File

@ -1,40 +1,20 @@
/* global Buffer exports require */ /* global Buffer exports require */
import {__} from 'embark-i18n';
import axios from "axios"; import axios from "axios";
require('./httpProxyOverride');
const Asm = require('stream-json/Assembler');
import {canonicalHost, timer, pingEndpoint, deconstructUrl} from 'embark-utils'; import {canonicalHost, timer, pingEndpoint, deconstructUrl} from 'embark-utils';
import express from 'express';
const {parser: jsonParser} = require('stream-json');
const pump = require('pump');
const express = require('express');
const bodyParser = require('body-parser');
export class Proxy { export class Proxy {
constructor(ipc, events, plugins) { constructor(options) {
this.ipc = ipc; this.ipc = options.ipc;
this.commList = {}; this.commList = {};
this.receipts = {}; this.receipts = {};
this.transactions = {}; this.transactions = {};
this.toModifyPayloads = {}; this.toModifyPayloads = {};
this.timeouts = {}; this.timeouts = {};
this.events = events; this.events = options.events;
this.plugins = plugins; this.plugins = options.plugins;
} this.logger = options.logger;
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;
} }
@ -67,18 +47,39 @@ export class Proxy {
app.use((req, res) => { app.use((req, res) => {
axios.post(endpoint, req.body) // Modify request
.then((response) => { this.plugins.emitAndRunActionsForEvent('blockchain:proxy:request',
// handle success {reqData: req.body},
this.plugins.emitAndRunActionsForEvent('blockchain:proxy:response', (err, resp) => {
{respData: response.data, reqData: req.body}, if (err) {
(err, resp) => { this.logger.error(__('Error parsing the request in the proxy'));
res.send(resp.respData); this.logger.error(err);
}); // Reset the data to the original request so that it can be used anyway
}) resp = {reqData: req.body};
.catch((error) => { }
res.status(500);
res.send(error.message); // 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);
});
}); });
}); });

View File

@ -204,9 +204,10 @@ class Engine {
// }); // });
this.registerModule('ethereum-blockchain-client'); this.registerModule('ethereum-blockchain-client');
this.registerModulePackage('embark-proxy'); this.registerModulePackage('embark-proxy', {plugins: this.plugins});
// this.registerModule('web3', { plugins: this.plugins }); // this.registerModule('web3', { plugins: this.plugins });
this.registerModulePackage('embark-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-specialconfigs', {plugins: this.plugins});
this.registerModulePackage('embark-console-listener', {ipc: this.ipc}); this.registerModulePackage('embark-console-listener', {ipc: this.ipc});
} }