Skip to content

Commit

Permalink
Feature: message eth sign + Address Book Migration (#1151)
Browse files Browse the repository at this point in the history
* wip number methods

* snaps

* sign messasge

* 13.1

* bump gaba

* snaps

* to string

* fix android issue

* fix address book

* add gaba again

* add gaba again

* fix network

* add eth_sign to wallet connect

* lock

* debig false
  • Loading branch information
estebanmino authored Oct 22, 2019
1 parent b7c7299 commit 7f428f1
Show file tree
Hide file tree
Showing 16 changed files with 747 additions and 491 deletions.
22 changes: 22 additions & 0 deletions app/components/Nav/Main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import Logger from '../../../util/Logger';
import contractMap from 'eth-contract-metadata';
import { BN } from 'gaba';
import { BNToHex } from 'gaba/util';
import MessageSign from '../../UI/MessageSign';

const styles = StyleSheet.create({
flex: {
Expand Down Expand Up @@ -432,6 +433,18 @@ class Main extends PureComponent {

Engine.context.TransactionController.hub.on('unapprovedTransaction', this.onUnapprovedTransaction);

Engine.context.MessageManager.hub.on('unapprovedMessage', messageParams => {
const { title: currentPageTitle, url: currentPageUrl } = messageParams.meta;
delete messageParams.meta;
this.setState({
signMessage: true,
signMessageParams: messageParams,
signType: 'eth',
currentPageTitle,
currentPageUrl
});
});

Engine.context.PersonalMessageManager.hub.on('unapprovedMessage', messageParams => {
const { title: currentPageTitle, url: currentPageUrl } = messageParams.meta;
delete messageParams.meta;
Expand Down Expand Up @@ -814,6 +827,15 @@ class Main extends PureComponent {
currentPageInformation={{ title: currentPageTitle, url: currentPageUrl }}
/>
)}
{signType === 'eth' && (
<MessageSign
navigation={this.props.navigation}
messageParams={signMessageParams}
onCancel={this.onSignAction}
onConfirm={this.onSignAction}
currentPageInformation={{ title: currentPageTitle, url: currentPageUrl }}
/>
)}
</Modal>
);
};
Expand Down
4 changes: 2 additions & 2 deletions app/components/UI/AccountInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ class AccountInput extends PureComponent {
}

getVisibleOptions = value => {
const { accounts, addressBook } = this.props;
const allAddresses = { ...addressBook, ...accounts };
const { accounts, addressBook, network } = this.props;
const allAddresses = { ...addressBook[network], ...accounts };

if (typeof value !== 'undefined' && value.toString().length > 0) {
// If it's a valid address we don't show any suggestion
Expand Down
72 changes: 72 additions & 0 deletions app/components/UI/MessageSign/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MessageSign should render correctly 1`] = `
<View
style={
Object {
"backgroundColor": "#FFFFFF",
"borderTopLeftRadius": 10,
"borderTopRightRadius": 10,
"minHeight": "90%",
"paddingBottom": 20,
}
}
>
<View>
<Text
onPress={[Function]}
style={
Object {
"color": "#000000",
"fontFamily": "Roboto",
"fontSize": 18,
"fontWeight": "600",
"marginHorizontal": 20,
"marginVertical": 12,
"textAlign": "center",
}
}
>
Signature Request
</Text>
</View>
<Connect(SignatureRequest)
currentPageInformation={
Object {
"title": "title",
"url": "url",
}
}
onCancel={[Function]}
onConfirm={[Function]}
showWarning={true}
type="ethSign"
>
<View
style={
Object {
"borderBottomColor": "#bbc0c5",
"borderBottomWidth": 1,
"padding": 20,
}
}
>
<Text
style={
Object {
"fontFamily": "Roboto",
"fontSize": 16,
"fontWeight": "400",
"margin": 5,
}
}
>
Message:
</Text>
<Text>
message
</Text>
</View>
</Connect(SignatureRequest)>
</View>
`;
116 changes: 116 additions & 0 deletions app/components/UI/MessageSign/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View, Text } from 'react-native';
import { colors, fontStyles } from '../../../styles/common';
import Engine from '../../../core/Engine';
import SignatureRequest from '../SignatureRequest';
import { strings } from '../../../../locales/i18n';
import DeviceSize from '../../../util/DeviceSize';

const styles = StyleSheet.create({
root: {
backgroundColor: colors.white,
minHeight: '90%',
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
paddingBottom: DeviceSize.isIphoneX() ? 20 : 0
},
informationRow: {
borderBottomColor: colors.grey200,
borderBottomWidth: 1,
padding: 20
},
messageLabelText: {
...fontStyles.normal,
margin: 5,
fontSize: 16
},
title: {
textAlign: 'center',
fontSize: 18,
marginVertical: 12,
marginHorizontal: 20,
color: colors.fontPrimary,
...fontStyles.bold
}
});

/**
* PureComponent that supports eth_sign
*/
export default class MessageSign extends PureComponent {
static propTypes = {
/**
* react-navigation object used for switching between screens
*/
navigation: PropTypes.object,
/**
* Callback triggered when this message signature is rejected
*/
onCancel: PropTypes.func,
/**
* Callback triggered when this message signature is approved
*/
onConfirm: PropTypes.func,
/**
* Personal message to be displayed to the user
*/
messageParams: PropTypes.object,
/**
* Object containing current page title and url
*/
currentPageInformation: PropTypes.object
};

signMessage = async () => {
const { messageParams } = this.props;
const { KeyringController, MessageManager } = Engine.context;
const messageId = messageParams.metamaskId;
const cleanMessageParams = await MessageManager.approveMessage(messageParams);
const rawSig = await KeyringController.signMessage(cleanMessageParams);
MessageManager.setMessageStatusSigned(messageId, rawSig);
};

rejectMessage = () => {
const { messageParams } = this.props;
const { MessageManager } = Engine.context;
const messageId = messageParams.metamaskId;
MessageManager.rejectMessage(messageId);
};

cancelSignature = () => {
this.rejectMessage();
this.props.onCancel();
};

confirmSignature = () => {
this.signMessage();
this.props.onConfirm();
};

render() {
const { messageParams, currentPageInformation, navigation } = this.props;
return (
<View style={styles.root}>
<View style={styles.titleWrapper}>
<Text style={styles.title} onPress={this.cancelSignature}>
{strings('signature_request.title')}
</Text>
</View>
<SignatureRequest
navigation={navigation}
onCancel={this.cancelSignature}
onConfirm={this.confirmSignature}
currentPageInformation={currentPageInformation}
type="ethSign"
showWarning
>
<View style={styles.informationRow}>
<Text style={styles.messageLabelText}>{strings('signature_request.message')}</Text>
<Text>{messageParams.data}</Text>
</View>
</SignatureRequest>
</View>
);
}
}
12 changes: 12 additions & 0 deletions app/components/UI/MessageSign/index.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { shallow } from 'enzyme';
import MessageSign from './';

describe('MessageSign', () => {
it('should render correctly', () => {
const wrapper = shallow(
<MessageSign currentPageInformation={{ title: 'title', url: 'url' }} messageParams={{ data: 'message' }} />
);
expect(wrapper).toMatchSnapshot();
});
});
2 changes: 1 addition & 1 deletion app/components/UI/PersonalSign/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const styles = StyleSheet.create({
});

/**
* PureComponent that supports eth_sign and personal_sign
* PureComponent that supports personal_sign
*/
export default class PersonalSign extends PureComponent {
static propTypes = {
Expand Down
53 changes: 41 additions & 12 deletions app/components/UI/SignatureRequest/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View, Text } from 'react-native';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import { colors, fontStyles, baseStyles } from '../../../styles/common';
import { strings } from '../../../../locales/i18n';
import { connect } from 'react-redux';
Expand Down Expand Up @@ -49,7 +49,16 @@ const styles = StyleSheet.create({
...fontStyles.normal,
color: colors.red,
textAlign: 'center',
padding: 10
paddingTop: 10,
paddingHorizontal: 10
},
warningLink: {
...fontStyles.normal,
color: colors.blue,
textAlign: 'center',
paddingHorizontal: 10,
paddingBottom: 10,
textDecorationLine: 'underline'
},
signText: {
...fontStyles.normal,
Expand Down Expand Up @@ -93,13 +102,15 @@ const styles = StyleSheet.create({
}
});

const ethLogo = require('../../../images/eth-logo.png'); // eslint-disable-line

/**
* PureComponent that renders scrollable content inside signature request user interface
*/
class SignatureRequest extends PureComponent {
static propTypes = {
/**
* Object representing the navigator
*/
navigation: PropTypes.object,
/**
* Map of accounts to information objects including balances
*/
Expand All @@ -124,10 +135,6 @@ class SignatureRequest extends PureComponent {
* Content to display above the action buttons
*/
children: PropTypes.node,
/**
* Custom message to be displayed to the user
*/
message: PropTypes.string,
/**
* Object containing domain information for the signature request for EIP712
*/
Expand All @@ -143,7 +150,11 @@ class SignatureRequest extends PureComponent {
/**
* String representing the selected the selected network
*/
networkType: PropTypes.string
networkType: PropTypes.string,
/**
* Whether it should display the warning message
*/
showWarning: PropTypes.bool
};

renderPageInformation = () => {
Expand Down Expand Up @@ -199,8 +210,26 @@ class SignatureRequest extends PureComponent {
};
};

goToWarning = () => {
this.props.onCancel();
this.props.navigation.push('Webview', {
url: 'https://metamask.zendesk.com/hc/en-us/articles/360015488751',
title: 'metamask.zendesk.com'
});
};

showWarning = () => (
<TouchableOpacity onPress={this.goToWarning}>
<Text style={styles.warningText}>
{strings('signature_request.eth_sign_warning')}
{` `}
<Text style={styles.warningLink}>{strings('signature_request.learn_more')}</Text>
</Text>
</TouchableOpacity>
);

render() {
const { children, message, accounts, selectedAddress, identities } = this.props;
const { children, showWarning, accounts, selectedAddress, identities } = this.props;
const balance = renderFromWei(accounts[selectedAddress].balance);
const accountLabel = renderAccountName(selectedAddress, identities);
return (
Expand Down Expand Up @@ -229,8 +258,8 @@ class SignatureRequest extends PureComponent {
</View>
{this.renderPageInformation()}
<View style={styles.signingInformation}>
{message ? (
<Text style={styles.warningText}>{message}</Text>
{showWarning ? (
this.showWarning()
) : (
<Text style={styles.signText}>{strings('signature_request.signing')}</Text>
)}
Expand Down
1 change: 0 additions & 1 deletion app/components/Views/Approval/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ class Approval extends PureComponent {
const mapStateToProps = state => ({
transaction: state.transaction,
transactions: state.engine.backgroundState.TransactionController.transactions,
addressBook: state.engine.backgroundState.AddressBookController.addressBook,
networkType: state.engine.backgroundState.NetworkController.provider.type
});

Expand Down
4 changes: 2 additions & 2 deletions app/components/Views/BrowserTab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,10 +439,10 @@ export class BrowserTab extends PureComponent {
this.mounted = true;
this.backgroundBridge = new BackgroundBridge(Engine, this.webview, {
eth_sign: async payload => {
const { PersonalMessageManager } = Engine.context;
const { MessageManager } = Engine.context;
try {
const pageMeta = await this.getPageMeta();
const rawSig = await PersonalMessageManager.addUnapprovedMessageAsync({
const rawSig = await MessageManager.addUnapprovedMessageAsync({
data: payload.params[1],
from: payload.params[0],
...pageMeta
Expand Down
Loading

0 comments on commit 7f428f1

Please sign in to comment.