Enable Parity Signer Message Signing (#1663)
* Enable Parity Signer to sign messages * Verify that message signature is correct * Type systems are awesome :)
This commit is contained in:
parent
5542791af8
commit
cf59688896
|
@ -0,0 +1,28 @@
|
|||
import * as interfaces from './actionTypes';
|
||||
import { TypeKeys } from './constants';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
|
||||
export type TSignMessageRequested = typeof signMessageRequested;
|
||||
export function signMessageRequested(payload: string): interfaces.SignMessageRequestedAction {
|
||||
return {
|
||||
type: TypeKeys.SIGN_MESSAGE_REQUESTED,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export type TSignLocalMessageSucceeded = typeof signLocalMessageSucceeded;
|
||||
export function signLocalMessageSucceeded(
|
||||
payload: ISignedMessage
|
||||
): interfaces.SignLocalMessageSucceededAction {
|
||||
return {
|
||||
type: TypeKeys.SIGN_LOCAL_MESSAGE_SUCCEEDED,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export type TSignMessageFailed = typeof signMessageFailed;
|
||||
export function signMessageFailed(): interfaces.SignMessageFailedAction {
|
||||
return {
|
||||
type: TypeKeys.SIGN_MESSAGE_FAILED
|
||||
};
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
import { TypeKeys } from './constants';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
|
||||
export interface SignMessageRequestedAction {
|
||||
type: TypeKeys.SIGN_MESSAGE_REQUESTED;
|
||||
payload: string;
|
||||
}
|
||||
|
||||
export interface SignLocalMessageSucceededAction {
|
||||
type: TypeKeys.SIGN_LOCAL_MESSAGE_SUCCEEDED;
|
||||
payload: ISignedMessage;
|
||||
}
|
||||
|
||||
export interface SignMessageFailedAction {
|
||||
type: TypeKeys.SIGN_MESSAGE_FAILED;
|
||||
}
|
||||
|
||||
/*** Union Type ***/
|
||||
export type MessageAction =
|
||||
| SignMessageRequestedAction
|
||||
| SignLocalMessageSucceededAction
|
||||
| SignMessageFailedAction;
|
|
@ -0,0 +1,5 @@
|
|||
export enum TypeKeys {
|
||||
SIGN_MESSAGE_REQUESTED = 'SIGN_MESSAGE_REQUESTED',
|
||||
SIGN_LOCAL_MESSAGE_SUCCEEDED = 'SIGN_LOCAL_MESSAGE_SUCCEEDED',
|
||||
SIGN_MESSAGE_FAILED = 'SIGN_MESSAGE_FAILED'
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export * from './actionCreators';
|
||||
export * from './constants';
|
||||
export * from './actionTypes';
|
|
@ -1,13 +1,32 @@
|
|||
import * as types from './actionTypes';
|
||||
import { TypeKeys } from './constants';
|
||||
|
||||
export type TRequestSignature = typeof requestSignature;
|
||||
export function requestSignature(from: string, rlp: string): types.RequestSignatureAction {
|
||||
export type TRequestTransactionSignature = typeof requestTransactionSignature;
|
||||
export function requestTransactionSignature(
|
||||
from: string,
|
||||
data: string
|
||||
): types.RequestTransactionSignatureAction {
|
||||
return {
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_SIGNATURE,
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_TX_SIGNATURE,
|
||||
payload: {
|
||||
isMessage: false,
|
||||
from,
|
||||
rlp
|
||||
data
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export type TRequestMessageSignature = typeof requestMessageSignature;
|
||||
export function requestMessageSignature(
|
||||
from: string,
|
||||
data: string
|
||||
): types.RequestMessageSignatureAction {
|
||||
return {
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_MSG_SIGNATURE,
|
||||
payload: {
|
||||
isMessage: true,
|
||||
from,
|
||||
data
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,19 @@
|
|||
import { TypeKeys } from './constants';
|
||||
|
||||
export interface RequestSignatureAction {
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_SIGNATURE;
|
||||
export interface RequestTransactionSignatureAction {
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_TX_SIGNATURE;
|
||||
payload: {
|
||||
rlp: string;
|
||||
isMessage: false;
|
||||
data: string;
|
||||
from: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface RequestMessageSignatureAction {
|
||||
type: TypeKeys.PARITY_SIGNER_REQUEST_MSG_SIGNATURE;
|
||||
payload: {
|
||||
isMessage: true;
|
||||
data: string;
|
||||
from: string;
|
||||
};
|
||||
}
|
||||
|
@ -14,4 +24,7 @@ export interface FinalizeSignatureAction {
|
|||
}
|
||||
|
||||
/*** Union Type ***/
|
||||
export type ParitySignerAction = RequestSignatureAction | FinalizeSignatureAction;
|
||||
export type ParitySignerAction =
|
||||
| RequestTransactionSignatureAction
|
||||
| RequestMessageSignatureAction
|
||||
| FinalizeSignatureAction;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
export enum TypeKeys {
|
||||
PARITY_SIGNER_REQUEST_SIGNATURE = 'PARITY_SIGNER_REQUEST_SIGNATURE',
|
||||
PARITY_SIGNER_REQUEST_TX_SIGNATURE = 'PARITY_SIGNER_REQUEST_TX_SIGNATURE',
|
||||
PARITY_SIGNER_REQUEST_MSG_SIGNATURE = 'PARITY_SIGNER_REQUEST_MSG_SIGNATURE',
|
||||
PARITY_SIGNER_FINALIZE_SIGNATURE = 'PARITY_SIGNER_FINALIZE_SIGNATURE'
|
||||
}
|
||||
|
|
|
@ -18,7 +18,8 @@ interface ScanProps {
|
|||
interface ShowProps {
|
||||
scan: false;
|
||||
account: string;
|
||||
rlp: string;
|
||||
data?: string;
|
||||
rlp?: string;
|
||||
}
|
||||
|
||||
interface SharedProps {
|
||||
|
|
|
@ -22,10 +22,9 @@ export const DISABLE_WALLETS: { [key in WalletMode]: DisabledWallets } = {
|
|||
}
|
||||
},
|
||||
[WalletMode.UNABLE_TO_SIGN]: {
|
||||
wallets: [SecureWalletName.TREZOR, SecureWalletName.PARITY_SIGNER, MiscWalletName.VIEW_ONLY],
|
||||
wallets: [SecureWalletName.TREZOR, MiscWalletName.VIEW_ONLY],
|
||||
reasons: {
|
||||
[SecureWalletName.TREZOR]: 'This wallet can’t sign messages',
|
||||
[SecureWalletName.PARITY_SIGNER]: 'This wallet can’t sign messages',
|
||||
[MiscWalletName.VIEW_ONLY]: 'This wallet can’t sign messages'
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,9 @@ interface PropsClosed {
|
|||
|
||||
interface PropsOpen {
|
||||
isOpen: true;
|
||||
rlp: string;
|
||||
isMessage: boolean;
|
||||
from: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
interface ActionProps {
|
||||
|
@ -40,7 +41,7 @@ class QrSignerModal extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
const { scan } = this.state;
|
||||
const { from, rlp } = this.props;
|
||||
const { from, data, isMessage } = this.props;
|
||||
|
||||
const buttons: IButton[] = [
|
||||
{
|
||||
|
@ -60,7 +61,7 @@ class QrSignerModal extends React.Component<Props, State> {
|
|||
return (
|
||||
<div className="QrSignerModal">
|
||||
<Modal
|
||||
title={translateRaw('DEP_SIGNTX')}
|
||||
title={translateRaw(isMessage ? 'NAV_SIGNMSG' : 'DEP_SIGNTX')}
|
||||
isOpen={true}
|
||||
buttons={buttons}
|
||||
handleClose={this.onClose}
|
||||
|
@ -68,8 +69,10 @@ class QrSignerModal extends React.Component<Props, State> {
|
|||
<div className="QrSignerModal-qr-bounds">
|
||||
{scan ? (
|
||||
<ParityQrSigner scan={true} onScan={this.onScan} />
|
||||
) : isMessage ? (
|
||||
<ParityQrSigner scan={false} account={from} data={data} />
|
||||
) : (
|
||||
<ParityQrSigner scan={false} account={from} rlp={rlp} />
|
||||
<ParityQrSigner scan={false} account={from} rlp={data} />
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
|
@ -103,12 +106,9 @@ function mapStateToProps(state: AppState): PropsClosed | PropsOpen {
|
|||
return { isOpen: false };
|
||||
}
|
||||
|
||||
const { from, rlp } = requested;
|
||||
|
||||
return {
|
||||
isOpen: true,
|
||||
from,
|
||||
rlp
|
||||
...requested
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
import React from 'react';
|
||||
import translate from 'translations';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
import { IFullWallet } from 'libs/wallet';
|
||||
import { TShowNotification } from 'actions/notifications';
|
||||
import { TSignMessageRequested } from 'actions/message';
|
||||
|
||||
interface Props {
|
||||
wallet: IFullWallet;
|
||||
message: string;
|
||||
showNotification: TShowNotification;
|
||||
onSignMessage(msg: ISignedMessage): any;
|
||||
signMessageRequested: TSignMessageRequested;
|
||||
}
|
||||
|
||||
export default class SignMessageButton extends React.Component<Props, {}> {
|
||||
|
@ -20,24 +16,9 @@ export default class SignMessageButton extends React.Component<Props, {}> {
|
|||
);
|
||||
}
|
||||
|
||||
private handleSignMessage = async () => {
|
||||
const { wallet, message, showNotification, onSignMessage } = this.props;
|
||||
private handleSignMessage = () => {
|
||||
const { signMessageRequested, message } = this.props;
|
||||
|
||||
try {
|
||||
const signedMessage: ISignedMessage = {
|
||||
address: wallet.getAddressString(),
|
||||
msg: message,
|
||||
sig: await wallet.signMessage(message),
|
||||
version: '2'
|
||||
};
|
||||
|
||||
onSignMessage(signedMessage);
|
||||
showNotification(
|
||||
'success',
|
||||
translate('SIGN_MSG_SUCCESS', { $address: signedMessage.address })
|
||||
);
|
||||
} catch (err) {
|
||||
showNotification('danger', translate('SIGN_MSG_FAIL', { $err: err.message }));
|
||||
}
|
||||
signMessageRequested(message);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
|||
import { connect } from 'react-redux';
|
||||
import WalletDecrypt, { DISABLE_WALLETS } from 'components/WalletDecrypt';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { showNotification, TShowNotification } from 'actions/notifications';
|
||||
import { signMessageRequested, TSignMessageRequested } from 'actions/message';
|
||||
import { resetWallet, TResetWallet } from 'actions/wallet';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
import { IFullWallet } from 'libs/wallet';
|
||||
|
@ -15,18 +15,17 @@ import { TextArea, CodeBlock } from 'components/ui';
|
|||
interface Props {
|
||||
wallet: IFullWallet;
|
||||
unlocked: boolean;
|
||||
showNotification: TShowNotification;
|
||||
signMessageRequested: TSignMessageRequested;
|
||||
signedMessage: ISignedMessage | null;
|
||||
resetWallet: TResetWallet;
|
||||
}
|
||||
|
||||
interface State {
|
||||
message: string;
|
||||
signedMessage: ISignedMessage | null;
|
||||
}
|
||||
|
||||
const initialState: State = {
|
||||
message: '',
|
||||
signedMessage: null
|
||||
message: ''
|
||||
};
|
||||
|
||||
const messagePlaceholder = translateRaw('SIGN_MSG_PLACEHOLDER');
|
||||
|
@ -39,8 +38,8 @@ export class SignMessage extends Component<Props, State> {
|
|||
}
|
||||
|
||||
public render() {
|
||||
const { wallet, unlocked } = this.props;
|
||||
const { message, signedMessage } = this.state;
|
||||
const { unlocked, signedMessage } = this.props;
|
||||
const { message } = this.state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -68,10 +67,8 @@ export class SignMessage extends Component<Props, State> {
|
|||
</div>
|
||||
|
||||
<SignButton
|
||||
wallet={wallet}
|
||||
message={this.state.message}
|
||||
showNotification={this.props.showNotification}
|
||||
onSignMessage={this.onSignMessage}
|
||||
signMessageRequested={this.props.signMessageRequested}
|
||||
/>
|
||||
|
||||
{signedMessage && (
|
||||
|
@ -97,21 +94,17 @@ export class SignMessage extends Component<Props, State> {
|
|||
this.setState({ message });
|
||||
};
|
||||
|
||||
private onSignMessage = (signedMessage: ISignedMessage) => {
|
||||
this.setState({ signedMessage });
|
||||
};
|
||||
|
||||
private changeWallet = () => {
|
||||
this.props.resetWallet();
|
||||
};
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState) => ({
|
||||
wallet: state.wallet.inst,
|
||||
signedMessage: state.message.signed,
|
||||
unlocked: isWalletFullyUnlocked(state)
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, {
|
||||
showNotification,
|
||||
signMessageRequested,
|
||||
resetWallet
|
||||
})(SignMessage);
|
||||
|
|
|
@ -92,7 +92,7 @@ export class VerifyMessage extends Component<Props, State> {
|
|||
this.props.showNotification('success', translate('SUCCESS_7'));
|
||||
} catch (err) {
|
||||
this.clearVerifiedData();
|
||||
this.props.showNotification('danger', translate('ERROR_12'));
|
||||
this.props.showNotification('danger', translate('ERROR_38'));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -10,10 +10,9 @@ export default class ParitySignerWallet implements IFullWallet {
|
|||
}
|
||||
|
||||
public signRawTransaction = () =>
|
||||
Promise.reject(new Error('Web3 wallets cannot sign raw transactions.'));
|
||||
Promise.reject(new Error('Parity Signer cannot sign raw transactions.'));
|
||||
|
||||
public signMessage = () =>
|
||||
Promise.reject(new Error('Signing via Parity Signer not yet supported.'));
|
||||
public signMessage = () => Promise.reject(new Error('Parity Signer cannot sign messages.'));
|
||||
|
||||
public getAddressString() {
|
||||
return this.address;
|
||||
|
|
|
@ -9,6 +9,7 @@ import { rates, State as RatesState } from './rates';
|
|||
import { State as SwapState, swap } from './swap';
|
||||
import { State as WalletState, wallet } from './wallet';
|
||||
import { State as TransactionState, transaction } from './transaction';
|
||||
import { State as MessageState, message } from './message';
|
||||
import { State as GasState, gas } from './gas';
|
||||
import { onboardStatus, State as OnboardStatusState } from './onboardStatus';
|
||||
import { State as TransactionsState, transactions } from './transactions';
|
||||
|
@ -28,6 +29,7 @@ export interface AppState {
|
|||
swap: SwapState;
|
||||
transaction: TransactionState;
|
||||
transactions: TransactionsState;
|
||||
message: MessageState;
|
||||
paritySigner: ParitySignerState;
|
||||
gas: GasState;
|
||||
schedule: ScheduleState;
|
||||
|
@ -47,6 +49,7 @@ export default combineReducers<AppState>({
|
|||
deterministicWallets,
|
||||
transaction,
|
||||
transactions,
|
||||
message,
|
||||
paritySigner,
|
||||
gas,
|
||||
schedule,
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { MessageAction, SignLocalMessageSucceededAction, TypeKeys } from 'actions/message';
|
||||
import { ISignedMessage } from 'libs/signing';
|
||||
|
||||
export interface State {
|
||||
signed?: ISignedMessage | null;
|
||||
}
|
||||
|
||||
export const INITIAL_STATE: State = {
|
||||
signed: null
|
||||
};
|
||||
|
||||
function signLocalMessageSucceeded(state: State, action: SignLocalMessageSucceededAction): State {
|
||||
return {
|
||||
...state,
|
||||
signed: action.payload
|
||||
};
|
||||
}
|
||||
|
||||
function signMessageFailed(state: State): State {
|
||||
return {
|
||||
...state,
|
||||
signed: null
|
||||
};
|
||||
}
|
||||
|
||||
export function message(state: State = INITIAL_STATE, action: MessageAction): State {
|
||||
switch (action.type) {
|
||||
case TypeKeys.SIGN_LOCAL_MESSAGE_SUCCEEDED:
|
||||
return signLocalMessageSucceeded(state, action);
|
||||
case TypeKeys.SIGN_MESSAGE_FAILED:
|
||||
return signMessageFailed(state);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -1,19 +1,35 @@
|
|||
import { ParitySignerAction, RequestSignatureAction, TypeKeys } from 'actions/paritySigner';
|
||||
import {
|
||||
ParitySignerAction,
|
||||
RequestTransactionSignatureAction,
|
||||
RequestMessageSignatureAction,
|
||||
TypeKeys
|
||||
} from 'actions/paritySigner';
|
||||
|
||||
export interface State {
|
||||
requested?: QrSignatureState | null;
|
||||
}
|
||||
|
||||
interface QrSignatureState {
|
||||
isMessage: boolean;
|
||||
from: string;
|
||||
rlp: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export const INITIAL_STATE: State = {
|
||||
requested: null
|
||||
};
|
||||
|
||||
function requestSignature(state: State, action: RequestSignatureAction): State {
|
||||
function requestTransactionSignature(
|
||||
state: State,
|
||||
action: RequestTransactionSignatureAction
|
||||
): State {
|
||||
return {
|
||||
...state,
|
||||
requested: action.payload
|
||||
};
|
||||
}
|
||||
|
||||
function requestMessageSignature(state: State, action: RequestMessageSignatureAction): State {
|
||||
return {
|
||||
...state,
|
||||
requested: action.payload
|
||||
|
@ -29,8 +45,10 @@ function finalizeSignature(state: State): State {
|
|||
|
||||
export function paritySigner(state: State = INITIAL_STATE, action: ParitySignerAction): State {
|
||||
switch (action.type) {
|
||||
case TypeKeys.PARITY_SIGNER_REQUEST_SIGNATURE:
|
||||
return requestSignature(state, action);
|
||||
case TypeKeys.PARITY_SIGNER_REQUEST_TX_SIGNATURE:
|
||||
return requestTransactionSignature(state, action);
|
||||
case TypeKeys.PARITY_SIGNER_REQUEST_MSG_SIGNATURE:
|
||||
return requestMessageSignature(state, action);
|
||||
case TypeKeys.PARITY_SIGNER_FINALIZE_SIGNATURE:
|
||||
return finalizeSignature(state);
|
||||
default:
|
||||
|
|
|
@ -8,6 +8,7 @@ import swapRates from './swap/rates';
|
|||
import wallet from './wallet';
|
||||
import { ens } from './ens';
|
||||
import { transaction } from './transaction';
|
||||
import { message } from './message';
|
||||
import transactions from './transactions';
|
||||
import gas from './gas';
|
||||
import { schedule } from './schedule';
|
||||
|
@ -21,6 +22,7 @@ export default {
|
|||
notifications,
|
||||
wallet,
|
||||
transaction,
|
||||
message,
|
||||
deterministicWallets,
|
||||
rates,
|
||||
transactions,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { SagaIterator } from 'redux-saga';
|
||||
import { put, call, select } from 'redux-saga/effects';
|
||||
import translate from 'translations';
|
||||
import { padLeftEven } from 'libs/values';
|
||||
import { showNotification } from 'actions/notifications';
|
||||
import { getWalletInst } from 'selectors/wallet';
|
||||
import { IFullWallet } from 'libs/wallet';
|
||||
import { signMessageFailed, SignMessageRequestedAction } from 'actions/message';
|
||||
|
||||
export function* signingWrapper(
|
||||
handler: (wallet: IFullWallet, message: string) => SagaIterator,
|
||||
action: SignMessageRequestedAction
|
||||
): SagaIterator {
|
||||
const message = action.payload;
|
||||
const wallet = yield select(getWalletInst);
|
||||
|
||||
try {
|
||||
yield call(handler, wallet, message);
|
||||
} catch (err) {
|
||||
yield put(showNotification('danger', translate('SIGN_MSG_FAIL', { $err: err.message }), 5000));
|
||||
yield put(signMessageFailed());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a string into hex-encoded UTF-8 byte array, `0x` prefixed.
|
||||
*
|
||||
* @param {string} message to encode
|
||||
* @return {string}
|
||||
*/
|
||||
export function messageToData(message: string): string {
|
||||
return (
|
||||
'0x' +
|
||||
Array.from(Buffer.from(message, 'utf8'))
|
||||
.map(n => padLeftEven(n.toString(16)))
|
||||
.join('')
|
||||
);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import { SagaIterator } from 'redux-saga';
|
||||
import { all } from 'redux-saga/effects';
|
||||
import { signing } from './signing';
|
||||
|
||||
export function* message(): SagaIterator {
|
||||
yield all([...signing]);
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
import { SagaIterator } from 'redux-saga';
|
||||
import { put, take, apply, takeEvery, call, select } from 'redux-saga/effects';
|
||||
import translate, { translateRaw } from 'translations';
|
||||
import { showNotification } from 'actions/notifications';
|
||||
import { verifySignedMessage } from 'libs/signing';
|
||||
import {
|
||||
TypeKeys,
|
||||
SignMessageRequestedAction,
|
||||
signLocalMessageSucceeded,
|
||||
SignLocalMessageSucceededAction,
|
||||
signMessageFailed
|
||||
} from 'actions/message';
|
||||
import {
|
||||
requestMessageSignature,
|
||||
FinalizeSignatureAction,
|
||||
TypeKeys as ParityKeys
|
||||
} from 'actions/paritySigner';
|
||||
import { IFullWallet } from 'libs/wallet';
|
||||
import { getWalletType, IWalletType } from 'selectors/wallet';
|
||||
import { messageToData, signingWrapper } from './helpers';
|
||||
|
||||
function* signLocalMessage(wallet: IFullWallet, msg: string): SagaIterator {
|
||||
const address = yield apply(wallet, wallet.getAddressString);
|
||||
const sig: string = yield apply(wallet, wallet.signMessage, [msg]);
|
||||
|
||||
yield put(
|
||||
signLocalMessageSucceeded({
|
||||
address,
|
||||
msg,
|
||||
sig,
|
||||
version: '2'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function* signParitySignerMessage(wallet: IFullWallet, msg: string): SagaIterator {
|
||||
const address = yield apply(wallet, wallet.getAddressString);
|
||||
const data = yield call(messageToData, msg);
|
||||
|
||||
yield put(requestMessageSignature(address, data));
|
||||
|
||||
const { payload: sig }: FinalizeSignatureAction = yield take(
|
||||
ParityKeys.PARITY_SIGNER_FINALIZE_SIGNATURE
|
||||
);
|
||||
|
||||
if (!sig) {
|
||||
throw new Error(translateRaw('ERROR_38'));
|
||||
}
|
||||
|
||||
yield put(
|
||||
signLocalMessageSucceeded({
|
||||
address,
|
||||
msg,
|
||||
sig,
|
||||
version: '2'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function* handleMessageRequest(action: SignMessageRequestedAction): SagaIterator {
|
||||
const walletType: IWalletType = yield select(getWalletType);
|
||||
|
||||
const signingHandler = walletType.isParitySignerWallet
|
||||
? signParitySignerMessage
|
||||
: signLocalMessage;
|
||||
|
||||
return yield call(signingWrapper, signingHandler, action);
|
||||
}
|
||||
|
||||
function* verifySignature(action: SignLocalMessageSucceededAction): SagaIterator {
|
||||
const success = yield call(verifySignedMessage, action.payload);
|
||||
|
||||
if (success) {
|
||||
yield put(
|
||||
showNotification(
|
||||
'success',
|
||||
translate('SIGN_MSG_SUCCESS', { $address: action.payload.address })
|
||||
)
|
||||
);
|
||||
} else {
|
||||
yield put(signMessageFailed());
|
||||
yield put(showNotification('danger', translate('ERROR_38')));
|
||||
}
|
||||
}
|
||||
|
||||
export const signing = [
|
||||
takeEvery(TypeKeys.SIGN_MESSAGE_REQUESTED, handleMessageRequest),
|
||||
takeEvery(TypeKeys.SIGN_LOCAL_MESSAGE_SUCCEEDED, verifySignature)
|
||||
];
|
|
@ -15,7 +15,7 @@ import { computeIndexingHash } from 'libs/transaction';
|
|||
import { serializedAndTransactionFieldsMatch } from 'selectors/transaction';
|
||||
import { showNotification } from 'actions/notifications';
|
||||
import {
|
||||
requestSignature,
|
||||
requestTransactionSignature,
|
||||
FinalizeSignatureAction,
|
||||
TypeKeys as ParityKeys
|
||||
} from 'actions/paritySigner';
|
||||
|
@ -53,7 +53,7 @@ export function* signParitySignerTransactionHandler({
|
|||
const from = yield apply(wallet, wallet.getAddressString);
|
||||
const rlp = yield call(transactionToRLP, tx);
|
||||
|
||||
yield put(requestSignature(from, rlp));
|
||||
yield put(requestTransactionSignature(from, rlp));
|
||||
|
||||
const { payload }: FinalizeSignatureAction = yield take(
|
||||
ParityKeys.PARITY_SIGNER_FINALIZE_SIGNATURE
|
||||
|
|
|
@ -266,6 +266,7 @@
|
|||
"ERROR_34": "The name you are attempting to reveal does not match the name you have entered. ",
|
||||
"ERROR_36": "Enter valid TX hash",
|
||||
"ERROR_37": "Enter valid hex string (0-9, a-f)",
|
||||
"ERROR_38": "Invalid signed message. ",
|
||||
"SUCCESS_1": "Valid address ",
|
||||
"SUCCESS_2": "Wallet successfully decrypted ",
|
||||
"SUCCESS_3": "Your TX has been broadcast to the network. It is waiting to be mined & confirmed. During ICOs, it may take 3+ hours to confirm. Use the Verify & Check buttons below to see. TX Hash: ",
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"npm": ">= 5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@parity/qr-signer": "0.1.1",
|
||||
"@parity/qr-signer": "0.2.0",
|
||||
"babel-polyfill": "6.26.0",
|
||||
"bip39": "2.5.0",
|
||||
"bn.js": "4.11.8",
|
||||
|
|
Loading…
Reference in New Issue