Skip to content
This repository has been archived by the owner on May 24, 2022. It is now read-only.

Integrate Parity Signer into Fether #336

Merged
merged 15 commits into from
Jan 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/fether-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,18 @@
},
"dependencies": {
"@craco/craco": "^3.2.3",
"@parity/api": "^3.0.11",
"@parity/abi": "^3.0.11",
"@parity/api": "^3.0.25",
"@parity/contracts": "^3.0.11",
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
"@parity/light.js": "^3.0.11",
"@parity/light.js": "^3.0.25",
"@parity/light.js-react": "^3.0.11",
"@parity/qr-signer": "^0.3.1",
"bignumber.js": "^8.0.1",
"bip39": "^2.5.0",
"debounce-promise": "^3.1.0",
"debug": "^4.1.0",
"ethereumjs-tx": "^1.3.7",
"ethereumjs-util": "^6.0.0",
"ethereumjs-wallet": "^0.6.2",
"fether-ui": "^0.1.2",
"file-saver": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/fether-react/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';script-src file: http: 'unsafe-inline'; connect-src file: http: https: ws: wss:;img-src 'self' 'unsafe-inline' file: data: blob: http: https:;style-src 'unsafe-inline' file:;">
<meta http-equiv="Content-Security-Policy" content="default-src 'self';script-src file: http: blob: 'unsafe-inline'; connect-src file: http: https: ws: wss:;img-src 'self' 'unsafe-inline' file: data: blob: http: https:;style-src 'unsafe-inline' file:;">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
Expand Down
16 changes: 4 additions & 12 deletions packages/fether-react/src/Accounts/AccountsList/AccountsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@

import React, { Component } from 'react';
import { AccountCard, Header } from 'fether-ui';
import { accountsInfo$, withoutLoading } from '@parity/light.js';
import { inject, observer } from 'mobx-react';
import light from '@parity/light.js-react';

import Health from '../../Health';
import Feedback from './Feedback';
import withAccountsInfo from '../../utils/withAccountsInfo';

@light({
accountsInfo: () => accountsInfo$().pipe(withoutLoading())
})
@withAccountsInfo
@inject('createAccountStore', 'parityStore')
@observer
class AccountsList extends Component {
Expand Down Expand Up @@ -63,13 +60,8 @@ class AccountsList extends Component {
<AccountCard
address={address}
className='-clickable'
name={
accountsInfo &&
accountsInfo[address] &&
(accountsInfo[address].name
? accountsInfo[address].name
: '(No name)')
}
type={accountsInfo[address].type}
name={accountsInfo[address].name || '(no name)'}
shortAddress
/>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import React, { Component } from 'react';
import { Card, Form as FetherForm } from 'fether-ui';
import { inject, observer } from 'mobx-react';

import Scanner from '../../../Scanner';

@inject('createAccountStore')
@observer
class AccountImportOptions extends Component {
state = {
error: '',
isLoading: false,
phrase: ''
phrase: '',
importingFromSigner: false
};

handleNextStep = async () => {
Expand Down Expand Up @@ -67,51 +70,97 @@ class AccountImportOptions extends Component {
}
};

handleSignerImported = async ({ address }) => {
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
const {
createAccountStore: { setAddressOnly }
} = this.props;

await setAddressOnly(address);

this.handleNextStep();
};

handleSignerImport = () => {
this.setState({
importingFromSigner: true
});
};

render () {
const {
history,
location: { pathname }
} = this.props;
const { error, phrase } = this.state;
const { error, importingFromSigner, phrase } = this.state;
const currentStep = pathname.slice(-1);

const jsonCard = (
<div key='createAccount'>
<div className='text -centered'>
<p> Recover from JSON Keyfile </p>

<FetherForm.InputFile
label='JSON Backup Keyfile'
onChangeFile={this.handleChangeFile}
required
/>
<Card>
<div key='createAccount'>
<div className='text -centered'>
<p>Recover from JSON Keyfile</p>

<FetherForm.InputFile
label='JSON Backup Keyfile'
onChangeFile={this.handleChangeFile}
required
/>
</div>
</div>
</div>
</Card>
);

const signerCard = (
<Card>
<div key='createAccount'>
<div className='text -centered'>
<p>Recover from Parity Signer</p>

{importingFromSigner ? (
<Scanner
onScan={this.handleSignerImported}
label='Please show the QR code of the account on the webcam.'
/>
) : (
<button
className='button -footer'
onClick={this.handleSignerImport}
>
Scan QR code
</button>
)}
</div>
</div>
</Card>
);

const phraseCard = (
<div key='importBackup'>
<div className='text -centered'>
<p>Recover from Seed Phrase</p>

<FetherForm.Field
as='textarea'
label='Recovery phrase'
onChange={this.handlePhraseChange}
required
phrase={phrase}
/>

{this.renderButton()}
<Card>
<div key='importBackup'>
<div className='text -centered'>
<p>Recover from Seed Phrase</p>

<FetherForm.Field
as='textarea'
label='Recovery phrase'
onChange={this.handlePhraseChange}
required
phrase={phrase}
/>

{this.renderButton()}
</div>
</div>
</div>
</Card>
);

return (
<div className='center-md'>
<Card> {jsonCard} </Card>
{!importingFromSigner && jsonCard}
<br />
{signerCard}
<br />
<Card> {phraseCard} </Card>
{!importingFromSigner && phraseCard}
<br />
<p>{error}</p>
<nav className='form-nav -space-around'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,32 @@ class AccountName extends Component {

handleSubmit = () => {
const {
createAccountStore,
history,
location: { pathname }
} = this.props;

const currentStep = pathname.slice(-1);

history.push(`/accounts/new/${+currentStep + 1}`);

if (createAccountStore.noPrivateKey()) {
// Save Signer account to Parity without asking for a password
createAccountStore
.saveAccountToParity()
.then(res => {
createAccountStore.clear();
history.push('/accounts');
})
.catch(err => {
console.error(err);

this.setState({
error: err.text
});
});
} else {
// Ask for a password otherwise
history.push(`/accounts/new/${+currentStep + 1}`);
}
};

render () {
Expand All @@ -45,12 +64,13 @@ class AccountName extends Component {

renderCardWhenImported = () => {
const {
createAccountStore: { address, name }
createAccountStore: { address, name, noPrivateKey }
} = this.props;

return (
<AccountCard
address={address}
type={noPrivateKey() ? 'signer' : 'node'}
drawers={[this.renderDrawer()]}
name={name || '(no name)'}
/>
Expand Down Expand Up @@ -89,6 +109,7 @@ class AccountName extends Component {
renderDrawer = () => {
const {
createAccountStore: { address, name },
error,
history,
location: { pathname }
} = this.props;
Expand All @@ -107,6 +128,7 @@ class AccountName extends Component {
type='text'
value={name}
/>
{error && <p>{error}</p>}
<nav className='form-nav -space-around'>
{currentStep > 1 && (
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class AccountPassword extends Component {
const { createAccountStore, history } = this.props;
const { confirm, password } = this.state;

event && event.preventDefault();
event.preventDefault();

if (!createAccountStore.jsonString && confirm !== password) {
this.setState({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
// SPDX-License-Identifier: BSD-3-Clause

import React, { Component } from 'react';
import { accountsInfo$ } from '@parity/light.js';
import { Header } from 'fether-ui';
import { inject, observer } from 'mobx-react';
import light from '@parity/light.js-react';
import { Link, Route } from 'react-router-dom';

import AccountCopyPhrase from './AccountCopyPhrase';
Expand All @@ -16,9 +14,10 @@ import AccountRewritePhrase from './AccountRewritePhrase';
import AccountName from './AccountName';
import AccountPassword from './AccountPassword';
import Health from '../../Health';
import withAccountsInfo from '../../utils/withAccountsInfo';

@light({ accountsInfo: accountsInfo$ })
@inject('createAccountStore')
@withAccountsInfo
@observer
class CreateAccount extends Component {
constructor (props) {
Expand All @@ -45,7 +44,6 @@ class CreateAccount extends Component {
} = this.props;
createAccountStore.clear();
createAccountStore.setIsImport(!createAccountStore.isImport);

// If we were further in the account creation, go back to step 1
if (step > 1) {
history.push('/accounts/new/1');
Expand Down
27 changes: 10 additions & 17 deletions packages/fether-react/src/BackupAccount/BackupAccount.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,13 @@
import React, { Component } from 'react';
import { AccountHeader, Card, Form as FetherForm } from 'fether-ui';
import { observer } from 'mobx-react';
import { accountsInfo$ } from '@parity/light.js';
import light from '@parity/light.js-react';
import { Link, withRouter } from 'react-router-dom';

import backupAccount from '../utils/backupAccount';
import withAccount from '../utils/withAccount';

@withRouter
@withAccount
@light({
accountsInfo: accountsInfo$
})
@observer
class BackupAccount extends Component {
state = {
Expand All @@ -31,14 +26,17 @@ class BackupAccount extends Component {
};

handleSubmit = event => {
const { accountAddress, history } = this.props;
const {
account: { address },
history
} = this.props;
const { password } = this.state;

event && event.preventDefault();

this.setState({ isLoading: true });

backupAccount(accountAddress, password)
backupAccount(address, password)
.then(res => {
/*
FIXME: this timeout is a placeholder for after the backup file is saved.
Expand All @@ -58,23 +56,18 @@ class BackupAccount extends Component {

render () {
const {
accountsInfo,
history,
location: { pathname }
account: { name, address, type },
history
} = this.props;
const { isLoading, message, password } = this.state;
const accountAddress = pathname.slice(-42);

return (
<div>
<AccountHeader
address={accountAddress}
address={address}
copyAddress
name={
accountsInfo &&
accountsInfo[accountAddress] &&
accountsInfo[accountAddress].name
}
name={name}
type={type}
left={
<Link to='/accounts' className='icon -back'>
Back
Expand Down
Loading