Skip to content

Commit

Permalink
refactor: accept SignController approval request from frontend (#6600)
Browse files Browse the repository at this point in the history
  • Loading branch information
OGPoyraz authored Jul 25, 2023
1 parent 19e52f7 commit 1f2c424
Show file tree
Hide file tree
Showing 30 changed files with 1,181 additions and 1,225 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import SignatureRequestRoot from '../../UI/SignatureRequest/Root';

const SignatureApproval = () => {
const { approvalRequest } = useApprovalRequest();
const { approvalRequest, onReject, onConfirm } = useApprovalRequest();

const onSign = useCallback(() => undefined, []);
const onSignConfirm = useCallback(() => {
onConfirm({ waitForResult: true });
}, [onConfirm]);

const messageParams =
approvalRequest &&
Expand All @@ -22,7 +24,8 @@ const SignatureApproval = () => {
<SignatureRequestRoot
messageParams={messageParams}
approvalType={approvalRequest?.type}
onSign={onSign}
onSignConfirm={onSignConfirm}
onSignReject={onReject}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`SignatureApproval populates message params if approval type is eth_sign
"test": "value",
}
}
onSign={[Function]}
onSignConfirm={[Function]}
/>
`;

Expand All @@ -20,7 +20,7 @@ exports[`SignatureApproval populates message params if approval type is eth_sign
"test": "value",
}
}
onSign={[Function]}
onSignConfirm={[Function]}
/>
`;

Expand All @@ -32,19 +32,19 @@ exports[`SignatureApproval populates message params if approval type is personal
"test": "value",
}
}
onSign={[Function]}
onSignConfirm={[Function]}
/>
`;

exports[`SignatureApproval provides no message params if incorrect approval request type 1`] = `
<Root
approvalType="ADD_ETHEREUM_CHAIN"
onSign={[Function]}
onSignConfirm={[Function]}
/>
`;

exports[`SignatureApproval provides no message params if no approval request 1`] = `
<Root
onSign={[Function]}
onSignConfirm={[Function]}
/>
`;
198 changes: 198 additions & 0 deletions app/components/UI/MessageSign/MessageSign.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import React, { PureComponent } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { fontStyles } from '../../../styles/common';
import SignatureRequest from '../SignatureRequest';
import ExpandedMessage from '../SignatureRequest/ExpandedMessage';
import { KEYSTONE_TX_CANCELED } from '../../../constants/error';
import { MetaMetricsEvents } from '../../../core/Analytics';
import AnalyticsV2 from '../../../util/analyticsV2';
import { ThemeContext, mockTheme } from '../../../util/theme';
import {
addSignatureErrorListener,
getAnalyticsParams,
handleSignatureAction,
removeSignatureErrorListener,
} from '../../../util/confirmation/signatureUtils';
import { MessageParams, PageMeta } from '../SignatureRequest/types';
import { Colors } from '../../../util/theme/models';

interface MessageSignProps {
/**
* react-navigation object used for switching between screens
*/
navigation: any;
/**
* Callback triggered when this message signature is rejected
*/
onReject: () => void;
/**
* Callback triggered when this message signature is approved
*/
onConfirm: () => void;
/**
* Message to be displayed to the user
*/
messageParams: MessageParams;
/**
* Object containing current page title and url
*/
currentPageInformation: PageMeta;
/**
* Hides or shows the expanded signing message
*/
toggleExpandedMessage: () => void;
/**
* Indicated whether or not the expanded message is shown
*/
showExpandedMessage: boolean;
}

interface MessageSignState {
truncateMessage: boolean;
}

const createStyles = (colors: Colors) =>
StyleSheet.create({
expandedMessage: {
textAlign: 'center',
...fontStyles.normal,
fontSize: 14,
color: colors.text.default,
},
messageText: {
color: colors.text.default,
},
messageWrapper: {
marginBottom: 4,
},
});

/**
* Component that supports eth_sign
*/
class MessageSign extends PureComponent<MessageSignProps, MessageSignState> {
static contextType = ThemeContext;

state: MessageSignState = {
truncateMessage: false,
};

componentDidMount = () => {
const {
messageParams: { metamaskId },
} = this.props;
AnalyticsV2.trackEvent(
MetaMetricsEvents.SIGN_REQUEST_STARTED,
getAnalyticsParams(),
);
addSignatureErrorListener(metamaskId, this.onSignatureError);
};

componentWillUnmount = () => {
const {
messageParams: { metamaskId },
} = this.props;
removeSignatureErrorListener(metamaskId, this.onSignatureError);
};

onSignatureError = ({ error }: any) => {
if (error?.message.startsWith(KEYSTONE_TX_CANCELED)) {
AnalyticsV2.trackEvent(
MetaMetricsEvents.QR_HARDWARE_TRANSACTION_CANCELED,
getAnalyticsParams(),
);
}
};

rejectSignature = async () => {
const { messageParams, onReject } = this.props;
await handleSignatureAction(onReject, messageParams, 'eth', false);
};

confirmSignature = async () => {
const { messageParams, onConfirm } = this.props;
await handleSignatureAction(onConfirm, messageParams, 'eth', true);
};

getStyles = () => {
const colors = this.context.colors || mockTheme.colors;
return createStyles(colors);
};

renderMessageText = () => {
const { messageParams, showExpandedMessage } = this.props;
const { truncateMessage } = this.state;
const styles = this.getStyles();

let messageText;
if (showExpandedMessage) {
messageText = (
<Text style={styles.expandedMessage}>{messageParams.data}</Text>
);
} else {
messageText = truncateMessage ? (
<Text
style={styles.messageText}
numberOfLines={5}
ellipsizeMode={'tail'}
>
{messageParams.data}
</Text>
) : (
<Text
style={styles.messageText}
onTextLayout={this.shouldTruncateMessage}
>
{messageParams.data}
</Text>
);
}
return messageText;
};

shouldTruncateMessage = (e: any) => {
if (e.nativeEvent.lines.length > 5) {
this.setState({ truncateMessage: true });
return;
}
this.setState({ truncateMessage: false });
};

render() {
const {
currentPageInformation,
navigation,
showExpandedMessage,
toggleExpandedMessage,
messageParams: { from },
} = this.props;
const styles = this.getStyles();

const rootView = showExpandedMessage ? (
<ExpandedMessage
currentPageInformation={currentPageInformation}
renderMessage={this.renderMessageText}
toggleExpandedMessage={toggleExpandedMessage}
/>
) : (
<SignatureRequest
navigation={navigation}
onReject={this.rejectSignature}
onConfirm={this.confirmSignature}
currentPageInformation={currentPageInformation}
truncateMessage={this.state.truncateMessage}
showExpandedMessage={showExpandedMessage}
toggleExpandedMessage={toggleExpandedMessage}
type="ethSign"
showWarning
fromAddress={from}
testID={'eth-signature-request'}
>
<View style={styles.messageWrapper}>{this.renderMessageText()}</View>
</SignatureRequest>
);
return rootView;
}
}

export default MessageSign;
12 changes: 10 additions & 2 deletions app/components/UI/MessageSign/__snapshots__/index.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,19 @@ exports[`MessageSign should render correctly 1`] = `
messageParams={
Object {
"data": "message",
"from": "0x0",
"metamaskId": "TestMessageId",
"origin": "example.com",
}
}
onCancel={[Function]}
onConfirm={[Function]}
navigation={
Object {
"navigate": [MockFunction],
}
}
onConfirm={[MockFunction]}
onReject={[MockFunction]}
showExpandedMessage={false}
toggleExpandedMessage={[MockFunction]}
/>
`;
Loading

0 comments on commit 1f2c424

Please sign in to comment.