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

Commit

Permalink
Merge pull request #336 from paritytech/ac-signer
Browse files Browse the repository at this point in the history
Integrate Parity Signer into Fether
  • Loading branch information
amaury1093 authored Jan 15, 2019
2 parents c7a9053 + bfc3894 commit 4cdfca0
Show file tree
Hide file tree
Showing 44 changed files with 1,230 additions and 236 deletions.
12 changes: 8 additions & 4 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/contracts": "^3.0.11",
"@parity/light.js": "^3.0.11",
"@parity/light.js-react": "^3.0.11",
"@parity/abi": "^3.0.25",
"@parity/api": "^3.0.25",
"@parity/contracts": "^3.0.25",
"@parity/light.js": "^3.0.25",
"@parity/light.js-react": "^3.0.25",
"@parity/qr-signer": "^0.3.2",
"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.2.0",
"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
25 changes: 13 additions & 12 deletions packages/fether-react/src/Accounts/AccountsList/AccountsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@

import React, { Component } from 'react';
import { AccountCard, Clickable, Header } from 'fether-ui';
import { accountsInfo$, withoutLoading } from '@parity/light.js';
import { chainId$, 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';

@withAccountsInfo
@inject('createAccountStore', 'parityStore')
@light({
accountsInfo: () => accountsInfo$().pipe(withoutLoading())
chainId: () => chainId$().pipe(withoutLoading())
})
@inject('createAccountStore', 'parityStore')
@observer
class AccountsList extends Component {
handleClick = ({
Expand All @@ -34,9 +36,13 @@ class AccountsList extends Component {
};

render () {
const { accountsInfo } = this.props;
const { accountsInfo, chainId } = this.props;

const accountsList = Object.keys(accountsInfo);
const accountsList = Object.keys(accountsInfo).filter(
key =>
!accountsInfo[key].chainId ||
accountsInfo[key].chainId === parseInt(chainId, 10)
);
const accountsListLength = accountsList && accountsList.length;

return (
Expand Down Expand Up @@ -64,13 +70,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 @@ -5,20 +5,20 @@

import React, { Component } from 'react';
import { addressShort, Card, Form as FetherForm } from 'fether-ui';
import { accounts$, withoutLoading } from '@parity/light.js';
import light from '@parity/light.js-react';
import { inject, observer } from 'mobx-react';

@light({
accounts: () => accounts$().pipe(withoutLoading())
})
import Scanner from '../../../Scanner';
import withAccountsInfo from '../../../utils/withAccountsInfo';

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

handleNextStep = async () => {
Expand Down Expand Up @@ -87,11 +87,42 @@ class AccountImportOptions extends Component {
}
};

hasExistingAddressForImport = addressForImport => {
const { accounts } = this.props;
const isExistingAddress = accounts
.map(address => address && address.toLowerCase())
.includes(addressForImport.toLowerCase());
handleSignerImported = async ({ address, chainId: chainIdString }) => {
const {
createAccountStore: { importFromSigner }
} = this.props;

if (!address || !chainIdString) {
this.setState({ error: 'Invalid QR code.' });
return;
}

const chainId = parseInt(chainIdString);

if (this.hasExistingAddressForImport(address, chainId)) {
return;
}

await importFromSigner({ address, chainId });

this.handleNextStep();
};

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

hasExistingAddressForImport = (addressForImport, chainId) => {
const { accountsInfo } = this.props;
const isExistingAddress = Object.keys(accountsInfo).some(
key =>
key.toLowerCase() === addressForImport.toLowerCase() &&
(!accountsInfo[key].chainId ||
!chainId ||
accountsInfo[key].chainId === chainId)
);

if (isExistingAddress) {
this.setState({
Expand All @@ -108,46 +139,76 @@ class AccountImportOptions extends Component {
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
Loading

0 comments on commit 4cdfca0

Please sign in to comment.