Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parity Signer #1349

Merged
merged 20 commits into from Apr 6, 2018
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions common/actions/paritySigner/actionCreators.ts
@@ -0,0 +1,21 @@
import * as types from './actionTypes';
import { TypeKeys } from './constants';

export type TRequestSignature = typeof requestSignature;
export function requestSignature(from: string, rlp: string): types.RequestSignatureAction {
return {
type: TypeKeys.PARITY_SIGNER_REQUEST_SIGNATURE,
payload: {
from,
rlp
}
};
}

export type TFinalizeSignature = typeof finalizeSignature;
export function finalizeSignature(signature: string | null): types.FinalizeSignatureAction {
return {
type: TypeKeys.PARITY_SIGNER_FINALIZE_SIGNATURE,
payload: signature
};
}
17 changes: 17 additions & 0 deletions common/actions/paritySigner/actionTypes.ts
@@ -0,0 +1,17 @@
import { TypeKeys } from './constants';

export interface RequestSignatureAction {
type: TypeKeys.PARITY_SIGNER_REQUEST_SIGNATURE;
payload: {
rlp: string;
from: string;
};
}

export interface FinalizeSignatureAction {
type: TypeKeys.PARITY_SIGNER_FINALIZE_SIGNATURE;
payload: string | null;
}

/*** Union Type ***/
export type ParitySignerAction = RequestSignatureAction | FinalizeSignatureAction;
4 changes: 4 additions & 0 deletions common/actions/paritySigner/constants.ts
@@ -0,0 +1,4 @@
export enum TypeKeys {
PARITY_SIGNER_REQUEST_SIGNATURE = 'PARITY_SIGNER_REQUEST_SIGNATURE',
PARITY_SIGNER_FINALIZE_SIGNATURE = 'PARITY_SIGNER_FINALIZE_SIGNATURE'
}
3 changes: 3 additions & 0 deletions common/actions/paritySigner/index.ts
@@ -0,0 +1,3 @@
export * from './constants';
export * from './actionTypes';
export * from './actionCreators';
Binary file added common/assets/images/mobile/app-store-badge.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added common/assets/images/mobile/google-play-badge.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
149 changes: 149 additions & 0 deletions common/assets/images/wallets/parity-signer.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions common/components/ParityQrSigner.scss
@@ -0,0 +1,30 @@
@import 'common/sass/variables';

.ParityQrSigner {
display: flex;
align-items: center;
justify-content: center;
width: 300px;
height: 300px;
text-align: center;
margin: 0 auto 1.5em;
border-radius: 4px;
overflow: hidden;

&.is-disabled {
background: $gray-lighter;
}

&-error {
padding: $space;
font-size: $font-size-small;
color: $gray-light;

&-icon {
display: block;
font-size: 60px;
margin-bottom: $space-md;
opacity: 0.8;
}
}
}
110 changes: 110 additions & 0 deletions common/components/ParityQrSigner.tsx
@@ -0,0 +1,110 @@
import React from 'react';
import classnames from 'classnames';
import translate from 'translations';
import { Spinner } from 'components/ui';
import QrSigner from '@parity/qr-signer';
import './ParityQrSigner.scss';

interface State {
webcamError: null | React.ReactElement<any>;
isLoading: boolean;
}

interface ScanProps {
scan: true;
onScan(data: string): void;
}

interface ShowProps {
scan: false;
account: string;
rlp: string;
}

interface SharedProps {
size?: number;
}

type Props = (ScanProps | ShowProps) & SharedProps;

export default class ParityQrSigner extends React.PureComponent<Props, State> {
public state: State = {
webcamError: null,
isLoading: true
};

public componentDidMount() {
this.checkForWebcam();
if (navigator.mediaDevices) {
navigator.mediaDevices.addEventListener('devicechange', this.checkForWebcam);
}
}

public componentWillUnmount() {
if (navigator.mediaDevices && navigator.mediaDevices.ondevicechange) {
navigator.mediaDevices.removeEventListener('devicechange', this.checkForWebcam);
}
}

public checkForWebcam = async () => {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
try {
await navigator.mediaDevices.getUserMedia({ video: true });
this.setState({
webcamError: null,
isLoading: false
});
} catch (e) {
const err = e as DOMException;
let errorMessage;
switch (err.name) {
case 'NotAllowedError':
case 'SecurityError':
errorMessage = translate('ADD_PARITY_ERROR_DISABLED');
break;
case 'NotFoundError':
case 'OverconstrainedError':
errorMessage = translate('ADD_PARITY_ERROR_NO_CAM');
break;
default:
errorMessage = translate('ADD_PARITY_ERROR_UNKNOWN');
}
this.setState({
webcamError: errorMessage,
isLoading: false
});
}
}
};

public render() {
const { webcamError, isLoading } = this.state;
const size = this.props.size || 300;

return (
<div
className={classnames({
ParityQrSigner: true,
'is-disabled': !!webcamError || isLoading
})}
style={{
width: size,
height: size
}}
>
{isLoading ? (
<div className="ParityQrSigner-loader">
<Spinner size="x3" light={true} />
</div>
) : webcamError ? (
<div className="ParityQrSigner-error">
<i className="ParityQrSigner-error-icon fa fa-exclamation-circle" />
{webcamError}
</div>
) : (
<QrSigner {...this.props} size={size} />
)}
</div>
);
}
}
12 changes: 12 additions & 0 deletions common/components/WalletDecrypt/WalletDecrypt.tsx
Expand Up @@ -29,6 +29,7 @@ import {
ViewOnlyDecrypt,
Web3Decrypt,
WalletButton,
ParitySignerDecrypt,
InsecureWalletWarning
} from './components';
import { AppState } from 'reducers';
Expand All @@ -49,6 +50,8 @@ import LedgerIcon from 'assets/images/wallets/ledger.svg';
import MetamaskIcon from 'assets/images/wallets/metamask.svg';
import MistIcon from 'assets/images/wallets/mist.svg';
import TrezorIcon from 'assets/images/wallets/trezor.svg';
import ParitySignerIcon from 'assets/images/wallets/parity-signer.svg';
import { wikiLink as paritySignerHelpLink } from 'libs/wallet/non-deterministic/parity';
import './WalletDecrypt.scss';
import { withRouter, RouteComponentProps } from 'react-router';

Expand Down Expand Up @@ -168,6 +171,15 @@ const WalletDecrypt = withRouter<Props>(
unlock: this.props.setWallet,
helpLink: 'https://doc.satoshilabs.com/trezor-apps/mew.html'
},
[SecureWalletName.PARITY_SIGNER]: {
lid: 'X_PARITYSIGNER',
icon: ParitySignerIcon,
description: 'ADD_PARITY_DESC',
component: ParitySignerDecrypt,
initialParams: {},
unlock: this.props.setWallet,
helpLink: paritySignerHelpLink
},
[InsecureWalletName.KEYSTORE_FILE]: {
lid: 'X_KEYSTORE2',
example: 'UTC--2017-12-15T17-35-22.547Z--6be6e49e82425a5aa56396db03512f2cc10e95e8',
Expand Down
7 changes: 7 additions & 0 deletions common/components/WalletDecrypt/components/ParitySigner.scss
@@ -0,0 +1,7 @@
.ParitySignerUnlock {
&-badge {
display: inline-block;
height: 3em;
margin: 0 0.4em;
}
}