From 3bea632a9a6f7e58f4ca451471add24833cde02b Mon Sep 17 00:00:00 2001 From: HenryNguyen5 Date: Tue, 7 Nov 2017 13:42:53 -0500 Subject: [PATCH] EthereumJS-Wallet (Part 2) (#310) * Progress commit -- ethereumjs-wallet typings * Add hdkey module + better wallet typing * Add provider-engine typings * Add jsdoc descriptions for hdkey constructor methods * Fix missing return type * Fix another missing return * Make provider engine options optional * Add priv/pubkey members to wallet instance * Turn into SFC + Use ethereumjs-lib * Use proper interface naming for V3Wallet * Switch to ethereumjs-wallet * Switch to ethereumjs-wallet and refactor using NewTabLink * Use proper interface naming for V3Wallet * Use proper interface naming for PublicKeyOnlyWallet * Fix broken test, re-add scryptsy to make this PR pass * Fix definition module for thirdparty wallets * Decrease n-factor to 1024, checksum address of keystore * Update typedef for react-dom from 15 to 16 * Lock react-dom, set typescript to 2.5.2 --- .../actions/generateWallet/actionCreators.ts | 4 +- common/actions/generateWallet/actionTypes.ts | 4 +- common/components/PrintableWallet/index.tsx | 108 +- common/components/ui/NewTabLink.tsx | 7 +- .../components/CryptoWarning.tsx | 43 +- .../components/DownloadWallet.tsx | 81 +- .../GenerateWallet/components/PaperWallet.tsx | 176 +- .../containers/Tabs/GenerateWallet/index.tsx | 9 +- common/reducers/generateWallet.ts | 4 +- common/utils/isMobile.ts | 6 +- package-lock.json | 6187 ++++++++--------- package.json | 10 +- 12 files changed, 3085 insertions(+), 3554 deletions(-) diff --git a/common/actions/generateWallet/actionCreators.ts b/common/actions/generateWallet/actionCreators.ts index 896d6ffc..2ae69f21 100644 --- a/common/actions/generateWallet/actionCreators.ts +++ b/common/actions/generateWallet/actionCreators.ts @@ -1,4 +1,4 @@ -import { PrivKeyWallet } from 'libs/wallet'; +import { generate } from 'ethereumjs-wallet'; import * as interfaces from './actionTypes'; import { TypeKeys } from './constants'; @@ -8,7 +8,7 @@ export function generateNewWallet( ): interfaces.GenerateNewWalletAction { return { type: TypeKeys.GENERATE_WALLET_GENERATE_WALLET, - wallet: PrivKeyWallet.generate(), + wallet: generate(), password }; } diff --git a/common/actions/generateWallet/actionTypes.ts b/common/actions/generateWallet/actionTypes.ts index 9bbecb70..bfb811fd 100644 --- a/common/actions/generateWallet/actionTypes.ts +++ b/common/actions/generateWallet/actionTypes.ts @@ -1,10 +1,10 @@ -import { PrivKeyWallet } from 'libs/wallet'; +import { IFullWallet } from 'ethereumjs-wallet'; import { TypeKeys } from './constants'; /*** Generate Wallet File ***/ export interface GenerateNewWalletAction { type: TypeKeys.GENERATE_WALLET_GENERATE_WALLET; - wallet: PrivKeyWallet; + wallet: IFullWallet; password: string; } diff --git a/common/components/PrintableWallet/index.tsx b/common/components/PrintableWallet/index.tsx index 4bde0fe0..bbabe064 100644 --- a/common/components/PrintableWallet/index.tsx +++ b/common/components/PrintableWallet/index.tsx @@ -1,71 +1,53 @@ import { PaperWallet } from 'components'; -import PrivKeyWallet from 'libs/wallet/privkey'; -import React, { Component } from 'react'; +import { IFullWallet } from 'ethereumjs-wallet'; +import React from 'react'; import translate from 'translations'; import printElement from 'utils/printElement'; -interface Props { - wallet: PrivKeyWallet; -} +const print = (address: string, privateKey: string) => () => + address && + privateKey && + printElement(, { + popupFeatures: { + scrollbars: 'no' + }, + styles: ` + * { + box-sizing: border-box; + } -interface State { - address: string | null; - privateKey: string | null; -} + body { + font-family: Lato, sans-serif; + font-size: 1rem; + line-height: 1.4; + margin: 0; + } + ` + }); -const initialState = { - address: null, - privateKey: null +const PrintableWallet: React.SFC<{ wallet: IFullWallet }> = ({ wallet }) => { + const address = wallet.getAddressString(); + const privateKey = wallet.getPrivateKeyString(); + + if (!address || !privateKey) { + return null; + } + + return ( +
+ + + {translate('x_Print')} + +
+ ); }; -export default class PrintableWallet extends Component { - public state: State = initialState; - - public async componentDidMount() { - const address = await this.props.wallet.getAddress(); - const privateKey = this.props.wallet.getPrivateKey(); - this.setState({ address, privateKey }); - } - - public print = () => { - const { address, privateKey } = this.state; - if (address && privateKey) { - printElement(, { - popupFeatures: { - scrollbars: 'no' - }, - styles: ` - * { - box-sizing: border-box; - } - - body { - font-family: Lato, sans-serif; - font-size: 1rem; - line-height: 1.4; - margin: 0; - } - ` - }); - } - }; - - public render() { - const { address, privateKey } = this.state; - return address && privateKey ? ( -
- - - {translate('x_Print')} - -
- ) : null; - } -} +export default PrintableWallet; diff --git a/common/components/ui/NewTabLink.tsx b/common/components/ui/NewTabLink.tsx index 8d5a21f5..fa74a270 100644 --- a/common/components/ui/NewTabLink.tsx +++ b/common/components/ui/NewTabLink.tsx @@ -29,14 +29,15 @@ interface AAttributes { type?: string; } -interface NewTabLinkProps extends AAttributes { +interface NewTabLinkProps extends AAttributes { content?: React.ReactElement | string; children?: React.ReactElement | string; } -const NewTabLink = ({ content, children, ...rest }: NewTabLinkProps) => +const NewTabLink = ({ content, children, ...rest }: NewTabLinkProps) => ( {content || children} {/* Keep content for short-hand text insertion */} - ; + +); export default NewTabLink; diff --git a/common/containers/Tabs/GenerateWallet/components/CryptoWarning.tsx b/common/containers/Tabs/GenerateWallet/components/CryptoWarning.tsx index 14e42a1a..0fd75caa 100644 --- a/common/containers/Tabs/GenerateWallet/components/CryptoWarning.tsx +++ b/common/containers/Tabs/GenerateWallet/components/CryptoWarning.tsx @@ -7,33 +7,39 @@ import chromeIcon from 'assets/images/browsers/chrome.svg'; import operaIcon from 'assets/images/browsers/opera.svg'; import './CryptoWarning.scss'; -const BROWSERS = [{ - name: "Firefox", - href: "https://www.mozilla.org/en-US/firefox/new/", - icon: firefoxIcon, -}, { - name: "Chrome", - href: "https://www.google.com/chrome/browser/desktop/index.html", - icon: chromeIcon, -}, { - name: "Opera", - href: "http://www.opera.com/", - icon: operaIcon, -}]; +const BROWSERS = [ + { + name: 'Firefox', + href: 'https://www.mozilla.org/en-US/firefox/new/', + icon: firefoxIcon + }, + { + name: 'Chrome', + href: 'https://www.google.com/chrome/browser/desktop/index.html', + icon: chromeIcon + }, + { + name: 'Opera', + href: 'http://www.opera.com/', + icon: operaIcon + } +]; -const CryptoWarning: React.SFC<{}> = () => +const CryptoWarning: React.SFC<{}> = () => (

Your Browser Cannot Generate a Wallet

- {isMobile ? ` + {isMobile + ? ` MyEtherWallet requires certain features for secure wallet generation that your browser doesn't offer. You can still securely use the site otherwise. To generate a wallet, please use your device's default browser, or switch to a laptop or desktop computer. - ` : ` + ` + : ` MyEtherWallet requires certain features for secure wallet generation that your browser doesn't offer. You can still securely use the site otherwise. To generate a wallet, upgrade to one of the following @@ -42,7 +48,7 @@ const CryptoWarning: React.SFC<{}> = () =>

- {BROWSERS.map((browser) => + {BROWSERS.map(browser => ( = () =>
- )} + ))}
+); export default CryptoWarning; diff --git a/common/containers/Tabs/GenerateWallet/components/DownloadWallet.tsx b/common/containers/Tabs/GenerateWallet/components/DownloadWallet.tsx index 0f919921..65523458 100644 --- a/common/containers/Tabs/GenerateWallet/components/DownloadWallet.tsx +++ b/common/containers/Tabs/GenerateWallet/components/DownloadWallet.tsx @@ -1,6 +1,7 @@ import { ContinueToPaperAction } from 'actions/generateWallet'; -import { getV3Filename, UtcKeystore } from 'libs/keystore'; -import PrivKeyWallet from 'libs/wallet/privkey'; +import { IFullWallet, IV3Wallet } from 'ethereumjs-wallet'; +import { toChecksumAddress } from 'ethereumjs-util'; +import { NewTabLink } from 'components/ui'; import React, { Component } from 'react'; import translate from 'translations'; import { makeBlob } from 'utils/blob'; @@ -8,46 +9,35 @@ import './DownloadWallet.scss'; import Template from './Template'; interface Props { - wallet: PrivKeyWallet; + wallet: IFullWallet; password: string; continueToPaper(): ContinueToPaperAction; } interface State { hasDownloadedWallet: boolean; - address: string; - keystore: UtcKeystore | null; + keystore: IV3Wallet | null; } export default class DownloadWallet extends Component { public state: State = { hasDownloadedWallet: false, - address: '', keystore: null }; - public componentDidMount() { - this.props.wallet.getAddress().then(address => { - this.setState({ address }); - }); + public componentWillMount() { + this.setWallet(this.props.wallet, this.props.password); } - public componentWillMount() { - this.props.wallet.toKeystore(this.props.password).then(utcKeystore => { - this.setState({ keystore: utcKeystore }); - }); - } public componentWillUpdate(nextProps: Props) { if (this.props.wallet !== nextProps.wallet) { - nextProps.wallet.toKeystore(nextProps.password).then(utcKeystore => { - this.setState({ keystore: utcKeystore }); - }); + this.setWallet(nextProps.wallet, nextProps.password); } } public render() { const { hasDownloadedWallet } = this.state; - const filename = this.getFilename(); + const filename = this.props.wallet.getV3Filename(); const content = (
@@ -112,22 +102,14 @@ export default class DownloadWallet extends Component {

{translate('GEN_Help_4')}

@@ -136,28 +118,23 @@ export default class DownloadWallet extends Component { return