mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
[MMI] personal sign and sign typed logic (#19892)
* adds missing logic * lint fixes
This commit is contained in:
parent
5d3690aa24
commit
2c22e85947
@ -1467,6 +1467,18 @@ export default class MetamaskController extends EventEmitter {
|
||||
this.signatureController.newUnsignedPersonalMessage.bind(
|
||||
this.signatureController,
|
||||
),
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
setTypedMessageInProgress:
|
||||
this.signatureController.setTypedMessageInProgress.bind(
|
||||
this.signatureController,
|
||||
),
|
||||
setPersonalMessageInProgress:
|
||||
this.signatureController.setPersonalMessageInProgress.bind(
|
||||
this.signatureController,
|
||||
),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
processEncryptionPublicKey:
|
||||
this.encryptionPublicKeyController.newRequestEncryptionPublicKey.bind(
|
||||
this.encryptionPublicKeyController,
|
||||
|
@ -64,7 +64,10 @@ export default class SignatureRequestOriginal extends Component {
|
||||
resolvePendingApproval: PropTypes.func.isRequired,
|
||||
completedTx: PropTypes.func.isRequired,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
// Used to show a warning if the signing account is not the selected account
|
||||
// Largely relevant for contract wallet custodians
|
||||
selectedAccount: PropTypes.object,
|
||||
mmiOnSignCallback: PropTypes.func,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
|
||||
@ -262,7 +265,7 @@ export default class SignatureRequestOriginal extends Component {
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
txData: { type, id },
|
||||
txData,
|
||||
hardwareWalletRequiresConnection,
|
||||
rejectPendingApproval,
|
||||
resolvePendingApproval,
|
||||
@ -275,22 +278,34 @@ export default class SignatureRequestOriginal extends Component {
|
||||
submitText={t('sign')}
|
||||
onCancel={async () => {
|
||||
await rejectPendingApproval(
|
||||
id,
|
||||
txData.id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
}}
|
||||
onSubmit={async () => {
|
||||
if (type === MESSAGE_TYPE.ETH_SIGN) {
|
||||
if (txData.type === MESSAGE_TYPE.ETH_SIGN) {
|
||||
this.setState({ showSignatureRequestWarning: true });
|
||||
} else {
|
||||
await resolvePendingApproval(id);
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
if (this.props.mmiOnSignCallback) {
|
||||
await this.props.mmiOnSignCallback(txData);
|
||||
return;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
await resolvePendingApproval(txData.id);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
}
|
||||
}}
|
||||
disabled={hardwareWalletRequiresConnection}
|
||||
disabled={
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
Boolean(txData?.custodyId) ||
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
hardwareWalletRequiresConnection
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@ -9,6 +9,17 @@ import {
|
||||
rejectAllMessages,
|
||||
completedTx,
|
||||
} from '../../../store/actions';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
// eslint-disable-next-line import/order
|
||||
import { showCustodianDeepLink } from '@metamask-institutional/extension';
|
||||
import {
|
||||
mmiActionsFactory,
|
||||
setPersonalMessageInProgress,
|
||||
} from '../../../store/institutional/institution-background';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { checkForUnapprovedMessages } from '../../../store/institutional/institution-actions';
|
||||
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../../shared/constants/app';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
accountsWithSendEtherInfoSelector,
|
||||
getSubjectMetadata,
|
||||
@ -16,6 +27,8 @@ import {
|
||||
unconfirmedMessagesHashSelector,
|
||||
getTotalUnapprovedMessagesCount,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
unapprovedPersonalMsgsSelector,
|
||||
getAccountType,
|
||||
getSelectedAccount,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../../selectors';
|
||||
@ -30,6 +43,10 @@ function mapStateToProps(state, ownProps) {
|
||||
msgParams: { from },
|
||||
} = ownProps.txData;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
const envType = getEnvironmentType();
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
const hardwareWalletRequiresConnection =
|
||||
doesAddressRequireLedgerHidConnection(state, from);
|
||||
const isLedgerWallet = isAddressLedger(state, from);
|
||||
@ -48,12 +65,63 @@ function mapStateToProps(state, ownProps) {
|
||||
messagesList,
|
||||
messagesCount,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
accountType: getAccountType(state),
|
||||
isNotification: envType === ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
selectedAccount: getSelectedAccount(state),
|
||||
unapprovedPersonalMessages: unapprovedPersonalMsgsSelector(state),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
let mapDispatchToProps = null;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
function mmiMapDispatchToProps(dispatch) {
|
||||
const mmiActions = mmiActionsFactory();
|
||||
return {
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
setMsgInProgress: (msgId) => dispatch(setPersonalMessageInProgress(msgId)),
|
||||
showCustodianDeepLink: ({
|
||||
custodyId,
|
||||
fromAddress,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}) =>
|
||||
showCustodianDeepLink({
|
||||
dispatch,
|
||||
mmiActions,
|
||||
txId: undefined,
|
||||
fromAddress,
|
||||
custodyId,
|
||||
isSignature: true,
|
||||
closeNotification,
|
||||
onDeepLinkFetched,
|
||||
onDeepLinkShown,
|
||||
}),
|
||||
showTransactionsFailedModal: ({
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}) =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'TRANSACTION_FAILED',
|
||||
errorMessage,
|
||||
closeNotification,
|
||||
operationFailed,
|
||||
}),
|
||||
),
|
||||
setWaitForConfirmDeepLinkDialog: (wait) =>
|
||||
dispatch(mmiActions.setWaitForConfirmDeepLinkDialog(wait)),
|
||||
goHome: () => dispatch(goHome()),
|
||||
};
|
||||
}
|
||||
|
||||
mapDispatchToProps = mmiMapDispatchToProps;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
mapDispatchToProps = function (dispatch) {
|
||||
return {
|
||||
goHome: () => dispatch(goHome()),
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
@ -80,12 +148,21 @@ function mapDispatchToProps(dispatch) {
|
||||
dispatch(rejectAllMessages(messagesList));
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
const { txData } = ownProps;
|
||||
|
||||
const { allAccounts, messagesList, ...otherStateProps } = stateProps;
|
||||
const {
|
||||
allAccounts,
|
||||
messagesList,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
accountType,
|
||||
isNotification,
|
||||
unapprovedPersonalMessages,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
...otherStateProps
|
||||
} = stateProps;
|
||||
|
||||
const {
|
||||
msgParams: { from },
|
||||
@ -95,6 +172,41 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
|
||||
const { cancelAllApprovals: dispatchCancelAllApprovals } = dispatchProps;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
const mmiOnSignCallback = async (_msgData) => {
|
||||
if (accountType === 'custody') {
|
||||
try {
|
||||
let msgData = _msgData;
|
||||
let id = _msgData.custodyId;
|
||||
if (!_msgData.custodyId) {
|
||||
msgData = checkForUnapprovedMessages(
|
||||
_msgData,
|
||||
unapprovedPersonalMessages,
|
||||
);
|
||||
id = msgData.custodyId;
|
||||
}
|
||||
dispatchProps.showCustodianDeepLink({
|
||||
custodyId: id,
|
||||
fromAddress: fromAccount.address,
|
||||
closeNotification: isNotification,
|
||||
onDeepLinkFetched: () => undefined,
|
||||
onDeepLinkShown: () => undefined,
|
||||
});
|
||||
await dispatchProps.setMsgInProgress(msgData.metamaskId);
|
||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||
await goHome();
|
||||
} catch (err) {
|
||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||
await dispatchProps.showTransactionsFailedModal({
|
||||
errorMessage: err.message,
|
||||
closeNotification: true,
|
||||
operationFailed: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
...otherStateProps,
|
||||
@ -103,6 +215,9 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
txData,
|
||||
cancelAllApprovals: () =>
|
||||
dispatchCancelAllApprovals(valuesFor(messagesList)),
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
mmiOnSignCallback,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -223,14 +223,16 @@ export default class SignatureRequest extends PureComponent {
|
||||
.toString();
|
||||
|
||||
const onSign = async () => {
|
||||
await resolvePendingApproval(id);
|
||||
completedTx(id);
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
if (this.props.mmiOnSignCallback) {
|
||||
await this.props.mmiOnSignCallback(txData);
|
||||
return;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
await resolvePendingApproval(id);
|
||||
completedTx(id);
|
||||
|
||||
trackEvent({
|
||||
category: MetaMetricsEventCategory.Transactions,
|
||||
event: 'Confirm',
|
||||
|
@ -30,7 +30,7 @@ import {
|
||||
setTypedMessageInProgress,
|
||||
} from '../../../store/institutional/institution-background';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { checkForUnapprovedTypedMessages } from '../../../store/institutional/institution-actions';
|
||||
import { checkForUnapprovedMessages } from '../../../store/institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
@ -214,7 +214,7 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
let msgData = _msgData;
|
||||
let id = _msgData.custodyId;
|
||||
if (!_msgData.custodyId) {
|
||||
msgData = checkForUnapprovedTypedMessages(
|
||||
msgData = checkForUnapprovedMessages(
|
||||
_msgData,
|
||||
unapprovedTypedMessages,
|
||||
);
|
||||
|
@ -6,7 +6,7 @@ import { _setBackgroundConnection } from '../action-queue';
|
||||
import {
|
||||
showInteractiveReplacementTokenModal,
|
||||
showCustodyConfirmLink,
|
||||
checkForUnapprovedTypedMessages,
|
||||
checkForUnapprovedMessages,
|
||||
updateCustodyState,
|
||||
} from './institution-actions';
|
||||
|
||||
@ -153,8 +153,8 @@ describe('#InstitutionActions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#checkForUnapprovedTypedMessages', () => {
|
||||
it('calls checkForUnapprovedTypedMessages and returns the messageData', async () => {
|
||||
describe('#checkForUnapprovedMessages', () => {
|
||||
it('calls checkForUnapprovedMessages and returns the messageData', async () => {
|
||||
const messageData = {
|
||||
id: 1,
|
||||
type: 'tx',
|
||||
@ -166,7 +166,7 @@ describe('#checkForUnapprovedTypedMessages', () => {
|
||||
status: 'unapproved',
|
||||
};
|
||||
|
||||
expect(checkForUnapprovedTypedMessages(messageData, { msg: 'msg' })).toBe(
|
||||
expect(checkForUnapprovedMessages(messageData, { msg: 'msg' })).toBe(
|
||||
messageData,
|
||||
);
|
||||
});
|
||||
|
@ -109,18 +109,18 @@ export function updateCustodyState(
|
||||
}
|
||||
}
|
||||
|
||||
export function checkForUnapprovedTypedMessages(
|
||||
export function checkForUnapprovedMessages(
|
||||
msgData: TemporaryMessageDataType['msgParams'],
|
||||
unapprovedTypedMessages: MessagesIndexedById,
|
||||
unapprovedMessages: MessagesIndexedById,
|
||||
) {
|
||||
const custodianUnapprovedMessages = Object.keys(unapprovedTypedMessages)
|
||||
.map((key) => unapprovedTypedMessages[key])
|
||||
const custodianUnapprovedMessages = Object.keys(unapprovedMessages)
|
||||
.map((key) => unapprovedMessages[key])
|
||||
.filter((message) => message.custodyId && message.status === 'unapproved');
|
||||
|
||||
if (custodianUnapprovedMessages && custodianUnapprovedMessages.length > 0) {
|
||||
return {
|
||||
...msgData,
|
||||
custodyId: unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
||||
custodyId: unapprovedMessages[msgData.metamaskId]?.custodyId,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
callBackgroundMethod,
|
||||
submitRequestToBackground,
|
||||
} from '../action-queue';
|
||||
import { MetaMaskReduxState } from '../store';
|
||||
import { MetaMaskReduxDispatch, MetaMaskReduxState } from '../store';
|
||||
import { isErrorWithMessage } from '../../../shared/modules/error';
|
||||
|
||||
export function showInteractiveReplacementTokenBanner({
|
||||
@ -21,7 +21,7 @@ export function showInteractiveReplacementTokenBanner({
|
||||
url: string;
|
||||
oldRefreshToken: string;
|
||||
}): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return async (dispatch) => {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
try {
|
||||
await submitRequestToBackground('showInteractiveReplacementTokenBanner', [
|
||||
url,
|
||||
@ -37,7 +37,7 @@ export function showInteractiveReplacementTokenBanner({
|
||||
}
|
||||
|
||||
export function setTypedMessageInProgress(msgId: string) {
|
||||
return async (dispatch: any) => {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
dispatch(showLoadingIndication());
|
||||
try {
|
||||
await submitRequestToBackground('setTypedMessageInProgress', [msgId]);
|
||||
@ -51,6 +51,21 @@ export function setTypedMessageInProgress(msgId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
export function setPersonalMessageInProgress(msgId: string) {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
dispatch(showLoadingIndication());
|
||||
try {
|
||||
await submitRequestToBackground('setPersonalMessageInProgress', [msgId]);
|
||||
} catch (error: any) {
|
||||
log.error(error);
|
||||
dispatch(displayWarning(error.message));
|
||||
} finally {
|
||||
await forceUpdateMetamaskState(dispatch);
|
||||
dispatch(hideLoadingIndication());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A factory that contains all MMI actions ready to use
|
||||
* Example usage:
|
||||
|
Loading…
Reference in New Issue
Block a user