123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /**
- Window communication
- @module ipcCommunicator
- */
- const _ = global._;
- const fs = require('fs');
- const { app, ipcMain: ipc, shell, webContents } = require('electron');
- const Windows = require('./windows');
- const logger = require('./utils/logger');
- const appMenu = require('./menuItems');
- const Settings = require('./settings');
- const ethereumNode = require('./ethereumNode.js');
- const keyfileRecognizer = require('ethereum-keyfile-recognizer');
- import { getLanguage } from './core/settings/actions';
- const log = logger.create('ipcCommunicator');
- require('./abi.js');
- /*
- // windows including webviews
- windows = {
- 23: {
- type: 'requestWindow',
- window: obj,
- owner: 12
- },
- 12: {
- type: 'webview'
- window: obj
- owner: null
- }
- }
- */
- // UI ACTIONS
- ipc.on('backendAction_closeApp', () => {
- app.quit();
- });
- ipc.on('backendAction_openExternalUrl', (e, url) => {
- shell.openExternal(url);
- });
- ipc.on('backendAction_closePopupWindow', e => {
- const windowId = e.sender.id;
- const senderWindow = Windows.getById(windowId);
- if (senderWindow) {
- senderWindow.close();
- }
- });
- ipc.on('backendAction_setWindowSize', (e, width, height) => {
- const windowId = e.sender.id;
- const senderWindow = Windows.getById(windowId);
- if (senderWindow) {
- senderWindow.window.setSize(width, height | 0);
- senderWindow.window.center(); // ?
- }
- });
- ipc.on('backendAction_windowCallback', (e, value1, value2, value3) => {
- const windowId = e.sender.id;
- const senderWindow = Windows.getById(windowId);
- if (senderWindow.callback) {
- senderWindow.callback(value1, value2, value3);
- }
- });
- ipc.on('backendAction_windowMessageToOwner', (e, error, value) => {
- const windowId = e.sender.id;
- const senderWindow = Windows.getById(windowId);
- // If msg is from a generic window, use the "actingType" instead of type
- const senderWindowType = senderWindow.actingType || senderWindow.type;
- if (senderWindow.ownerId) {
- const ownerWindow = Windows.getById(senderWindow.ownerId);
- const mainWindow = Windows.getByType('main');
- if (ownerWindow) {
- ownerWindow.send(
- 'uiAction_windowMessage',
- senderWindowType,
- error,
- value
- );
- }
- // send through the mainWindow to the webviews
- if (mainWindow) {
- mainWindow.send(
- 'uiAction_windowMessage',
- senderWindowType,
- senderWindow.ownerId,
- error,
- value
- );
- }
- }
- });
- ipc.on('backendAction_getLanguage', e => {
- store.dispatch(getLanguage(e));
- });
- ipc.on('backendAction_stopWebviewNavigation', (e, id) => {
- console.log('webcontent ID', id);
- const webContent = webContents.fromId(id);
- if (webContent && !webContent.isDestroyed()) {
- webContent.stop();
- }
- e.returnValue = true;
- });
- // check wallet file
- ipc.on('backendAction_checkWalletFile', (e, path) => {
- fs.readFile(path, 'utf8', (event, data) => {
- try {
- const keyfile = JSON.parse(data);
- const result = keyfileRecognizer(keyfile);
- /** result
- * [ 'ethersale', undefined ] Ethersale keyfile
- * [ 'web3', 3 ] web3 (v3) keyfile
- * null no valid keyfile
- */
- const type = _.first(result);
- log.debug(`Importing ${type} account...`);
- if (type === 'ethersale') {
- e.sender.send('uiAction_checkedWalletFile', null, 'presale');
- } else if (type === 'web3') {
- e.sender.send('uiAction_checkedWalletFile', null, 'web3');
- let keystorePath = Settings.userHomePath;
- // eth
- if (ethereumNode.isEth) {
- if (process.platform === 'win32') {
- keystorePath = `${Settings.appDataPath}\\Web3\\keys`;
- } else {
- keystorePath += '/.web3/keys';
- }
- // geth
- } else {
- if (process.platform === 'darwin')
- keystorePath += '/Library/Ethereum/keystore';
- if (
- process.platform === 'freebsd' ||
- process.platform === 'linux' ||
- process.platform === 'sunos'
- )
- keystorePath += '/.ethereum/keystore';
- if (process.platform === 'win32')
- keystorePath = `${Settings.appDataPath}\\Ethereum\\keystore`;
- }
- if (!/^[0-9a-fA-F]{40}$/.test(keyfile.address)) {
- throw new Error('Invalid Address format.');
- }
- fs.writeFile(`${keystorePath}/0x${keyfile.address}`, data, err => {
- if (err) throw new Error("Can't write file to disk");
- });
- } else {
- throw new Error('Account import: Cannot recognize keyfile (invalid)');
- }
- } catch (err) {
- e.sender.send('uiAction_checkedWalletFile', null, 'invalid');
- if (
- /Unexpected token . in JSON at position 0/.test(err.message) === true
- ) {
- log.error('Account import: Cannot recognize keyfile (no JSON)');
- } else {
- log.error(err);
- }
- }
- });
- });
- // import presale wallet
- ipc.on('backendAction_importWalletFile', (e, path, pw) => {
- const spawn = require('child_process').spawn; // eslint-disable-line global-require
- const ClientBinaryManager = require('./clientBinaryManager'); // eslint-disable-line global-require
- let error = false;
- const binPath = ClientBinaryManager.getClient('geth').binPath;
- const nodeProcess = spawn(binPath, ['wallet', 'import', path]);
- nodeProcess.once('error', () => {
- error = true;
- e.sender.send(
- 'uiAction_importedWalletFile',
- 'Couldn\'t start the "geth wallet import <file.json>" process.'
- );
- });
- nodeProcess.stdout.on('data', _data => {
- const data = _data.toString();
- if (data) {
- log.info('Imported presale: ', data);
- }
- if (
- /Decryption failed|not equal to expected addr|could not decrypt/.test(
- data
- )
- ) {
- e.sender.send('uiAction_importedWalletFile', 'Decryption Failed');
- // if imported, return the address
- } else if (data.indexOf('Address:') !== -1) {
- const find = data.match(/\{([a-f0-9]+)\}/i);
- if (find.length && find[1]) {
- e.sender.send('uiAction_importedWalletFile', null, `0x${find[1]}`);
- } else {
- e.sender.send('uiAction_importedWalletFile', data);
- }
- // if not stop, so we don't kill the process
- } else {
- return;
- }
- nodeProcess.stdout.removeAllListeners('data');
- nodeProcess.removeAllListeners('error');
- nodeProcess.kill('SIGINT');
- });
- // file password
- setTimeout(() => {
- if (!error) {
- nodeProcess.stdin.write(`${pw}\n`);
- pw = null; // eslint-disable-line no-param-reassign
- }
- }, 2000);
- });
- const createAccountPopup = e => {
- Windows.createPopup('requestAccount', { ownerId: e.sender.id });
- };
- // MIST API
- ipc.on('mistAPI_createAccount', createAccountPopup);
- ipc.on('mistAPI_requestAccount', e => {
- if (global.mode === 'wallet') {
- createAccountPopup(e);
- } else {
- // Mist
- // if coming from wallet, skip connect, go straight to create
- if (e.sender.history[0].includes(`file://${dirname}/wallet/index.html`)) {
- createAccountPopup(e);
- } else {
- Windows.createPopup('connectAccount', { ownerId: e.sender.id });
- }
- }
- });
- const uiLoggers = {};
- ipc.on('console_log', (event, id, logLevel, logItemsStr) => {
- try {
- const loggerId = `(ui: ${id})`;
- let windowLogger = uiLoggers[loggerId];
- if (!windowLogger) {
- windowLogger = uiLoggers[loggerId] = logger.create(loggerId);
- }
- windowLogger[logLevel](..._.toArray(JSON.parse(logItemsStr)));
- } catch (err) {
- log.error(err);
- }
- });
- ipc.on('backendAction_reloadSelectedTab', event => {
- event.sender.send('uiAction_reloadSelectedTab');
- });
|