mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 18:00:18 +01:00
Accept SignController approval request from frontend (#19184)
This commit is contained in:
parent
524ab017c7
commit
64cbe1f2f8
@ -1,18 +0,0 @@
|
|||||||
diff --git a/dist/SignatureController.js b/dist/SignatureController.js
|
|
||||||
index b39d274f4547ab4e8b647293199ec21c4a9e38ca..288e55c97c3e4a234874dd8b8986ba77576b0dc4 100644
|
|
||||||
--- a/dist/SignatureController.js
|
|
||||||
+++ b/dist/SignatureController.js
|
|
||||||
@@ -308,12 +308,12 @@ _SignatureController_keyringController = new WeakMap(), _SignatureController_isE
|
|
||||||
const messageId = msgParams.metamaskId;
|
|
||||||
try {
|
|
||||||
const cleanMessageParams = yield messageManager.approveMessage(msgParams);
|
|
||||||
+ __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_acceptApproval).call(this, messageId);
|
|
||||||
const signature = yield getSignature(cleanMessageParams);
|
|
||||||
this.hub.emit(`${methodName}:signed`, { signature, messageId });
|
|
||||||
if (!cleanMessageParams.deferSetAsSigned) {
|
|
||||||
messageManager.setMessageStatusSigned(messageId, signature);
|
|
||||||
}
|
|
||||||
- __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_acceptApproval).call(this, messageId);
|
|
||||||
return __classPrivateFieldGet(this, _SignatureController_getAllState, "f").call(this);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
@ -45,7 +45,7 @@ export type CoreMessage = AbstractMessage & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type StateMessage = Required<
|
export type StateMessage = Required<
|
||||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata'>
|
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata' | 'error'>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type DecryptMessageControllerState = {
|
export type DecryptMessageControllerState = {
|
||||||
|
@ -45,7 +45,7 @@ export type CoreMessage = AbstractMessage & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type StateMessage = Required<
|
export type StateMessage = Required<
|
||||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata'>
|
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata' | 'error'>
|
||||||
> & {
|
> & {
|
||||||
msgParams: string;
|
msgParams: string;
|
||||||
};
|
};
|
||||||
|
@ -1258,11 +1258,7 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
this.signatureController = new SignatureController({
|
this.signatureController = new SignatureController({
|
||||||
messenger: this.controllerMessenger.getRestricted({
|
messenger: this.controllerMessenger.getRestricted({
|
||||||
name: 'SignatureController',
|
name: 'SignatureController',
|
||||||
allowedActions: [
|
allowedActions: [`${this.approvalController.name}:addRequest`],
|
||||||
`${this.approvalController.name}:addRequest`,
|
|
||||||
`${this.approvalController.name}:acceptRequest`,
|
|
||||||
`${this.approvalController.name}:rejectRequest`,
|
|
||||||
],
|
|
||||||
}),
|
}),
|
||||||
keyringController: this.keyringController,
|
keyringController: this.keyringController,
|
||||||
isEthSignEnabled: () =>
|
isEthSignEnabled: () =>
|
||||||
@ -2248,27 +2244,6 @@ export default class MetamaskController extends EventEmitter {
|
|||||||
updatePreviousGasParams:
|
updatePreviousGasParams:
|
||||||
txController.updatePreviousGasParams.bind(txController),
|
txController.updatePreviousGasParams.bind(txController),
|
||||||
|
|
||||||
// signatureController
|
|
||||||
signMessage: this.signatureController.signMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
cancelMessage: this.signatureController.cancelMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
signPersonalMessage: this.signatureController.signPersonalMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
cancelPersonalMessage:
|
|
||||||
this.signatureController.cancelPersonalMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
signTypedMessage: this.signatureController.signTypedMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
cancelTypedMessage: this.signatureController.cancelTypedMessage.bind(
|
|
||||||
this.signatureController,
|
|
||||||
),
|
|
||||||
|
|
||||||
// decryptMessageController
|
// decryptMessageController
|
||||||
decryptMessage: this.decryptMessageController.decryptMessage.bind(
|
decryptMessage: this.decryptMessageController.decryptMessage.bind(
|
||||||
this.decryptMessageController,
|
this.decryptMessageController,
|
||||||
|
@ -1718,7 +1718,8 @@
|
|||||||
"browserify>buffer": true,
|
"browserify>buffer": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
"eth-rpc-errors": true,
|
"eth-rpc-errors": true,
|
||||||
"ethereumjs-util": true
|
"ethereumjs-util": true,
|
||||||
|
"lodash": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@metamask/smart-transactions-controller": {
|
"@metamask/smart-transactions-controller": {
|
||||||
|
@ -1908,7 +1908,8 @@
|
|||||||
"browserify>buffer": true,
|
"browserify>buffer": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
"eth-rpc-errors": true,
|
"eth-rpc-errors": true,
|
||||||
"ethereumjs-util": true
|
"ethereumjs-util": true,
|
||||||
|
"lodash": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@metamask/smart-transactions-controller": {
|
"@metamask/smart-transactions-controller": {
|
||||||
|
@ -1908,7 +1908,8 @@
|
|||||||
"browserify>buffer": true,
|
"browserify>buffer": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
"eth-rpc-errors": true,
|
"eth-rpc-errors": true,
|
||||||
"ethereumjs-util": true
|
"ethereumjs-util": true,
|
||||||
|
"lodash": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@metamask/smart-transactions-controller": {
|
"@metamask/smart-transactions-controller": {
|
||||||
|
@ -1718,7 +1718,8 @@
|
|||||||
"browserify>buffer": true,
|
"browserify>buffer": true,
|
||||||
"browserify>events": true,
|
"browserify>events": true,
|
||||||
"eth-rpc-errors": true,
|
"eth-rpc-errors": true,
|
||||||
"ethereumjs-util": true
|
"ethereumjs-util": true,
|
||||||
|
"lodash": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@metamask/smart-transactions-controller": {
|
"@metamask/smart-transactions-controller": {
|
||||||
|
@ -196,8 +196,7 @@
|
|||||||
"fast-json-patch@^3.1.1": "patch:fast-json-patch@npm%3A3.1.1#./.yarn/patches/fast-json-patch-npm-3.1.1-7e8bb70a45.patch",
|
"fast-json-patch@^3.1.1": "patch:fast-json-patch@npm%3A3.1.1#./.yarn/patches/fast-json-patch-npm-3.1.1-7e8bb70a45.patch",
|
||||||
"request@^2.83.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch",
|
"request@^2.83.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch",
|
||||||
"request@^2.88.2": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch",
|
"request@^2.88.2": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch",
|
||||||
"request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch",
|
"request@^2.85.0": "patch:request@npm%3A2.88.2#./.yarn/patches/request-npm-2.88.2-f4a57c72c4.patch"
|
||||||
"@metamask/signature-controller@^3.0.0": "patch:@metamask/signature-controller@npm%3A3.0.0#./.yarn/patches/@metamask-signature-controller-npm-3.0.0-8771b6885e.patch"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
@ -248,7 +247,7 @@
|
|||||||
"@metamask/jazzicon": "^2.0.0",
|
"@metamask/jazzicon": "^2.0.0",
|
||||||
"@metamask/key-tree": "^7.0.0",
|
"@metamask/key-tree": "^7.0.0",
|
||||||
"@metamask/logo": "^3.1.1",
|
"@metamask/logo": "^3.1.1",
|
||||||
"@metamask/message-manager": "^6.0.0",
|
"@metamask/message-manager": "^7.0.0",
|
||||||
"@metamask/metamask-eth-abis": "^3.0.0",
|
"@metamask/metamask-eth-abis": "^3.0.0",
|
||||||
"@metamask/notification-controller": "^3.0.0",
|
"@metamask/notification-controller": "^3.0.0",
|
||||||
"@metamask/obs-store": "^8.1.0",
|
"@metamask/obs-store": "^8.1.0",
|
||||||
@ -261,7 +260,7 @@
|
|||||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1",
|
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1",
|
||||||
"@metamask/safe-event-emitter": "^2.0.0",
|
"@metamask/safe-event-emitter": "^2.0.0",
|
||||||
"@metamask/scure-bip39": "^2.0.3",
|
"@metamask/scure-bip39": "^2.0.3",
|
||||||
"@metamask/signature-controller": "^3.0.0",
|
"@metamask/signature-controller": "^4.0.1",
|
||||||
"@metamask/slip44": "^3.0.0",
|
"@metamask/slip44": "^3.0.0",
|
||||||
"@metamask/smart-transactions-controller": "^3.1.0",
|
"@metamask/smart-transactions-controller": "^3.1.0",
|
||||||
"@metamask/snaps-controllers": "^0.32.2",
|
"@metamask/snaps-controllers": "^0.32.2",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useCallback, useMemo, useState } from 'react';
|
import React, { useCallback, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||||
import { getCurrentQRHardwareState } from '../../../selectors';
|
import { getCurrentQRHardwareState } from '../../../selectors';
|
||||||
import Popover from '../../ui/popover';
|
import Popover from '../../ui/popover';
|
||||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||||
@ -7,11 +8,8 @@ import {
|
|||||||
cancelSyncQRHardware as cancelSyncQRHardwareAction,
|
cancelSyncQRHardware as cancelSyncQRHardwareAction,
|
||||||
cancelQRHardwareSignRequest as cancelQRHardwareSignRequestAction,
|
cancelQRHardwareSignRequest as cancelQRHardwareSignRequestAction,
|
||||||
cancelTx,
|
cancelTx,
|
||||||
cancelPersonalMsg,
|
rejectPendingApproval,
|
||||||
cancelMsg,
|
|
||||||
cancelTypedMsg,
|
|
||||||
} from '../../../store/actions';
|
} from '../../../store/actions';
|
||||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
|
||||||
import QRHardwareWalletImporter from './qr-hardware-wallet-importer';
|
import QRHardwareWalletImporter from './qr-hardware-wallet-importer';
|
||||||
import QRHardwareSignRequest from './qr-hardware-sign-request';
|
import QRHardwareSignRequest from './qr-hardware-sign-request';
|
||||||
|
|
||||||
@ -43,25 +41,13 @@ const QRHardwarePopover = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const signRequestCancel = useCallback(() => {
|
const signRequestCancel = useCallback(() => {
|
||||||
let action = cancelTx;
|
dispatch(
|
||||||
switch (_txData.type) {
|
rejectPendingApproval(
|
||||||
case MESSAGE_TYPE.PERSONAL_SIGN: {
|
_txData.id,
|
||||||
action = cancelPersonalMsg;
|
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||||
break;
|
),
|
||||||
}
|
);
|
||||||
case MESSAGE_TYPE.ETH_SIGN: {
|
dispatch(cancelTx(_txData));
|
||||||
action = cancelMsg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MESSAGE_TYPE.ETH_SIGN_TYPED_DATA: {
|
|
||||||
action = cancelTypedMsg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
action = cancelTx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dispatch(action(_txData));
|
|
||||||
dispatch(cancelQRHardwareSignRequestAction());
|
dispatch(cancelQRHardwareSignRequestAction());
|
||||||
}, [dispatch, _txData]);
|
}, [dispatch, _txData]);
|
||||||
|
|
||||||
|
@ -96,6 +96,7 @@ const SignatureRequestOriginalWarning = ({
|
|||||||
<Button
|
<Button
|
||||||
className="signature-request-warning__footer__sign-button"
|
className="signature-request-warning__footer__sign-button"
|
||||||
type="danger-primary"
|
type="danger-primary"
|
||||||
|
data-testid="signature-warning-sign-button"
|
||||||
onClick={onSubmit}
|
onClick={onSubmit}
|
||||||
>
|
>
|
||||||
{t('sign')}
|
{t('sign')}
|
||||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { ObjectInspector } from 'react-inspector';
|
import { ObjectInspector } from 'react-inspector';
|
||||||
|
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||||
import LedgerInstructionField from '../ledger-instruction-field';
|
import LedgerInstructionField from '../ledger-instruction-field';
|
||||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||||
import {
|
import {
|
||||||
@ -49,18 +50,19 @@ export default class SignatureRequestOriginal extends Component {
|
|||||||
address: PropTypes.string.isRequired,
|
address: PropTypes.string.isRequired,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
cancel: PropTypes.func.isRequired,
|
|
||||||
clearConfirmTransaction: PropTypes.func.isRequired,
|
clearConfirmTransaction: PropTypes.func.isRequired,
|
||||||
history: PropTypes.object.isRequired,
|
history: PropTypes.object.isRequired,
|
||||||
mostRecentOverviewPage: PropTypes.string.isRequired,
|
mostRecentOverviewPage: PropTypes.string.isRequired,
|
||||||
sign: PropTypes.func.isRequired,
|
|
||||||
txData: PropTypes.object.isRequired,
|
txData: PropTypes.object.isRequired,
|
||||||
subjectMetadata: PropTypes.object,
|
subjectMetadata: PropTypes.object,
|
||||||
hardwareWalletRequiresConnection: PropTypes.bool,
|
hardwareWalletRequiresConnection: PropTypes.bool,
|
||||||
isLedgerWallet: PropTypes.bool,
|
isLedgerWallet: PropTypes.bool,
|
||||||
messagesCount: PropTypes.number,
|
messagesCount: PropTypes.number,
|
||||||
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
|
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
|
||||||
cancelAll: PropTypes.func.isRequired,
|
cancelAllApprovals: PropTypes.func.isRequired,
|
||||||
|
rejectPendingApproval: PropTypes.func.isRequired,
|
||||||
|
resolvePendingApproval: PropTypes.func.isRequired,
|
||||||
|
completedTx: PropTypes.func.isRequired,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
selectedAccount: PropTypes.object,
|
selectedAccount: PropTypes.object,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
@ -230,33 +232,48 @@ export default class SignatureRequestOriginal extends Component {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
onSubmit = async (event) => {
|
onSubmit = async () => {
|
||||||
const { clearConfirmTransaction, history, mostRecentOverviewPage, sign } =
|
const {
|
||||||
this.props;
|
clearConfirmTransaction,
|
||||||
|
history,
|
||||||
|
mostRecentOverviewPage,
|
||||||
|
resolvePendingApproval,
|
||||||
|
completedTx,
|
||||||
|
txData: { id },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
await sign(event);
|
await resolvePendingApproval(id);
|
||||||
|
completedTx(id);
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
onCancel = async (event) => {
|
onCancel = async () => {
|
||||||
const { clearConfirmTransaction, history, mostRecentOverviewPage, cancel } =
|
const {
|
||||||
this.props;
|
clearConfirmTransaction,
|
||||||
|
history,
|
||||||
|
mostRecentOverviewPage,
|
||||||
|
rejectPendingApproval,
|
||||||
|
txData: { id },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
await cancel(event);
|
await rejectPendingApproval(
|
||||||
|
id,
|
||||||
|
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||||
|
);
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderFooter = () => {
|
renderFooter = () => {
|
||||||
const {
|
const {
|
||||||
cancel,
|
|
||||||
sign,
|
|
||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
history,
|
history,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
txData: { type },
|
txData: { type, id },
|
||||||
hardwareWalletRequiresConnection,
|
hardwareWalletRequiresConnection,
|
||||||
|
rejectPendingApproval,
|
||||||
|
resolvePendingApproval,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { t } = this.context;
|
const { t } = this.context;
|
||||||
|
|
||||||
@ -264,16 +281,19 @@ export default class SignatureRequestOriginal extends Component {
|
|||||||
<PageContainerFooter
|
<PageContainerFooter
|
||||||
cancelText={t('reject')}
|
cancelText={t('reject')}
|
||||||
submitText={t('sign')}
|
submitText={t('sign')}
|
||||||
onCancel={async (event) => {
|
onCancel={async () => {
|
||||||
await cancel(event);
|
await rejectPendingApproval(
|
||||||
|
id,
|
||||||
|
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||||
|
);
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
}}
|
}}
|
||||||
onSubmit={async (event) => {
|
onSubmit={async () => {
|
||||||
if (type === MESSAGE_TYPE.ETH_SIGN) {
|
if (type === MESSAGE_TYPE.ETH_SIGN) {
|
||||||
this.setState({ showSignatureRequestWarning: true });
|
this.setState({ showSignatureRequestWarning: true });
|
||||||
} else {
|
} else {
|
||||||
await sign(event);
|
await resolvePendingApproval(id);
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
}
|
}
|
||||||
@ -285,19 +305,19 @@ export default class SignatureRequestOriginal extends Component {
|
|||||||
|
|
||||||
handleCancelAll = () => {
|
handleCancelAll = () => {
|
||||||
const {
|
const {
|
||||||
cancelAll,
|
|
||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
history,
|
history,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
showRejectTransactionsConfirmationModal,
|
showRejectTransactionsConfirmationModal,
|
||||||
messagesCount,
|
messagesCount,
|
||||||
|
cancelAllApprovals,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const unapprovedTxCount = messagesCount;
|
const unapprovedTxCount = messagesCount;
|
||||||
|
|
||||||
showRejectTransactionsConfirmationModal({
|
showRejectTransactionsConfirmationModal({
|
||||||
unapprovedTxCount,
|
unapprovedTxCount,
|
||||||
onSubmit: async () => {
|
onSubmit: async () => {
|
||||||
await cancelAll();
|
await cancelAllApprovals();
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
},
|
},
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { compose } from 'redux';
|
import { compose } from 'redux';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { withRouter } from 'react-router-dom';
|
||||||
|
import {
|
||||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
goHome,
|
||||||
import { goHome, cancelMsgs, showModal } from '../../../store/actions';
|
showModal,
|
||||||
|
resolvePendingApproval,
|
||||||
|
rejectPendingApproval,
|
||||||
|
rejectAllMessages,
|
||||||
|
completedTx,
|
||||||
|
} from '../../../store/actions';
|
||||||
import {
|
import {
|
||||||
accountsWithSendEtherInfoSelector,
|
accountsWithSendEtherInfoSelector,
|
||||||
getSubjectMetadata,
|
getSubjectMetadata,
|
||||||
@ -65,44 +70,30 @@ function mapDispatchToProps(dispatch) {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
cancelAll: (messagesList) => dispatch(cancelMsgs(messagesList)),
|
completedTx: (txId) => dispatch(completedTx(txId)),
|
||||||
|
resolvePendingApproval: (id) => {
|
||||||
|
dispatch(resolvePendingApproval(id));
|
||||||
|
},
|
||||||
|
rejectPendingApproval: (id, error) =>
|
||||||
|
dispatch(rejectPendingApproval(id, error)),
|
||||||
|
cancelAllApprovals: (messagesList) => {
|
||||||
|
dispatch(rejectAllMessages(messagesList));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeProps(stateProps, dispatchProps, ownProps) {
|
function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||||
const {
|
const { txData } = ownProps;
|
||||||
signPersonalMessage,
|
|
||||||
signTypedMessage,
|
|
||||||
cancelPersonalMessage,
|
|
||||||
cancelTypedMessage,
|
|
||||||
signMessage,
|
|
||||||
cancelMessage,
|
|
||||||
txData,
|
|
||||||
} = ownProps;
|
|
||||||
|
|
||||||
const { allAccounts, messagesList, ...otherStateProps } = stateProps;
|
const { allAccounts, messagesList, ...otherStateProps } = stateProps;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
type,
|
|
||||||
msgParams: { from },
|
msgParams: { from },
|
||||||
} = txData;
|
} = txData;
|
||||||
|
|
||||||
const fromAccount = getAccountByAddress(allAccounts, from);
|
const fromAccount = getAccountByAddress(allAccounts, from);
|
||||||
|
|
||||||
const { cancelAll: dispatchCancelAll } = dispatchProps;
|
const { cancelAllApprovals: dispatchCancelAllApprovals } = dispatchProps;
|
||||||
|
|
||||||
let cancel;
|
|
||||||
let sign;
|
|
||||||
if (type === MESSAGE_TYPE.PERSONAL_SIGN) {
|
|
||||||
cancel = cancelPersonalMessage;
|
|
||||||
sign = signPersonalMessage;
|
|
||||||
} else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) {
|
|
||||||
cancel = cancelTypedMessage;
|
|
||||||
sign = signTypedMessage;
|
|
||||||
} else if (type === MESSAGE_TYPE.ETH_SIGN) {
|
|
||||||
cancel = cancelMessage;
|
|
||||||
sign = signMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...ownProps,
|
...ownProps,
|
||||||
@ -110,9 +101,8 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
...dispatchProps,
|
...dispatchProps,
|
||||||
fromAccount,
|
fromAccount,
|
||||||
txData,
|
txData,
|
||||||
cancel,
|
cancelAllApprovals: () =>
|
||||||
sign,
|
dispatchCancelAllApprovals(valuesFor(messagesList)),
|
||||||
cancelAll: () => dispatchCancelAll(valuesFor(messagesList)),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,13 +1,25 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import configureMockStore from 'redux-mock-store';
|
import configureMockStore from 'redux-mock-store';
|
||||||
import { fireEvent, screen } from '@testing-library/react';
|
import { fireEvent, screen } from '@testing-library/react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||||
import mockState from '../../../../test/data/mock-state.json';
|
import mockState from '../../../../test/data/mock-state.json';
|
||||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||||
import configureStore from '../../../store/store';
|
import configureStore from '../../../store/store';
|
||||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||||
|
import {
|
||||||
|
resolvePendingApproval,
|
||||||
|
rejectPendingApproval,
|
||||||
|
completedTx,
|
||||||
|
} from '../../../store/actions';
|
||||||
import SignatureRequestOriginal from '.';
|
import SignatureRequestOriginal from '.';
|
||||||
|
|
||||||
|
jest.mock('../../../store/actions', () => ({
|
||||||
|
resolvePendingApproval: jest.fn().mockReturnValue({ type: 'test' }),
|
||||||
|
rejectPendingApproval: jest.fn().mockReturnValue({ type: 'test' }),
|
||||||
|
completedTx: jest.fn().mockReturnValue({ type: 'test' }),
|
||||||
|
}));
|
||||||
|
|
||||||
const MOCK_SIGN_DATA = JSON.stringify({
|
const MOCK_SIGN_DATA = JSON.stringify({
|
||||||
domain: {
|
domain: {
|
||||||
name: 'happydapp.website',
|
name: 'happydapp.website',
|
||||||
@ -92,12 +104,30 @@ describe('SignatureRequestOriginal', () => {
|
|||||||
expect(screen.getByText('Signature request')).toBeInTheDocument();
|
expect(screen.getByText('Signature request')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render warning for eth sign when sign button clicked', () => {
|
it('should render warning for eth sign when sign button clicked', async () => {
|
||||||
render();
|
render();
|
||||||
const signButton = screen.getByTestId('page-container-footer-next');
|
const signButton = screen.getByTestId('page-container-footer-next');
|
||||||
|
|
||||||
fireEvent.click(signButton);
|
fireEvent.click(signButton);
|
||||||
expect(screen.getByText('Your funds may be at risk')).toBeInTheDocument();
|
expect(screen.getByText('Your funds may be at risk')).toBeInTheDocument();
|
||||||
|
|
||||||
|
const secondSignButton = screen.getByTestId(
|
||||||
|
'signature-warning-sign-button',
|
||||||
|
);
|
||||||
|
await act(async () => {
|
||||||
|
fireEvent.click(secondSignButton);
|
||||||
|
});
|
||||||
|
expect(resolvePendingApproval).toHaveBeenCalledTimes(1);
|
||||||
|
expect(completedTx).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should cancel approval when user reject signing', async () => {
|
||||||
|
render();
|
||||||
|
const rejectButton = screen.getByTestId('page-container-footer-cancel');
|
||||||
|
await act(async () => {
|
||||||
|
fireEvent.click(rejectButton);
|
||||||
|
});
|
||||||
|
expect(rejectPendingApproval).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should escape RTL character in label or value', () => {
|
it('should escape RTL character in label or value', () => {
|
||||||
|
@ -4,6 +4,7 @@ import { useSelector, useDispatch } from 'react-redux';
|
|||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import log from 'loglevel';
|
import log from 'loglevel';
|
||||||
import { isValidSIWEOrigin } from '@metamask/controller-utils';
|
import { isValidSIWEOrigin } from '@metamask/controller-utils';
|
||||||
|
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||||
import { BannerAlert, Text } from '../../component-library';
|
import { BannerAlert, Text } from '../../component-library';
|
||||||
import Popover from '../../ui/popover';
|
import Popover from '../../ui/popover';
|
||||||
import Checkbox from '../../ui/check-box';
|
import Checkbox from '../../ui/check-box';
|
||||||
@ -25,27 +26,28 @@ import {
|
|||||||
SEVERITIES,
|
SEVERITIES,
|
||||||
TextVariant,
|
TextVariant,
|
||||||
} from '../../../helpers/constants/design-system';
|
} from '../../../helpers/constants/design-system';
|
||||||
|
import {
|
||||||
|
resolvePendingApproval,
|
||||||
|
rejectPendingApproval,
|
||||||
|
rejectAllMessages,
|
||||||
|
completedTx,
|
||||||
|
showModal,
|
||||||
|
} from '../../../store/actions';
|
||||||
|
|
||||||
import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message';
|
import SecurityProviderBannerMessage from '../security-provider-banner-message/security-provider-banner-message';
|
||||||
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
import { SECURITY_PROVIDER_MESSAGE_SEVERITIES } from '../security-provider-banner-message/security-provider-banner-message.constants';
|
||||||
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
|
import ConfirmPageContainerNavigation from '../confirm-page-container/confirm-page-container-navigation';
|
||||||
import { getMostRecentOverviewPage } from '../../../ducks/history/history';
|
import { getMostRecentOverviewPage } from '../../../ducks/history/history';
|
||||||
import { showModal, cancelMsgs } from '../../../store/actions';
|
|
||||||
import LedgerInstructionField from '../ledger-instruction-field';
|
import LedgerInstructionField from '../ledger-instruction-field';
|
||||||
|
|
||||||
import SignatureRequestHeader from '../signature-request-header';
|
import SignatureRequestHeader from '../signature-request-header';
|
||||||
import Header from './signature-request-siwe-header';
|
import Header from './signature-request-siwe-header';
|
||||||
import Message from './signature-request-siwe-message';
|
import Message from './signature-request-siwe-message';
|
||||||
|
|
||||||
export default function SignatureRequestSIWE({
|
export default function SignatureRequestSIWE({ txData }) {
|
||||||
txData,
|
|
||||||
cancelPersonalMessage,
|
|
||||||
signPersonalMessage,
|
|
||||||
}) {
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
|
|
||||||
const allAccounts = useSelector(accountsWithSendEtherInfoSelector);
|
const allAccounts = useSelector(accountsWithSendEtherInfoSelector);
|
||||||
const subjectMetadata = useSelector(getSubjectMetadata);
|
const subjectMetadata = useSelector(getSubjectMetadata);
|
||||||
|
|
||||||
@ -59,6 +61,7 @@ export default function SignatureRequestSIWE({
|
|||||||
origin,
|
origin,
|
||||||
siwe: { parsedMessage },
|
siwe: { parsedMessage },
|
||||||
},
|
},
|
||||||
|
id,
|
||||||
} = txData;
|
} = txData;
|
||||||
|
|
||||||
const isLedgerWallet = useSelector((state) => isAddressLedger(state, from));
|
const isLedgerWallet = useSelector((state) => isAddressLedger(state, from));
|
||||||
@ -82,27 +85,27 @@ export default function SignatureRequestSIWE({
|
|||||||
(txData?.securityProviderResponse &&
|
(txData?.securityProviderResponse &&
|
||||||
Object.keys(txData.securityProviderResponse).length === 0);
|
Object.keys(txData.securityProviderResponse).length === 0);
|
||||||
|
|
||||||
const onSign = useCallback(
|
const onSign = useCallback(async () => {
|
||||||
async (event) => {
|
try {
|
||||||
try {
|
await dispatch(resolvePendingApproval(id, null));
|
||||||
await signPersonalMessage(event);
|
dispatch(completedTx(id));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(e);
|
log.error(e);
|
||||||
}
|
}
|
||||||
},
|
}, [id, dispatch]);
|
||||||
[signPersonalMessage],
|
|
||||||
);
|
|
||||||
|
|
||||||
const onCancel = useCallback(
|
const onCancel = useCallback(async () => {
|
||||||
async (event) => {
|
try {
|
||||||
try {
|
await dispatch(
|
||||||
await cancelPersonalMessage(event);
|
rejectPendingApproval(
|
||||||
} catch (e) {
|
id,
|
||||||
log.error(e);
|
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||||
}
|
),
|
||||||
},
|
);
|
||||||
[cancelPersonalMessage],
|
} catch (e) {
|
||||||
);
|
log.error(e);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleCancelAll = () => {
|
const handleCancelAll = () => {
|
||||||
const unapprovedTxCount = messagesCount;
|
const unapprovedTxCount = messagesCount;
|
||||||
@ -112,7 +115,7 @@ export default function SignatureRequestSIWE({
|
|||||||
name: 'REJECT_TRANSACTIONS',
|
name: 'REJECT_TRANSACTIONS',
|
||||||
unapprovedTxCount,
|
unapprovedTxCount,
|
||||||
onSubmit: async () => {
|
onSubmit: async () => {
|
||||||
await dispatch(cancelMsgs(valuesFor(messagesList)));
|
await dispatch(rejectAllMessages(valuesFor(messagesList)));
|
||||||
dispatch(clearConfirmTransaction());
|
dispatch(clearConfirmTransaction());
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
},
|
},
|
||||||
@ -242,12 +245,4 @@ SignatureRequestSIWE.propTypes = {
|
|||||||
* The display content of transaction data
|
* The display content of transaction data
|
||||||
*/
|
*/
|
||||||
txData: PropTypes.object.isRequired,
|
txData: PropTypes.object.isRequired,
|
||||||
/**
|
|
||||||
* Handler for cancel button
|
|
||||||
*/
|
|
||||||
cancelPersonalMessage: PropTypes.func.isRequired,
|
|
||||||
/**
|
|
||||||
* Handler for sign button
|
|
||||||
*/
|
|
||||||
signPersonalMessage: PropTypes.func.isRequired,
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { memoize } from 'lodash';
|
import { memoize } from 'lodash';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||||
import LedgerInstructionField from '../ledger-instruction-field';
|
import LedgerInstructionField from '../ledger-instruction-field';
|
||||||
import {
|
import {
|
||||||
sanitizeMessage,
|
sanitizeMessage,
|
||||||
@ -62,14 +63,7 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
* Check if the wallet is ledget wallet or not
|
* Check if the wallet is ledget wallet or not
|
||||||
*/
|
*/
|
||||||
isLedgerWallet: PropTypes.bool,
|
isLedgerWallet: PropTypes.bool,
|
||||||
/**
|
|
||||||
* Handler for cancel button
|
|
||||||
*/
|
|
||||||
cancel: PropTypes.func.isRequired,
|
|
||||||
/**
|
|
||||||
* Handler for sign button
|
|
||||||
*/
|
|
||||||
sign: PropTypes.func.isRequired,
|
|
||||||
/**
|
/**
|
||||||
* Whether the hardware wallet requires a connection disables the sign button if true.
|
* Whether the hardware wallet requires a connection disables the sign button if true.
|
||||||
*/
|
*/
|
||||||
@ -92,10 +86,14 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
history: PropTypes.object,
|
history: PropTypes.object,
|
||||||
mostRecentOverviewPage: PropTypes.string,
|
mostRecentOverviewPage: PropTypes.string,
|
||||||
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
|
showRejectTransactionsConfirmationModal: PropTypes.func.isRequired,
|
||||||
cancelAll: PropTypes.func.isRequired,
|
cancelAllApprovals: PropTypes.func.isRequired,
|
||||||
|
resolvePendingApproval: PropTypes.func.isRequired,
|
||||||
|
rejectPendingApproval: PropTypes.func.isRequired,
|
||||||
|
completedTx: PropTypes.func.isRequired,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
showCustodianDeepLink: PropTypes.func,
|
showCustodianDeepLink: PropTypes.func,
|
||||||
isNotification: PropTypes.bool,
|
isNotification: PropTypes.bool,
|
||||||
|
mmiOnSignCallback: PropTypes.func,
|
||||||
// Used to show a warning if the signing account is not the selected account
|
// Used to show a warning if the signing account is not the selected account
|
||||||
// Largely relevant for contract wallet custodians
|
// Largely relevant for contract wallet custodians
|
||||||
selectedAccount: PropTypes.object,
|
selectedAccount: PropTypes.object,
|
||||||
@ -150,18 +148,18 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
|
|
||||||
handleCancelAll = () => {
|
handleCancelAll = () => {
|
||||||
const {
|
const {
|
||||||
cancelAll,
|
|
||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
history,
|
history,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
showRejectTransactionsConfirmationModal,
|
showRejectTransactionsConfirmationModal,
|
||||||
unapprovedMessagesCount,
|
unapprovedMessagesCount,
|
||||||
|
cancelAllApprovals,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
showRejectTransactionsConfirmationModal({
|
showRejectTransactionsConfirmationModal({
|
||||||
unapprovedTxCount: unapprovedMessagesCount,
|
unapprovedTxCount: unapprovedMessagesCount,
|
||||||
onSubmit: async () => {
|
onSubmit: async () => {
|
||||||
await cancelAll();
|
await cancelAllApprovals();
|
||||||
clearConfirmTransaction();
|
clearConfirmTransaction();
|
||||||
history.push(mostRecentOverviewPage);
|
history.push(mostRecentOverviewPage);
|
||||||
},
|
},
|
||||||
@ -174,10 +172,9 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
txData: {
|
txData: {
|
||||||
msgParams: { data, origin, version },
|
msgParams: { data, origin, version },
|
||||||
type,
|
type,
|
||||||
|
id,
|
||||||
},
|
},
|
||||||
fromAccount: { address, balance, name },
|
fromAccount: { address, balance, name },
|
||||||
cancel,
|
|
||||||
sign,
|
|
||||||
isLedgerWallet,
|
isLedgerWallet,
|
||||||
hardwareWalletRequiresConnection,
|
hardwareWalletRequiresConnection,
|
||||||
chainId,
|
chainId,
|
||||||
@ -188,6 +185,9 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
currentCurrency,
|
currentCurrency,
|
||||||
conversionRate,
|
conversionRate,
|
||||||
unapprovedMessagesCount,
|
unapprovedMessagesCount,
|
||||||
|
resolvePendingApproval,
|
||||||
|
rejectPendingApproval,
|
||||||
|
completedTx,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const { t, trackEvent } = this.context;
|
const { t, trackEvent } = this.context;
|
||||||
@ -221,8 +221,15 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
.toBase(10)
|
.toBase(10)
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
const onSign = (event) => {
|
const onSign = async () => {
|
||||||
sign(event);
|
await resolvePendingApproval(id);
|
||||||
|
completedTx(id);
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
if (this.props.mmiOnSignCallback) {
|
||||||
|
await this.props.mmiOnSignCallback(txData);
|
||||||
|
}
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
trackEvent({
|
trackEvent({
|
||||||
category: MetaMetricsEventCategory.Transactions,
|
category: MetaMetricsEventCategory.Transactions,
|
||||||
event: 'Confirm',
|
event: 'Confirm',
|
||||||
@ -235,8 +242,11 @@ export default class SignatureRequest extends PureComponent {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = (event) => {
|
const onCancel = async () => {
|
||||||
cancel(event);
|
await rejectPendingApproval(
|
||||||
|
id,
|
||||||
|
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||||
|
);
|
||||||
trackEvent({
|
trackEvent({
|
||||||
category: MetaMetricsEventCategory.Transactions,
|
category: MetaMetricsEventCategory.Transactions,
|
||||||
event: 'Cancel',
|
event: 'Cancel',
|
||||||
|
@ -13,6 +13,7 @@ import {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
getAccountType,
|
getAccountType,
|
||||||
getSelectedAccount,
|
getSelectedAccount,
|
||||||
|
unapprovedTypedMessagesSelector,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
} from '../../../selectors';
|
} from '../../../selectors';
|
||||||
import {
|
import {
|
||||||
@ -29,16 +30,20 @@ import {
|
|||||||
setTypedMessageInProgress,
|
setTypedMessageInProgress,
|
||||||
} from '../../../store/institutional/institution-background';
|
} from '../../../store/institutional/institution-background';
|
||||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||||
|
import { checkForUnapprovedTypedMessages } from '../../../store/institutional/institution-actions';
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
import {
|
import {
|
||||||
MESSAGE_TYPE,
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
} from '../../../../shared/constants/app';
|
} from '../../../../shared/constants/app';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
cancelMsgs,
|
|
||||||
showModal,
|
showModal,
|
||||||
|
resolvePendingApproval,
|
||||||
|
rejectPendingApproval,
|
||||||
|
rejectAllMessages,
|
||||||
|
completedTx,
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
goHome,
|
goHome,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
@ -89,6 +94,7 @@ function mapStateToProps(state, ownProps) {
|
|||||||
accountType: getAccountType(state),
|
accountType: getAccountType(state),
|
||||||
isNotification: envType === ENVIRONMENT_TYPE_NOTIFICATION,
|
isNotification: envType === ENVIRONMENT_TYPE_NOTIFICATION,
|
||||||
selectedAccount: getSelectedAccount(state),
|
selectedAccount: getSelectedAccount(state),
|
||||||
|
unapprovedTypedMessages: unapprovedTypedMessagesSelector(state),
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -143,6 +149,10 @@ mapDispatchToProps = mmiMapDispatchToProps;
|
|||||||
|
|
||||||
mapDispatchToProps = function (dispatch) {
|
mapDispatchToProps = function (dispatch) {
|
||||||
return {
|
return {
|
||||||
|
resolvePendingApproval: (id) => dispatch(resolvePendingApproval(id)),
|
||||||
|
completedTx: (id) => dispatch(completedTx(id)),
|
||||||
|
rejectPendingApproval: (id, error) =>
|
||||||
|
dispatch(rejectPendingApproval(id, error)),
|
||||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||||
showRejectTransactionsConfirmationModal: ({
|
showRejectTransactionsConfirmationModal: ({
|
||||||
onSubmit,
|
onSubmit,
|
||||||
@ -157,8 +167,9 @@ mapDispatchToProps = function (dispatch) {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
cancelAll: (unconfirmedMessagesList) =>
|
cancelAllApprovals: (unconfirmedMessagesList) => {
|
||||||
dispatch(cancelMsgs(unconfirmedMessagesList)),
|
dispatch(rejectAllMessages(unconfirmedMessagesList));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -180,49 +191,33 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
accountType,
|
accountType,
|
||||||
isNotification,
|
isNotification,
|
||||||
|
unapprovedTypedMessages,
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
} = stateProps;
|
} = stateProps;
|
||||||
const {
|
const { txData } = ownProps;
|
||||||
signPersonalMessage,
|
|
||||||
signTypedMessage,
|
const {
|
||||||
cancelPersonalMessage,
|
cancelAll: dispatchCancelAll,
|
||||||
cancelTypedMessage,
|
cancelAllApprovals: dispatchCancelAllApprovals,
|
||||||
signMessage,
|
} = dispatchProps;
|
||||||
cancelMessage,
|
|
||||||
txData,
|
|
||||||
} = ownProps;
|
|
||||||
|
|
||||||
const { cancelAll: dispatchCancelAll } = dispatchProps;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
type,
|
|
||||||
msgParams: { from },
|
msgParams: { from },
|
||||||
} = txData;
|
} = txData;
|
||||||
|
|
||||||
const fromAccount = getAccountByAddress(allAccounts, from);
|
const fromAccount = getAccountByAddress(allAccounts, from);
|
||||||
|
|
||||||
let cancel;
|
|
||||||
let sign;
|
|
||||||
|
|
||||||
if (type === MESSAGE_TYPE.PERSONAL_SIGN) {
|
|
||||||
cancel = cancelPersonalMessage;
|
|
||||||
sign = signPersonalMessage;
|
|
||||||
} else if (type === MESSAGE_TYPE.ETH_SIGN_TYPED_DATA) {
|
|
||||||
cancel = cancelTypedMessage;
|
|
||||||
sign = signTypedMessage;
|
|
||||||
} else if (type === MESSAGE_TYPE.ETH_SIGN) {
|
|
||||||
cancel = cancelMessage;
|
|
||||||
sign = signMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
const signFn = async (...opts) => {
|
const mmiOnSignCallback = async (_msgData) => {
|
||||||
if (accountType === 'custody') {
|
if (accountType === 'custody') {
|
||||||
try {
|
try {
|
||||||
let msgData = opts;
|
let msgData = _msgData;
|
||||||
let id = opts.custodyId;
|
let id = _msgData.custodyId;
|
||||||
if (!opts.custodyId) {
|
if (!_msgData.custodyId) {
|
||||||
msgData = await sign(opts);
|
msgData = checkForUnapprovedTypedMessages(
|
||||||
|
_msgData,
|
||||||
|
unapprovedTypedMessages,
|
||||||
|
);
|
||||||
id = msgData.custodyId;
|
id = msgData.custodyId;
|
||||||
}
|
}
|
||||||
dispatchProps.showCustodianDeepLink({
|
dispatchProps.showCustodianDeepLink({
|
||||||
@ -235,7 +230,6 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
await dispatchProps.setMsgInProgress(msgData.metamaskId);
|
await dispatchProps.setMsgInProgress(msgData.metamaskId);
|
||||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||||
await goHome();
|
await goHome();
|
||||||
return msgData;
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||||
await dispatchProps.showTransactionsFailedModal({
|
await dispatchProps.showTransactionsFailedModal({
|
||||||
@ -243,11 +237,8 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
closeNotification: true,
|
closeNotification: true,
|
||||||
operationFailed: true,
|
operationFailed: true,
|
||||||
});
|
});
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sign(opts);
|
|
||||||
};
|
};
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
@ -256,14 +247,6 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
...dispatchProps,
|
...dispatchProps,
|
||||||
fromAccount,
|
fromAccount,
|
||||||
txData,
|
txData,
|
||||||
cancel,
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask)
|
|
||||||
sign,
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
// eslint-disable-next-line no-dupe-keys
|
|
||||||
sign: signFn,
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
isLedgerWallet,
|
isLedgerWallet,
|
||||||
hardwareWalletRequiresConnection,
|
hardwareWalletRequiresConnection,
|
||||||
chainId,
|
chainId,
|
||||||
@ -276,6 +259,11 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
|||||||
unapprovedMessagesCount,
|
unapprovedMessagesCount,
|
||||||
mostRecentOverviewPage,
|
mostRecentOverviewPage,
|
||||||
cancelAll: () => dispatchCancelAll(valuesFor(unconfirmedMessagesList)),
|
cancelAll: () => dispatchCancelAll(valuesFor(unconfirmedMessagesList)),
|
||||||
|
cancelAllApprovals: () =>
|
||||||
|
dispatchCancelAllApprovals(valuesFor(unconfirmedMessagesList)),
|
||||||
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
|
mmiOnSignCallback,
|
||||||
|
///: END:ONLY_INCLUDE_IN
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
import { fireEvent, screen } from '@testing-library/react';
|
import { fireEvent, screen, act } from '@testing-library/react';
|
||||||
import configureMockStore from 'redux-mock-store';
|
import configureMockStore from 'redux-mock-store';
|
||||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||||
import SignatureRequest from './signature-request.container';
|
import SignatureRequest from './signature-request.container';
|
||||||
@ -90,6 +90,7 @@ describe('Signature Request', () => {
|
|||||||
clearConfirmTransaction: sinon.spy(),
|
clearConfirmTransaction: sinon.spy(),
|
||||||
cancelMessage: sinon.spy(),
|
cancelMessage: sinon.spy(),
|
||||||
cancel: sinon.stub().resolves(),
|
cancel: sinon.stub().resolves(),
|
||||||
|
rejectPendingApproval: sinon.stub().resolves(),
|
||||||
showRejectTransactionsConfirmationModal: sinon.stub().resolves(),
|
showRejectTransactionsConfirmationModal: sinon.stub().resolves(),
|
||||||
cancelAll: sinon.stub().resolves(),
|
cancelAll: sinon.stub().resolves(),
|
||||||
providerConfig: {
|
providerConfig: {
|
||||||
@ -97,6 +98,9 @@ describe('Signature Request', () => {
|
|||||||
},
|
},
|
||||||
unapprovedMessagesCount: 2,
|
unapprovedMessagesCount: 2,
|
||||||
sign: sinon.stub().resolves(),
|
sign: sinon.stub().resolves(),
|
||||||
|
cancelAllApprovals: sinon.stub().resolves(),
|
||||||
|
resolvePendingApproval: sinon.stub().resolves(),
|
||||||
|
completedTx: sinon.stub().resolves(),
|
||||||
txData: {
|
txData: {
|
||||||
msgParams: {
|
msgParams: {
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -162,22 +166,24 @@ describe('Signature Request', () => {
|
|||||||
propsWithFiat.clearConfirmTransaction.resetHistory();
|
propsWithFiat.clearConfirmTransaction.resetHistory();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cancel', () => {
|
it('cancel', async () => {
|
||||||
const cancelButton = screen.getByTestId('page-container-footer-cancel');
|
const cancelButton = screen.getByTestId('page-container-footer-cancel');
|
||||||
fireEvent.click(cancelButton);
|
await act(() => {
|
||||||
expect(propsWithFiat.cancel.calledOnce).toStrictEqual(true);
|
fireEvent.click(cancelButton);
|
||||||
|
});
|
||||||
|
expect(propsWithFiat.rejectPendingApproval.calledOnce).toStrictEqual(
|
||||||
|
true,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sign', () => {
|
it('sign', async () => {
|
||||||
const signButton = screen.getByTestId('page-container-footer-next');
|
const signButton = screen.getByTestId('page-container-footer-next');
|
||||||
fireEvent.click(signButton);
|
await act(() => {
|
||||||
expect(propsWithFiat.sign.calledOnce).toStrictEqual(true);
|
fireEvent.click(signButton);
|
||||||
});
|
});
|
||||||
|
expect(propsWithFiat.resolvePendingApproval.calledOnce).toStrictEqual(
|
||||||
it('cancelAll', () => {
|
true,
|
||||||
const cancelAll = screen.getByTestId('signature-request-reject-all');
|
);
|
||||||
fireEvent.click(cancelAll);
|
|
||||||
expect(propsWithFiat.cancelAll.calledOnce).toStrictEqual(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('have user warning', () => {
|
it('have user warning', () => {
|
||||||
|
@ -22,12 +22,6 @@ import { TransactionStatus } from '../../../shared/constants/transaction';
|
|||||||
import { getSendTo } from '../../ducks/send';
|
import { getSendTo } from '../../ducks/send';
|
||||||
import { getProviderConfig } from '../../ducks/metamask/metamask';
|
import { getProviderConfig } from '../../ducks/metamask/metamask';
|
||||||
|
|
||||||
const SIGN_MESSAGE_TYPE = {
|
|
||||||
MESSAGE: 'message',
|
|
||||||
PERSONAL: 'personal',
|
|
||||||
TYPED: 'typed',
|
|
||||||
};
|
|
||||||
|
|
||||||
const signatureSelect = (txData) => {
|
const signatureSelect = (txData) => {
|
||||||
const {
|
const {
|
||||||
type,
|
type,
|
||||||
@ -49,12 +43,6 @@ const signatureSelect = (txData) => {
|
|||||||
return SignatureRequestOriginal;
|
return SignatureRequestOriginal;
|
||||||
};
|
};
|
||||||
|
|
||||||
const stopPropagation = (event) => {
|
|
||||||
if (event?.stopPropagation) {
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const ConfirmTxScreen = ({ match }) => {
|
const ConfirmTxScreen = ({ match }) => {
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const { navigateToMostRecentOverviewPage } = useRouting();
|
const { navigateToMostRecentOverviewPage } = useRouting();
|
||||||
@ -182,34 +170,6 @@ const ConfirmTxScreen = ({ match }) => {
|
|||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const signMessage = (type) => (event) => {
|
|
||||||
stopPropagation(event);
|
|
||||||
const params = txData.msgParams;
|
|
||||||
params.metamaskId = txData.id;
|
|
||||||
let action;
|
|
||||||
if (type === SIGN_MESSAGE_TYPE.MESSAGE) {
|
|
||||||
action = actions.signMsg;
|
|
||||||
} else if (type === SIGN_MESSAGE_TYPE.PERSONAL) {
|
|
||||||
action = actions.signPersonalMsg;
|
|
||||||
} else {
|
|
||||||
action = actions.signTypedMsg;
|
|
||||||
}
|
|
||||||
return dispatch(action?.(params));
|
|
||||||
};
|
|
||||||
|
|
||||||
const cancelMessage = (type) => (event) => {
|
|
||||||
stopPropagation(event);
|
|
||||||
let action;
|
|
||||||
if (type === SIGN_MESSAGE_TYPE.MESSAGE) {
|
|
||||||
action = actions.cancelMsg;
|
|
||||||
} else if (type === SIGN_MESSAGE_TYPE.PERSONAL) {
|
|
||||||
action = actions.cancelPersonalMsg;
|
|
||||||
} else {
|
|
||||||
action = actions.cancelTypedMsg;
|
|
||||||
}
|
|
||||||
return dispatch(action(txData));
|
|
||||||
};
|
|
||||||
|
|
||||||
const SigComponent = signatureSelect(txData);
|
const SigComponent = signatureSelect(txData);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -219,12 +179,6 @@ const ConfirmTxScreen = ({ match }) => {
|
|||||||
identities={identities}
|
identities={identities}
|
||||||
currentCurrency={currentCurrency}
|
currentCurrency={currentCurrency}
|
||||||
blockGasLimit={blockGasLimit}
|
blockGasLimit={blockGasLimit}
|
||||||
signMessage={signMessage(SIGN_MESSAGE_TYPE.MESSAGE)}
|
|
||||||
signPersonalMessage={signMessage(SIGN_MESSAGE_TYPE.PERSONAL)}
|
|
||||||
signTypedMessage={signMessage(SIGN_MESSAGE_TYPE.TYPED)}
|
|
||||||
cancelMessage={cancelMessage(SIGN_MESSAGE_TYPE.MESSAGE)}
|
|
||||||
cancelPersonalMessage={cancelMessage(SIGN_MESSAGE_TYPE.PERSONAL)}
|
|
||||||
cancelTypedMessage={cancelMessage(SIGN_MESSAGE_TYPE.TYPED)}
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
selectedAccount={selectedAccount}
|
selectedAccount={selectedAccount}
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
@ -650,176 +650,6 @@ describe('Actions', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#signMsg', () => {
|
|
||||||
const msgParams = {
|
|
||||||
metamaskId: 123,
|
|
||||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
|
||||||
data: '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0',
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls signMsg in background', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
const signMessage = background.signMessage.callsFake((_, cb) =>
|
|
||||||
cb(null, defaultState.metamask),
|
|
||||||
);
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
await store.dispatch(actions.signMsg(msgParams));
|
|
||||||
expect(signMessage.callCount).toStrictEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('errors when signMessage in background throws', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
background.signMessage.callsFake((_, cb) => cb(new Error('error')));
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'SHOW_LOADING_INDICATION', payload: undefined },
|
|
||||||
{ type: 'DISPLAY_WARNING', payload: 'error' },
|
|
||||||
{ type: 'HIDE_LOADING_INDICATION' },
|
|
||||||
];
|
|
||||||
|
|
||||||
await expect(store.dispatch(actions.signMsg(msgParams))).rejects.toThrow(
|
|
||||||
'error',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#signPersonalMsg', () => {
|
|
||||||
const msgParams = {
|
|
||||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
|
||||||
data: '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0',
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls signPersonalMessage', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
const signPersonalMessage = background.signPersonalMessage.callsFake(
|
|
||||||
(_, cb) => cb(null, defaultState.metamask),
|
|
||||||
);
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
await store.dispatch(actions.signPersonalMsg(msgParams));
|
|
||||||
expect(signPersonalMessage.callCount).toStrictEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws if signPersonalMessage throws', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
background.signPersonalMessage.callsFake((_, cb) => {
|
|
||||||
cb(new Error('error'));
|
|
||||||
});
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'SHOW_LOADING_INDICATION', payload: undefined },
|
|
||||||
{ type: 'DISPLAY_WARNING', payload: 'error' },
|
|
||||||
{ type: 'HIDE_LOADING_INDICATION' },
|
|
||||||
];
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
store.dispatch(actions.signPersonalMsg(msgParams)),
|
|
||||||
).rejects.toThrow('error');
|
|
||||||
|
|
||||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#signTypedMsg', () => {
|
|
||||||
const msgParamsV3 = {
|
|
||||||
from: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc',
|
|
||||||
data: JSON.stringify({
|
|
||||||
types: {
|
|
||||||
EIP712Domain: [
|
|
||||||
{ name: 'name', type: 'string' },
|
|
||||||
{ name: 'version', type: 'string' },
|
|
||||||
{ name: 'chainId', type: 'uint256' },
|
|
||||||
{ name: 'verifyingContract', type: 'address' },
|
|
||||||
],
|
|
||||||
Person: [
|
|
||||||
{ name: 'name', type: 'string' },
|
|
||||||
{ name: 'wallet', type: 'address' },
|
|
||||||
],
|
|
||||||
Mail: [
|
|
||||||
{ name: 'from', type: 'Person' },
|
|
||||||
{ name: 'to', type: 'Person' },
|
|
||||||
{ name: 'contents', type: 'string' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
primaryType: 'Mail',
|
|
||||||
domain: {
|
|
||||||
name: 'Ether Mainl',
|
|
||||||
version: '1',
|
|
||||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
|
||||||
},
|
|
||||||
message: {
|
|
||||||
from: {
|
|
||||||
name: 'Cow',
|
|
||||||
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
|
||||||
},
|
|
||||||
to: {
|
|
||||||
name: 'Bob',
|
|
||||||
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
|
||||||
},
|
|
||||||
contents: 'Hello, Bob!',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
sinon.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('calls signTypedMsg in background with no error', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
const signTypedMsg = background.signTypedMessage.callsFake((_, cb) =>
|
|
||||||
cb(null, defaultState.metamask),
|
|
||||||
);
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
await store.dispatch(actions.signTypedMsg(msgParamsV3));
|
|
||||||
expect(signTypedMsg.callCount).toStrictEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('returns expected actions with error', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
background.signTypedMessage.callsFake((_, cb) => cb(new Error('error')));
|
|
||||||
|
|
||||||
_setBackgroundConnection(background);
|
|
||||||
|
|
||||||
const expectedActions = [
|
|
||||||
{ type: 'SHOW_LOADING_INDICATION', payload: undefined },
|
|
||||||
{ type: 'DISPLAY_WARNING', payload: 'error' },
|
|
||||||
{ type: 'HIDE_LOADING_INDICATION' },
|
|
||||||
];
|
|
||||||
|
|
||||||
await expect(store.dispatch(actions.signTypedMsg())).rejects.toThrow(
|
|
||||||
'error',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(store.getActions()).toStrictEqual(expectedActions);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#updateTransaction', () => {
|
describe('#updateTransaction', () => {
|
||||||
const txParams = {
|
const txParams = {
|
||||||
from: '0x1',
|
from: '0x1',
|
||||||
@ -2069,61 +1899,6 @@ describe('Actions', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#cancelMsgs', () => {
|
|
||||||
it('creates COMPLETED_TX with the cancelled messages IDs', async () => {
|
|
||||||
const store = mockStore();
|
|
||||||
|
|
||||||
const cancelTypedMessageStub = sinon.stub().callsFake((_, cb) => cb());
|
|
||||||
|
|
||||||
const cancelPersonalMessageStub = sinon.stub().callsFake((_, cb) => cb());
|
|
||||||
|
|
||||||
background.getApi.returns({
|
|
||||||
cancelTypedMessage: cancelTypedMessageStub,
|
|
||||||
cancelPersonalMessage: cancelPersonalMessageStub,
|
|
||||||
getState: sinon.stub().callsFake((cb) =>
|
|
||||||
cb(null, {
|
|
||||||
currentLocale: 'test',
|
|
||||||
selectedAddress: '0xFirstAddress',
|
|
||||||
providerConfig: {
|
|
||||||
chainId: '0x1',
|
|
||||||
},
|
|
||||||
accounts: {
|
|
||||||
'0xFirstAddress': {
|
|
||||||
balance: '0x0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
cachedBalances: {
|
|
||||||
'0x1': {
|
|
||||||
'0xFirstAddress': '0x0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
const msgsList = [
|
|
||||||
{ id: 7648683973086304, status: 'unapproved', type: 'personal_sign' },
|
|
||||||
{
|
|
||||||
id: 7648683973086303,
|
|
||||||
status: 'unapproved',
|
|
||||||
type: 'eth_signTypedData',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
_setBackgroundConnection(background.getApi());
|
|
||||||
|
|
||||||
await store.dispatch(actions.cancelMsgs(msgsList));
|
|
||||||
const resultantActions = store.getActions();
|
|
||||||
|
|
||||||
const expectedActions = resultantActions.filter(
|
|
||||||
(action) => action.type === 'COMPLETED_TX',
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(expectedActions[0].value.id).toStrictEqual(msgsList[0].id);
|
|
||||||
expect(expectedActions[1].value.id).toStrictEqual(msgsList[1].id);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('Desktop', () => {
|
describe('Desktop', () => {
|
||||||
describe('#setDesktopEnabled', () => {
|
describe('#setDesktopEnabled', () => {
|
||||||
it('calls background setDesktopEnabled method', async () => {
|
it('calls background setDesktopEnabled method', async () => {
|
||||||
|
@ -4,6 +4,7 @@ import { captureException } from '@sentry/browser';
|
|||||||
import { capitalize, isEqual } from 'lodash';
|
import { capitalize, isEqual } from 'lodash';
|
||||||
import { ThunkAction } from 'redux-thunk';
|
import { ThunkAction } from 'redux-thunk';
|
||||||
import { Action, AnyAction } from 'redux';
|
import { Action, AnyAction } from 'redux';
|
||||||
|
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||||
import { Hex, Json } from '@metamask/utils';
|
import { Hex, Json } from '@metamask/utils';
|
||||||
import {
|
import {
|
||||||
AssetsContractController,
|
AssetsContractController,
|
||||||
@ -15,14 +16,12 @@ import { PayloadAction } from '@reduxjs/toolkit';
|
|||||||
import { GasFeeController } from '@metamask/gas-fee-controller';
|
import { GasFeeController } from '@metamask/gas-fee-controller';
|
||||||
import { PermissionsRequest } from '@metamask/permission-controller';
|
import { PermissionsRequest } from '@metamask/permission-controller';
|
||||||
import { NonEmptyArray } from '@metamask/controller-utils';
|
import { NonEmptyArray } from '@metamask/controller-utils';
|
||||||
import { ethErrors } from 'eth-rpc-errors';
|
|
||||||
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
||||||
import switchDirection from '../../shared/lib/switch-direction';
|
import switchDirection from '../../shared/lib/switch-direction';
|
||||||
import {
|
import {
|
||||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||||
ORIGIN_METAMASK,
|
ORIGIN_METAMASK,
|
||||||
POLLING_TOKEN_ENVIRONMENT_TYPES,
|
POLLING_TOKEN_ENVIRONMENT_TYPES,
|
||||||
MESSAGE_TYPE,
|
|
||||||
} from '../../shared/constants/app';
|
} from '../../shared/constants/app';
|
||||||
import { getEnvironmentType, addHexPrefix } from '../../app/scripts/lib/util';
|
import { getEnvironmentType, addHexPrefix } from '../../app/scripts/lib/util';
|
||||||
import {
|
import {
|
||||||
@ -91,10 +90,7 @@ import { CustomGasSettings } from '../../app/scripts/controllers/transactions';
|
|||||||
import { ThemeType } from '../../shared/constants/preferences';
|
import { ThemeType } from '../../shared/constants/preferences';
|
||||||
import * as actionConstants from './actionConstants';
|
import * as actionConstants from './actionConstants';
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||||
import {
|
import { updateCustodyState } from './institutional/institution-actions';
|
||||||
checkForUnapprovedTypedMessages,
|
|
||||||
updateCustodyState,
|
|
||||||
} from './institutional/institution-actions';
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
import {
|
import {
|
||||||
generateActionId,
|
generateActionId,
|
||||||
@ -641,76 +637,6 @@ export function setCurrentCurrency(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function signMsg(
|
|
||||||
msgData: TemporaryMessageDataType['msgParams'],
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType['msgParams']>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
log.debug('action - signMsg');
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
log.debug(`actions calling background.signMessage`);
|
|
||||||
let newState;
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('signMessage', [msgData]);
|
|
||||||
} catch (error) {
|
|
||||||
logErrorWithMessage(error);
|
|
||||||
dispatch(displayWarning(error));
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
dispatch(completedTx(msgData.metamaskId));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function signPersonalMsg(
|
|
||||||
msgData: TemporaryMessageDataType['msgParams'],
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType['msgParams']>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
log.debug('action - signPersonalMsg');
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
log.debug(`actions calling background.signPersonalMessage`);
|
|
||||||
|
|
||||||
let newState;
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('signPersonalMessage', [msgData]);
|
|
||||||
} catch (error) {
|
|
||||||
logErrorWithMessage(error);
|
|
||||||
dispatch(displayWarning(error));
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
if (newState.unapprovedTypedMessages) {
|
|
||||||
return checkForUnapprovedTypedMessages(msgData, newState);
|
|
||||||
}
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
dispatch(completedTx(msgData.metamaskId));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function decryptMsgInline(
|
export function decryptMsgInline(
|
||||||
decryptedMsgData: TemporaryMessageDataType['msgParams'],
|
decryptedMsgData: TemporaryMessageDataType['msgParams'],
|
||||||
): ThunkAction<
|
): ThunkAction<
|
||||||
@ -805,44 +731,6 @@ export function encryptionPublicKeyMsg(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function signTypedMsg(
|
|
||||||
msgData: TemporaryMessageDataType['msgParams'],
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType['msgParams']>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
log.debug('action - signTypedMsg');
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
log.debug(`actions calling background.signTypedMessage`);
|
|
||||||
|
|
||||||
let newState: MetaMaskReduxState['metamask'];
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('signTypedMessage', [msgData]);
|
|
||||||
} catch (error) {
|
|
||||||
logErrorWithMessage(error);
|
|
||||||
dispatch(displayWarning(error));
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
|
||||||
if (newState.unapprovedTypedMessages) {
|
|
||||||
return checkForUnapprovedTypedMessages(msgData, newState);
|
|
||||||
}
|
|
||||||
///: END:ONLY_INCLUDE_IN
|
|
||||||
dispatch(completedTx(msgData.metamaskId));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function updateCustomNonce(value: string) {
|
export function updateCustomNonce(value: string) {
|
||||||
return {
|
return {
|
||||||
type: actionConstants.UPDATE_CUSTOM_NONCE,
|
type: actionConstants.UPDATE_CUSTOM_NONCE,
|
||||||
@ -1330,156 +1218,6 @@ export async function disableDesktop() {
|
|||||||
}
|
}
|
||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
|
|
||||||
export function cancelMsg(
|
|
||||||
msgData: TemporaryMessageDataType,
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
|
|
||||||
let newState;
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('cancelMessage', [msgData.id]);
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
dispatch(completedTx(msgData.id));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels all of the given messages
|
|
||||||
*
|
|
||||||
* @param msgDataList - a list of msg data objects
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
export function cancelMsgs(
|
|
||||||
msgDataList: TemporaryMessageDataType[],
|
|
||||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
|
|
||||||
try {
|
|
||||||
const msgIds = msgDataList.map(({ id }) => id);
|
|
||||||
const cancellations = msgDataList.map(
|
|
||||||
({ id, type }) =>
|
|
||||||
new Promise<void>((resolve, reject) => {
|
|
||||||
switch (type) {
|
|
||||||
case MESSAGE_TYPE.ETH_SIGN_TYPED_DATA:
|
|
||||||
callBackgroundMethod('cancelTypedMessage', [id], (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case MESSAGE_TYPE.PERSONAL_SIGN:
|
|
||||||
callBackgroundMethod('cancelPersonalMessage', [id], (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case MESSAGE_TYPE.ETH_DECRYPT:
|
|
||||||
callBackgroundMethod('cancelDecryptMessage', [id], (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case MESSAGE_TYPE.ETH_GET_ENCRYPTION_PUBLIC_KEY:
|
|
||||||
callBackgroundMethod(
|
|
||||||
'cancelEncryptionPublicKey',
|
|
||||||
[id],
|
|
||||||
(err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
case MESSAGE_TYPE.ETH_SIGN:
|
|
||||||
callBackgroundMethod('cancelMessage', [id], (err) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
reject(
|
|
||||||
new Error(
|
|
||||||
`MetaMask Message Signature: Unknown message type: ${id}`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
await Promise.all(cancellations);
|
|
||||||
const newState = await updateMetamaskStateFromBackground();
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
|
|
||||||
msgIds.forEach((id) => {
|
|
||||||
dispatch(completedTx(id));
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
logErrorWithMessage(err);
|
|
||||||
} finally {
|
|
||||||
if (getEnvironmentType() === ENVIRONMENT_TYPE_NOTIFICATION) {
|
|
||||||
closeNotificationPopup();
|
|
||||||
} else {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cancelPersonalMsg(
|
|
||||||
msgData: TemporaryMessageDataType,
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
|
|
||||||
let newState;
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('cancelPersonalMessage', [msgData.id]);
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
dispatch(completedTx(msgData.id));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cancelDecryptMsg(
|
export function cancelDecryptMsg(
|
||||||
msgData: TemporaryMessageDataType,
|
msgData: TemporaryMessageDataType,
|
||||||
): ThunkAction<
|
): ThunkAction<
|
||||||
@ -1534,33 +1272,6 @@ export function cancelEncryptionPublicKeyMsg(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function cancelTypedMsg(
|
|
||||||
msgData: TemporaryMessageDataType,
|
|
||||||
): ThunkAction<
|
|
||||||
Promise<TemporaryMessageDataType>,
|
|
||||||
MetaMaskReduxState,
|
|
||||||
unknown,
|
|
||||||
AnyAction
|
|
||||||
> {
|
|
||||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
|
||||||
dispatch(showLoadingIndication());
|
|
||||||
|
|
||||||
let newState;
|
|
||||||
try {
|
|
||||||
newState = await submitRequestToBackground<
|
|
||||||
MetaMaskReduxState['metamask']
|
|
||||||
>('cancelTypedMessage', [msgData.id]);
|
|
||||||
} finally {
|
|
||||||
dispatch(hideLoadingIndication());
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch(updateMetamaskState(newState));
|
|
||||||
dispatch(completedTx(msgData.id));
|
|
||||||
dispatch(closeCurrentNotificationWindow());
|
|
||||||
return msgData;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cancelTx(
|
export function cancelTx(
|
||||||
txMeta: TransactionMeta,
|
txMeta: TransactionMeta,
|
||||||
_showLoadingIndication = true,
|
_showLoadingIndication = true,
|
||||||
@ -3724,6 +3435,34 @@ export function rejectPendingApproval(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rejects all approvals for the given messages
|
||||||
|
*
|
||||||
|
* @param messageList - The list of messages to reject
|
||||||
|
*/
|
||||||
|
export function rejectAllMessages(
|
||||||
|
messageList: [],
|
||||||
|
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||||
|
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||||
|
const userRejectionError = serializeError(
|
||||||
|
ethErrors.provider.userRejectedRequest(),
|
||||||
|
);
|
||||||
|
await Promise.all(
|
||||||
|
messageList.map(
|
||||||
|
async ({ id }) =>
|
||||||
|
await submitRequestToBackground('rejectPendingApproval', [
|
||||||
|
id,
|
||||||
|
userRejectionError,
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const { pendingApprovals } = await forceUpdateMetamaskState(dispatch);
|
||||||
|
if (Object.values(pendingApprovals).length === 0) {
|
||||||
|
dispatch(closeCurrentNotificationWindow());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function setFirstTimeFlowType(
|
export function setFirstTimeFlowType(
|
||||||
type: 'create' | 'import',
|
type: 'create' | 'import',
|
||||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||||
|
@ -166,11 +166,9 @@ describe('#checkForUnapprovedTypedMessages', () => {
|
|||||||
status: 'unapproved',
|
status: 'unapproved',
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(
|
expect(checkForUnapprovedTypedMessages(messageData, { msg: 'msg' })).toBe(
|
||||||
checkForUnapprovedTypedMessages(messageData, {
|
messageData,
|
||||||
unapprovedTypedMessages: { msg: 'msg' },
|
);
|
||||||
}),
|
|
||||||
).toBe(messageData);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
CombinedBackgroundAndReduxState,
|
CombinedBackgroundAndReduxState,
|
||||||
MetaMaskReduxState,
|
MetaMaskReduxState,
|
||||||
TemporaryMessageDataType,
|
TemporaryMessageDataType,
|
||||||
|
MessagesIndexedById,
|
||||||
} from '../store';
|
} from '../store';
|
||||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||||
|
|
||||||
@ -110,19 +111,16 @@ export function updateCustodyState(
|
|||||||
|
|
||||||
export function checkForUnapprovedTypedMessages(
|
export function checkForUnapprovedTypedMessages(
|
||||||
msgData: TemporaryMessageDataType['msgParams'],
|
msgData: TemporaryMessageDataType['msgParams'],
|
||||||
newState: MetaMaskReduxState['metamask'],
|
unapprovedTypedMessages: MessagesIndexedById,
|
||||||
) {
|
) {
|
||||||
const custodianUnapprovedMessages = Object.keys(
|
const custodianUnapprovedMessages = Object.keys(unapprovedTypedMessages)
|
||||||
newState.unapprovedTypedMessages,
|
.map((key) => unapprovedTypedMessages[key])
|
||||||
)
|
|
||||||
.map((key) => newState.unapprovedTypedMessages[key])
|
|
||||||
.filter((message) => message.custodyId && message.status === 'unapproved');
|
.filter((message) => message.custodyId && message.status === 'unapproved');
|
||||||
|
|
||||||
if (custodianUnapprovedMessages && custodianUnapprovedMessages.length > 0) {
|
if (custodianUnapprovedMessages && custodianUnapprovedMessages.length > 0) {
|
||||||
return {
|
return {
|
||||||
...msgData,
|
...msgData,
|
||||||
custodyId:
|
custodyId: unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
||||||
newState.unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ export interface TemporaryMessageDataType {
|
|||||||
///: END:ONLY_INCLUDE_IN
|
///: END:ONLY_INCLUDE_IN
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MessagesIndexedById {
|
export interface MessagesIndexedById {
|
||||||
[id: string]: TemporaryMessageDataType;
|
[id: string]: TemporaryMessageDataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
45
yarn.lock
45
yarn.lock
@ -4333,9 +4333,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/message-manager@npm:^6.0.0":
|
"@metamask/message-manager@npm:^7.0.0":
|
||||||
version: 6.0.0
|
version: 7.0.0
|
||||||
resolution: "@metamask/message-manager@npm:6.0.0"
|
resolution: "@metamask/message-manager@npm:7.0.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@metamask/base-controller": ^3.0.0
|
"@metamask/base-controller": ^3.0.0
|
||||||
"@metamask/controller-utils": ^4.0.0
|
"@metamask/controller-utils": ^4.0.0
|
||||||
@ -4345,7 +4345,7 @@ __metadata:
|
|||||||
ethereumjs-util: ^7.0.10
|
ethereumjs-util: ^7.0.10
|
||||||
jsonschema: ^1.2.4
|
jsonschema: ^1.2.4
|
||||||
uuid: ^8.3.2
|
uuid: ^8.3.2
|
||||||
checksum: f1601145317739e06cb83aefb99cb12ecd717a164103e6094a753197dbf1b62e8eaa1e4aff8dd849d67d21358933cba7a6e1551eede0fcc32b7657496c4a2f2e
|
checksum: 1a7b785159d93153ef966a82bcdf9beea1a641cd663d2c1719cf6b671364f18b98c84795d23fa9872ec5e2bd9f08162c2c4d7369f46a81d12fd496b6433818a0
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -4683,39 +4683,22 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@metamask/signature-controller@npm:3.0.0":
|
"@metamask/signature-controller@npm:^4.0.1":
|
||||||
version: 3.0.0
|
version: 4.0.1
|
||||||
resolution: "@metamask/signature-controller@npm:3.0.0"
|
resolution: "@metamask/signature-controller@npm:4.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@metamask/approval-controller": ^3.0.0
|
"@metamask/approval-controller": ^3.3.0
|
||||||
"@metamask/base-controller": ^3.0.0
|
"@metamask/base-controller": ^3.0.0
|
||||||
"@metamask/controller-utils": ^4.0.0
|
"@metamask/controller-utils": ^4.0.0
|
||||||
"@metamask/message-manager": ^6.0.0
|
"@metamask/message-manager": ^7.0.0
|
||||||
"@metamask/utils": ^5.0.2
|
"@metamask/utils": ^5.0.2
|
||||||
eth-rpc-errors: ^4.0.2
|
eth-rpc-errors: ^4.0.2
|
||||||
ethereumjs-util: ^7.0.10
|
ethereumjs-util: ^7.0.10
|
||||||
immer: ^9.0.6
|
immer: ^9.0.6
|
||||||
|
lodash: ^4.17.21
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
"@metamask/approval-controller": ^3.0.0
|
"@metamask/approval-controller": ^3.3.0
|
||||||
checksum: 9afc2b8bc09d7cc6bab9d3e0bed1e70fd852cb78b0b07321afadac395cc0d7775697f99e1a846edd68afe8279929e3f763f09aa9b91eac682f0caed3e1c4fd5f
|
checksum: 8d510fe3761f2c0ac39bb6b9891497012e3608559480aee11f8f76556573521b01ecde334f1ffd71e8fc674243ae7fa111d0f2aaa36f4466d2e9466998af6618
|
||||||
languageName: node
|
|
||||||
linkType: hard
|
|
||||||
|
|
||||||
"@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A3.0.0#./.yarn/patches/@metamask-signature-controller-npm-3.0.0-8771b6885e.patch::locator=metamask-crx%40workspace%3A.":
|
|
||||||
version: 3.0.0
|
|
||||||
resolution: "@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A3.0.0#./.yarn/patches/@metamask-signature-controller-npm-3.0.0-8771b6885e.patch::version=3.0.0&hash=7fee95&locator=metamask-crx%40workspace%3A."
|
|
||||||
dependencies:
|
|
||||||
"@metamask/approval-controller": ^3.0.0
|
|
||||||
"@metamask/base-controller": ^3.0.0
|
|
||||||
"@metamask/controller-utils": ^4.0.0
|
|
||||||
"@metamask/message-manager": ^6.0.0
|
|
||||||
"@metamask/utils": ^5.0.2
|
|
||||||
eth-rpc-errors: ^4.0.2
|
|
||||||
ethereumjs-util: ^7.0.10
|
|
||||||
immer: ^9.0.6
|
|
||||||
peerDependencies:
|
|
||||||
"@metamask/approval-controller": ^3.0.0
|
|
||||||
checksum: 379cceaceaa4e120bbf9547b74d709f2a93117a17ec460e22e8935a54a1d10528f435563f6d9dcb1c4b9f521286033b23d5ec14063ea1c6f753953f5e0984a70
|
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -24363,7 +24346,7 @@ __metadata:
|
|||||||
"@metamask/jazzicon": ^2.0.0
|
"@metamask/jazzicon": ^2.0.0
|
||||||
"@metamask/key-tree": ^7.0.0
|
"@metamask/key-tree": ^7.0.0
|
||||||
"@metamask/logo": ^3.1.1
|
"@metamask/logo": ^3.1.1
|
||||||
"@metamask/message-manager": ^6.0.0
|
"@metamask/message-manager": ^7.0.0
|
||||||
"@metamask/metamask-eth-abis": ^3.0.0
|
"@metamask/metamask-eth-abis": ^3.0.0
|
||||||
"@metamask/notification-controller": ^3.0.0
|
"@metamask/notification-controller": ^3.0.0
|
||||||
"@metamask/obs-store": ^8.1.0
|
"@metamask/obs-store": ^8.1.0
|
||||||
@ -24377,7 +24360,7 @@ __metadata:
|
|||||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1"
|
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1"
|
||||||
"@metamask/safe-event-emitter": ^2.0.0
|
"@metamask/safe-event-emitter": ^2.0.0
|
||||||
"@metamask/scure-bip39": ^2.0.3
|
"@metamask/scure-bip39": ^2.0.3
|
||||||
"@metamask/signature-controller": ^3.0.0
|
"@metamask/signature-controller": ^4.0.1
|
||||||
"@metamask/slip44": ^3.0.0
|
"@metamask/slip44": ^3.0.0
|
||||||
"@metamask/smart-transactions-controller": ^3.1.0
|
"@metamask/smart-transactions-controller": ^3.1.0
|
||||||
"@metamask/snaps-controllers": ^0.32.2
|
"@metamask/snaps-controllers": ^0.32.2
|
||||||
|
Loading…
Reference in New Issue
Block a user