Moved commands out of UI into preload

This commit is contained in:
Rémy Roy
2021-11-30 12:00:12 -05:00
parent d78de6edf0
commit d4298d5bdd
9 changed files with 109 additions and 161 deletions

View File

@@ -5,18 +5,28 @@
* *
* @module * @module
*/ */
const readdirProm = window.utilAPI.promisify(window.fsAPI.readdir);
import { promisify } from 'util';
import { constants, readdir } from 'fs';
import { access, stat } from 'fs/promises';
import path from "path";
import { fileSync } from "tmp";
const readdirProm = promisify(readdir);
/** /**
* Check for the existence of a file or a directory on the filesystem. * Check for the existence of a file or a directory on the filesystem.
* *
* @param filename The path to the file or directory. * @param filename The path to the file or directory.
* *
* @returns Returns true if the file or directory exists. Returns false if not. * @returns Returns a Promise<boolean> that includes a true value if file or directory exists.
*/ */
const doesFileExist = (filename: string): boolean => { const doesFileExist = async (filename: string): Promise<boolean> => {
try { try {
window.fsAPI.accessSync(filename, window.fsAPI.constantsFOK); await access(filename, constants.F_OK);
return true; return true;
} catch (err) { } catch (err) {
return false; return false;
@@ -28,11 +38,11 @@ const doesFileExist = (filename: string): boolean => {
* *
* @param directory The path to the directory. * @param directory The path to the directory.
* *
* @returns Returns true if the directory exists. Returns false if not. * @returns Returns a Promise<boolean> that includes a true value if the directory exists.
*/ */
const doesDirectoryExist = (directory: string): boolean => { const doesDirectoryExist = async (directory: string): Promise<boolean> => {
if (doesFileExist(directory)) { if (await doesFileExist(directory)) {
return window.fsAPI.statSync(directory).isDirectory(); return (await stat(directory)).isDirectory();
} }
return false; return false;
} }
@@ -45,16 +55,16 @@ const doesDirectoryExist = (directory: string): boolean => {
* @returns Returns true if the directory is writable and if a file can be written in the * @returns Returns true if the directory is writable and if a file can be written in the
* directory. Returns false if not. * directory. Returns false if not.
*/ */
const isDirectoryWritable = (directory: string): boolean => { const isDirectoryWritable = async (directory: string): Promise<boolean> => {
let tempFile = null; let tempFile = null;
try { try {
window.fsAPI.accessSync(directory, window.fsAPI.constantsWOK); await access(directory, constants.W_OK);
/** /**
* On Windows, checking for W_OK on a directory is not enough to tell if we can write a file in * On Windows, checking for W_OK on a directory is not enough to tell if we can write a file in
* it. We need to actually write a temporary file to check. * it. We need to actually write a temporary file to check.
*/ */
tempFile = window.tmpAPI.fileSync({ keep: false, tmpdir: directory }); tempFile = fileSync({ keep: false, tmpdir: directory });
return true; return true;
} catch (err) { } catch (err) {
@@ -80,7 +90,7 @@ const findFirstFile = async (directory: string, startsWith: string): Promise<str
for (const entry of entries) { for (const entry of entries) {
if (entry.isFile() && entry.name.startsWith(startsWith)) { if (entry.isFile() && entry.name.startsWith(startsWith)) {
return window.pathAPI.join(directory, entry.name); return path.join(directory, entry.name);
} }
} }

View File

@@ -17,13 +17,21 @@
* @module * @module
*/ */
import { Network } from '../types' import { execFile } from 'child_process';
import { doesFileExist } from "./BashUtils"; import { promisify } from 'util';
import { constants } from 'fs';
import { access, mkdir } from 'fs/promises';
import { cwd } from 'process';
import path from "path";
import process from "process";
import { doesFileExist } from './BashUtils';
/** /**
* A promise version of the execFile function from fs for CLI calls. * A promise version of the execFile function from fs for CLI calls.
*/ */
const execFileProm = window.utilAPI.promisify(window.childProcessAPI.execFile); const execFileProm = promisify(execFile);
const ETH2_DEPOSIT_DIR_NAME = "eth2.0-deposit-cli-1.2.0"; const ETH2_DEPOSIT_DIR_NAME = "eth2.0-deposit-cli-1.2.0";
@@ -31,36 +39,36 @@ const ETH2_DEPOSIT_DIR_NAME = "eth2.0-deposit-cli-1.2.0";
* Paths needed to call the eth2deposit_proxy application using the Python 3 version installed on * Paths needed to call the eth2deposit_proxy application using the Python 3 version installed on
* the current machine. * the current machine.
*/ */
const ETH2_DEPOSIT_CLI_PATH = window.pathAPI.join("src", "vendors", ETH2_DEPOSIT_DIR_NAME); const ETH2_DEPOSIT_CLI_PATH = path.join("src", "vendors", ETH2_DEPOSIT_DIR_NAME);
const SCRIPTS_PATH = window.pathAPI.join("src", "scripts"); const SCRIPTS_PATH = path.join("src", "scripts");
const REQUIREMENTS_PATH = window.pathAPI.join(ETH2_DEPOSIT_CLI_PATH, "requirements.txt"); const REQUIREMENTS_PATH = path.join(ETH2_DEPOSIT_CLI_PATH, "requirements.txt");
const WORD_LIST_PATH = window.pathAPI.join(ETH2_DEPOSIT_CLI_PATH, "eth2deposit", "key_handling", const WORD_LIST_PATH = path.join(ETH2_DEPOSIT_CLI_PATH, "eth2deposit", "key_handling",
"key_derivation", "word_lists"); "key_derivation", "word_lists");
const REQUIREMENT_PACKAGES_PATH = window.pathAPI.join("dist", "packages"); const REQUIREMENT_PACKAGES_PATH = path.join("dist", "packages");
const ETH2DEPOSIT_PROXY_PATH = window.pathAPI.join(SCRIPTS_PATH, "eth2deposit_proxy.py"); const ETH2DEPOSIT_PROXY_PATH = path.join(SCRIPTS_PATH, "eth2deposit_proxy.py");
/** /**
* Paths needed to call the eth2deposit_proxy application using a single file application (SFE) * Paths needed to call the eth2deposit_proxy application using a single file application (SFE)
* bundled with pyinstaller. * bundled with pyinstaller.
*/ */
const SFE_PATH = window.pathAPI.join("build", "bin", "eth2deposit_proxy" + const SFE_PATH = path.join("build", "bin", "eth2deposit_proxy" +
(window.processAPI.platform() == "win32" ? ".exe" : "")); (process.platform == "win32" ? ".exe" : ""));
const DIST_WORD_LIST_PATH = window.pathAPI.join(window.processAPI.cwd(), "build", "word_lists"); const DIST_WORD_LIST_PATH = path.join(cwd(), "build", "word_lists");
/** /**
* Paths needed to call the eth2deposit_proxy application from a bundled application. * Paths needed to call the eth2deposit_proxy application from a bundled application.
*/ */
const BUNDLED_SFE_PATH = window.pathAPI.join(window.processAPI.resourcesPath(), "..", "build", const BUNDLED_SFE_PATH = path.join(process.resourcesPath, "..", "build",
"bin", "eth2deposit_proxy" + (window.processAPI.platform() == "win32" ? ".exe" : "")); "bin", "eth2deposit_proxy" + (process.platform == "win32" ? ".exe" : ""));
const BUNDLED_DIST_WORD_LIST_PATH = window.pathAPI.join(window.processAPI.resourcesPath(), "..", const BUNDLED_DIST_WORD_LIST_PATH = path.join(process.resourcesPath, "..",
"build", "word_lists"); "build", "word_lists");
const CREATE_MNEMONIC_SUBCOMMAND = "create_mnemonic"; const CREATE_MNEMONIC_SUBCOMMAND = "create_mnemonic";
const GENERATE_KEYS_SUBCOMMAND = "generate_keys"; const GENERATE_KEYS_SUBCOMMAND = "generate_keys";
const VALIDATE_MNEMONIC_SUBCOMMAND = "validate_mnemonic"; const VALIDATE_MNEMONIC_SUBCOMMAND = "validate_mnemonic";
const PYTHON_EXE = (window.processAPI.platform() == "win32" ? "python" : "python3"); const PYTHON_EXE = (process.platform == "win32" ? "python" : "python3");
const PATH_DELIM = (window.processAPI.platform() == "win32" ? ";" : ":"); const PATH_DELIM = (process.platform == "win32" ? ";" : ":");
/** /**
* Install the required Python packages needed to call the eth2deposit_proxy application using the * Install the required Python packages needed to call the eth2deposit_proxy application using the
@@ -71,10 +79,10 @@ const PATH_DELIM = (window.processAPI.platform() == "win32" ? ";" : ":");
*/ */
const requireDepositPackages = async (): Promise<boolean> => { const requireDepositPackages = async (): Promise<boolean> => {
if (!window.fsAPI.existsSync(REQUIREMENT_PACKAGES_PATH)) { try {
window.fsAPI.mkdir(REQUIREMENT_PACKAGES_PATH, { recursive: true }, (err) => { await access(REQUIREMENT_PACKAGES_PATH, constants.F_OK);
if (err) throw err; } catch {
}); await mkdir(REQUIREMENT_PACKAGES_PATH, { recursive: true });
const executable = PYTHON_EXE; const executable = PYTHON_EXE;
const args = ["-m", "pip", "install", "-r", REQUIREMENTS_PATH, "--target", const args = ["-m", "pip", "install", "-r", REQUIREMENTS_PATH, "--target",
@@ -82,6 +90,7 @@ const requireDepositPackages = async (): Promise<boolean> => {
await execFileProm(executable, args); await execFileProm(executable, args);
} }
return true return true
} }
@@ -115,12 +124,12 @@ const createMnemonic = async (language: string): Promise<string> => {
let executable:string = ""; let executable:string = "";
let args:string[] = []; let args:string[] = [];
let env = Object(window.processAPI.env()); let env = process.env;
if (doesFileExist(BUNDLED_SFE_PATH)) { if (await doesFileExist(BUNDLED_SFE_PATH)) {
executable = BUNDLED_SFE_PATH; executable = BUNDLED_SFE_PATH;
args = [CREATE_MNEMONIC_SUBCOMMAND, BUNDLED_DIST_WORD_LIST_PATH, "--language", language]; args = [CREATE_MNEMONIC_SUBCOMMAND, BUNDLED_DIST_WORD_LIST_PATH, "--language", language];
} else if (doesFileExist(SFE_PATH)) { } else if (await doesFileExist(SFE_PATH)) {
executable = SFE_PATH; executable = SFE_PATH;
args = [CREATE_MNEMONIC_SUBCOMMAND, DIST_WORD_LIST_PATH, "--language", language] args = [CREATE_MNEMONIC_SUBCOMMAND, DIST_WORD_LIST_PATH, "--language", language]
} else { } else {
@@ -163,7 +172,7 @@ const generateKeys = async (
mnemonic: string, mnemonic: string,
index: number, index: number,
count: number, count: number,
network: Network, network: string,
password: string, password: string,
eth1_withdrawal_address: string, eth1_withdrawal_address: string,
folder: string, folder: string,
@@ -171,9 +180,9 @@ const generateKeys = async (
let executable:string = ""; let executable:string = "";
let args:string[] = []; let args:string[] = [];
let env = Object(window.processAPI.env()); let env = process.env;
if (doesFileExist(BUNDLED_SFE_PATH)) { if (await doesFileExist(BUNDLED_SFE_PATH)) {
executable = BUNDLED_SFE_PATH; executable = BUNDLED_SFE_PATH;
args = [GENERATE_KEYS_SUBCOMMAND]; args = [GENERATE_KEYS_SUBCOMMAND];
if ( eth1_withdrawal_address != "" ) { if ( eth1_withdrawal_address != "" ) {
@@ -182,7 +191,7 @@ const generateKeys = async (
args = args.concat([BUNDLED_DIST_WORD_LIST_PATH, mnemonic, index.toString(), count.toString(), args = args.concat([BUNDLED_DIST_WORD_LIST_PATH, mnemonic, index.toString(), count.toString(),
folder, network.toLowerCase(), password]); folder, network.toLowerCase(), password]);
} else if (doesFileExist(SFE_PATH)) { } else if (await doesFileExist(SFE_PATH)) {
executable = SFE_PATH; executable = SFE_PATH;
args = [GENERATE_KEYS_SUBCOMMAND]; args = [GENERATE_KEYS_SUBCOMMAND];
if ( eth1_withdrawal_address != "" ) { if ( eth1_withdrawal_address != "" ) {
@@ -224,12 +233,12 @@ const validateMnemonic = async (
let executable:string = ""; let executable:string = "";
let args:string[] = []; let args:string[] = [];
let env = Object(window.processAPI.env()); let env = process.env;
if (doesFileExist(BUNDLED_SFE_PATH)) { if (await doesFileExist(BUNDLED_SFE_PATH)) {
executable = BUNDLED_SFE_PATH; executable = BUNDLED_SFE_PATH;
args = [VALIDATE_MNEMONIC_SUBCOMMAND, BUNDLED_DIST_WORD_LIST_PATH, mnemonic]; args = [VALIDATE_MNEMONIC_SUBCOMMAND, BUNDLED_DIST_WORD_LIST_PATH, mnemonic];
} else if (doesFileExist(SFE_PATH)) { } else if (await doesFileExist(SFE_PATH)) {
executable = SFE_PATH; executable = SFE_PATH;
args = [VALIDATE_MNEMONIC_SUBCOMMAND, DIST_WORD_LIST_PATH, mnemonic]; args = [VALIDATE_MNEMONIC_SUBCOMMAND, DIST_WORD_LIST_PATH, mnemonic];
} else { } else {

View File

@@ -12,13 +12,9 @@ import {
OpenDialogReturnValue OpenDialogReturnValue
} from "electron"; } from "electron";
import { accessSync, statSync, readdir, constants, mkdir, existsSync } from "fs"; import { createMnemonic, generateKeys, validateMnemonic } from './Eth2Deposit';
import path from "path";
import { promisify } from "util";
import { execFile } from "child_process";
import { cwd, platform, resourcesPath, env } from "process"
import { fileSync } from "tmp"; import { doesDirectoryExist, isDirectoryWritable, findFirstFile } from './BashUtils';
const ipcRendererSendClose = () => { const ipcRendererSendClose = () => {
ipcRenderer.send('close'); ipcRenderer.send('close');
@@ -28,18 +24,6 @@ const invokeShowOpenDialog = (options: OpenDialogOptions): Promise<OpenDialogRet
return ipcRenderer.invoke('showOpenDialog', options); return ipcRenderer.invoke('showOpenDialog', options);
}; };
const getPlatform = (): string => {
return platform;
}
const getResourcesPath = (): string => {
return resourcesPath;
}
const getEnv = (): Object => {
return env;
}
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {
'shellOpenExternal': shell.openExternal, 'shellOpenExternal': shell.openExternal,
'shellShowItemInFolder': shell.showItemInFolder, 'shellShowItemInFolder': shell.showItemInFolder,
@@ -48,35 +32,14 @@ contextBridge.exposeInMainWorld('electronAPI', {
'invokeShowOpenDialog': invokeShowOpenDialog 'invokeShowOpenDialog': invokeShowOpenDialog
}); });
contextBridge.exposeInMainWorld('fsAPI', { contextBridge.exposeInMainWorld('eth2Deposit', {
'accessSync': accessSync, 'createMnemonic': createMnemonic,
'statSync': statSync, 'generateKeys': generateKeys,
'readdir': readdir, 'validateMnemonic': validateMnemonic
'constantsFOK': constants.F_OK,
'constantsWOK': constants.W_OK,
'mkdir': mkdir,
'existsSync': existsSync
}); });
contextBridge.exposeInMainWorld('pathAPI', { contextBridge.exposeInMainWorld('bashUtils', {
'join': path.join 'doesDirectoryExist': doesDirectoryExist,
}) 'isDirectoryWritable': isDirectoryWritable,
'findFirstFile': findFirstFile
contextBridge.exposeInMainWorld('utilAPI', { });
'promisify': promisify
})
contextBridge.exposeInMainWorld('childProcessAPI', {
'execFile': execFile
})
contextBridge.exposeInMainWorld('processAPI', {
'cwd': cwd,
'platform': getPlatform,
'resourcesPath': getResourcesPath,
'env': getEnv
})
contextBridge.exposeInMainWorld('tmpAPI', {
'fileSync': fileSync
})

View File

@@ -31,58 +31,23 @@ export interface IElectronAPI {
invokeShowOpenDialog: (options: OpenDialogOptions) => Promise<OpenDialogReturnValue> invokeShowOpenDialog: (options: OpenDialogOptions) => Promise<OpenDialogReturnValue>
} }
export interface IFsAPI { export interface IEth2DepositAPI {
accessSync: (path: PathLike, mode?: number | undefined) => void, createMnemonic: (language: string) => Promise<string>,
statSync: (path: string | Buffer | URL, options?) => Stats, generateKeys: (mnemonic: string, index: number, count: number, network: string,
readdir: (path: PathLike, options: { password: string, eth1_withdrawal_address: string, folder: string) => Promise<void>,
encoding?: BufferEncoding | null; validateMnemonic: (mnemonic: string) => Promise<void>
withFileTypes?: true | undefined;
} | BufferEncoding | undefined | null,
callback: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void) => void,
constantsFOK: number,
constantsWOK: number,
mkdir: (path: PathLike, options: MakeDirectoryOptions & {
recursive: true;
}, callback: (err: NodeJS.ErrnoException | null, path?: string | undefined) => void) => void,
existsSync: (path: PathLike) => boolean
} }
export interface IPathAPI { export interface IBashUtilsAPI {
join: (...paths: string[]) => string doesDirectoryExist: (directory: string) => Promise<boolean>,
} isDirectoryWritable: (directory: string) => Promise<boolean>,
findFirstFile: (directory: string, startsWith: string) => Promise<string>
export interface IUtilAPI {
promisify: (original: Function) => Function
}
export interface IUtilAPI {
promisify: (original: Function) => Function
}
export interface IChildProcessAPI {
execFile: (file: string, args: string[], options: Object,
callback: (error: Error, stdout: string | Buffer, stderr: string | Buffer) => void) => ChildProcess
}
export interface IProcessAPI {
cwd: () => string,
platform: () => string,
resourcesPath: () => string,
env: () => Object
}
export interface ITmpAPI {
fileSync: (options: FileOptions) => FileResult
} }
declare global { declare global {
interface Window { interface Window {
electronAPI: IElectronAPI, electronAPI: IElectronAPI,
fsAPI: IFsAPI eth2Deposit: IEth2DepositAPI,
pathAPI: IPathAPI, bashUtils: IBashUtilsAPI
utilAPI: IUtilAPI,
childProcessAPI: IChildProcessAPI,
processAPI: IProcessAPI,
tmpAPI: ITmpAPI
} }
} }

View File

@@ -3,8 +3,6 @@ import React, { FC, ReactElement } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { Network } from '../../types'; import { Network } from '../../types';
import { findFirstFile } from "../../commands/BashUtils";
type KeysCreatedProps = { type KeysCreatedProps = {
folderPath: string, folderPath: string,
network: Network network: Network
@@ -24,7 +22,7 @@ const LoudText = styled(Typography)`
const KeysCreated: FC<KeysCreatedProps> = (props): ReactElement => { const KeysCreated: FC<KeysCreatedProps> = (props): ReactElement => {
const openKeyLocation = () => { const openKeyLocation = () => {
findFirstFile(props.folderPath, "keystore") window.bashUtils.findFirstFile(props.folderPath, "keystore")
.then((keystoreFile) => { .then((keystoreFile) => {
let fileToLocate = props.folderPath; let fileToLocate = props.folderPath;
if (keystoreFile != "") { if (keystoreFile != "") {

View File

@@ -1,13 +1,11 @@
import { Grid, Typography } from '@material-ui/core'; import { Grid, Typography } from '@material-ui/core';
import React, { FC, ReactElement, Dispatch, SetStateAction, useState } from 'react'; import React, { FC, ReactElement, Dispatch, SetStateAction, useState } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { generateKeys } from '../commands/Eth2Deposit';
import SelectFolder from './KeyGeneratioinFlow/2-SelectFolder'; import SelectFolder from './KeyGeneratioinFlow/2-SelectFolder';
import CreatingKeys from './KeyGeneratioinFlow/3-CreatingKeys'; import CreatingKeys from './KeyGeneratioinFlow/3-CreatingKeys';
import KeysCreated from './KeyGeneratioinFlow/4-KeysCreated'; import KeysCreated from './KeyGeneratioinFlow/4-KeysCreated';
import StepNavigation from './StepNavigation'; import StepNavigation from './StepNavigation';
import { Network } from '../types'; import { Network } from '../types';
import { doesDirectoryExist, isDirectoryWritable } from '../commands/BashUtils';
import { errors } from '../constants'; import { errors } from '../constants';
const ContentGrid = styled(Grid)` const ContentGrid = styled(Grid)`
@@ -90,21 +88,25 @@ const KeyGenerationWizard: FC<Props> = (props): ReactElement => {
setFolderError(false); setFolderError(false);
setFolderErrorMsg(""); setFolderErrorMsg("");
if (!doesDirectoryExist(props.folderPath)) { window.bashUtils.doesDirectoryExist(props.folderPath)
setFolderErrorMsg(errors.FOLDER_DOES_NOT_EXISTS); .then((exists) => {
setFolderError(true); if (!exists) {
break; setFolderErrorMsg(errors.FOLDER_DOES_NOT_EXISTS);
} setFolderError(true);
} else {
if (!isDirectoryWritable(props.folderPath)) { window.bashUtils.isDirectoryWritable(props.folderPath)
setFolderErrorMsg(errors.FOLDER_IS_NOT_WRITABLE); .then((writable) => {
setFolderError(true); if (!writable) {
break; setFolderErrorMsg(errors.FOLDER_IS_NOT_WRITABLE);
} setFolderError(true);
} else {
setStep(step + 1); setStep(step + 1);
handleKeyGeneration();
handleKeyGeneration(); }
});
}
});
} else { } else {
setFolderError(true); setFolderError(true);
@@ -132,7 +134,7 @@ const KeyGenerationWizard: FC<Props> = (props): ReactElement => {
const handleKeyGeneration = () => { const handleKeyGeneration = () => {
const eth1_withdrawal_address = ""; const eth1_withdrawal_address = "";
generateKeys( window.eth2Deposit.generateKeys(
props.mnemonic, props.mnemonic,
props.keyGenerationStartIndex!, props.keyGenerationStartIndex!,
props.numberOfKeys, props.numberOfKeys,

View File

@@ -1,7 +1,6 @@
import { Grid, Typography } from '@material-ui/core'; import { Grid, Typography } from '@material-ui/core';
import React, { FC, ReactElement, useState, Dispatch, SetStateAction, useEffect } from 'react'; import React, { FC, ReactElement, useState, Dispatch, SetStateAction, useEffect } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import { createMnemonic } from '../commands/Eth2Deposit';
import { Network } from '../types'; import { Network } from '../types';
import GenerateMnemonic from './MnemonicGenerationFlow/0-GenerateMnemonic'; import GenerateMnemonic from './MnemonicGenerationFlow/0-GenerateMnemonic';
import ShowMnemonic from './MnemonicGenerationFlow/1-2-ShowMnemonic'; import ShowMnemonic from './MnemonicGenerationFlow/1-2-ShowMnemonic';
@@ -111,7 +110,7 @@ const MnemonicGenerationWizard: FC<Props> = (props): ReactElement => {
setGenerateError(false); setGenerateError(false);
setGenerateErrorMsg(""); setGenerateErrorMsg("");
createMnemonic('english').then((mnemonic) => { window.eth2Deposit.createMnemonic('english').then((mnemonic) => {
props.setMnemonic(mnemonic); props.setMnemonic(mnemonic);
}).catch((error) => { }).catch((error) => {
setStep(0); setStep(0);

View File

@@ -1,7 +1,6 @@
import { Grid, TextField, Typography } from "@material-ui/core"; import { Grid, TextField, Typography } from "@material-ui/core";
import React, { FC, ReactElement, useState, Dispatch, SetStateAction } from "react"; import React, { FC, ReactElement, useState, Dispatch, SetStateAction } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { validateMnemonic } from '../commands/Eth2Deposit';
import ValidatingMnemonic from './MnemonicImportFlow/1-ValidatingMnemonic'; import ValidatingMnemonic from './MnemonicImportFlow/1-ValidatingMnemonic';
import { errors, MNEMONIC_LENGTH } from "../constants"; import { errors, MNEMONIC_LENGTH } from "../constants";
import StepNavigation from './StepNavigation'; import StepNavigation from './StepNavigation';
@@ -48,7 +47,7 @@ const MnemonicImport: FC<Props> = (props): ReactElement => {
setStep(step + 1); setStep(step + 1);
validateMnemonic(props.mnemonic).then(() => { window.eth2Deposit.validateMnemonic(props.mnemonic).then(() => {
props.onStepForward(); props.onStepForward();
}).catch((error) => { }).catch((error) => {
setStep(0); setStep(0);

View File

@@ -54,6 +54,9 @@ module.exports = [
{ test: /\.tsx?$/, loader: 'ts-loader' } { test: /\.tsx?$/, loader: 'ts-loader' }
] ]
}, },
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
target: 'electron-preload' target: 'electron-preload'
} }
]; ];