mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
Merge pull request #19910 from MetaMask/Version-v10.33.1
Version v10.33.1 RC
This commit is contained in:
commit
e72f829cde
@ -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) {
|
@ -0,0 +1,17 @@
|
||||
diff --git a/dist/SignatureController.js b/dist/SignatureController.js
|
||||
index b58b27e84aa84393afb366d4585c084d0380d21d..0629bcf517db744ccfa40e4d7d8f2829fa95559e 100644
|
||||
--- a/dist/SignatureController.js
|
||||
+++ b/dist/SignatureController.js
|
||||
@@ -237,8 +237,11 @@ _SignatureController_keyringController = new WeakMap(), _SignatureController_isE
|
||||
yield __classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_requestApproval).call(this, messageParamsWithId, approvalType);
|
||||
}
|
||||
catch (error) {
|
||||
+ signaturePromise.catch(() => {
|
||||
+ // Expecting reject error but throwing manually rather than waiting
|
||||
+ });
|
||||
__classPrivateFieldGet(this, _SignatureController_instances, "m", _SignatureController_cancelAbstractMessage).call(this, messageManager, messageId);
|
||||
- throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest('User rejected the request.');
|
||||
+ throw eth_rpc_errors_1.ethErrors.provider.userRejectedRequest(`MetaMask ${messageName} Signature: User denied message signature.`);
|
||||
}
|
||||
yield signMessage(messageParamsWithId, version, signingOpts);
|
||||
return signaturePromise;
|
@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [10.33.1]
|
||||
### Fixed
|
||||
- Fix to bug causing users to see an infinite spinner when signing typed messages. ([#19894](https://github.com/MetaMask/metamask-extension/pull/19894))
|
||||
|
||||
## [10.33.0]
|
||||
### Added
|
||||
- UI Upgrade ([#18903](https://github.com/MetaMask/metamask-extension/pull/18903))
|
||||
@ -3825,7 +3829,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Uncategorized
|
||||
- Added the ability to restore accounts from seed words.
|
||||
|
||||
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.33.0...HEAD
|
||||
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.33.1...HEAD
|
||||
[10.33.1]: https://github.com/MetaMask/metamask-extension/compare/v10.33.0...v10.33.1
|
||||
[10.33.0]: https://github.com/MetaMask/metamask-extension/compare/v10.32.0...v10.33.0
|
||||
[10.32.0]: https://github.com/MetaMask/metamask-extension/compare/v10.31.1...v10.32.0
|
||||
[10.31.1]: https://github.com/MetaMask/metamask-extension/compare/v10.31.0...v10.31.1
|
||||
|
@ -45,7 +45,7 @@ export type CoreMessage = AbstractMessage & {
|
||||
};
|
||||
|
||||
export type StateMessage = Required<
|
||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata'>
|
||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata' | 'error'>
|
||||
>;
|
||||
|
||||
export type DecryptMessageControllerState = {
|
||||
|
@ -45,7 +45,7 @@ export type CoreMessage = AbstractMessage & {
|
||||
};
|
||||
|
||||
export type StateMessage = Required<
|
||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata'>
|
||||
Omit<AbstractMessage, 'securityProviderResponse' | 'metadata' | 'error'>
|
||||
> & {
|
||||
msgParams: string;
|
||||
};
|
||||
|
@ -1258,11 +1258,7 @@ export default class MetamaskController extends EventEmitter {
|
||||
this.signatureController = new SignatureController({
|
||||
messenger: this.controllerMessenger.getRestricted({
|
||||
name: 'SignatureController',
|
||||
allowedActions: [
|
||||
`${this.approvalController.name}:addRequest`,
|
||||
`${this.approvalController.name}:acceptRequest`,
|
||||
`${this.approvalController.name}:rejectRequest`,
|
||||
],
|
||||
allowedActions: [`${this.approvalController.name}:addRequest`],
|
||||
}),
|
||||
keyringController: this.keyringController,
|
||||
isEthSignEnabled: () =>
|
||||
@ -2248,27 +2244,6 @@ export default class MetamaskController extends EventEmitter {
|
||||
updatePreviousGasParams:
|
||||
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
|
||||
decryptMessage: this.decryptMessageController.decryptMessage.bind(
|
||||
this.decryptMessageController,
|
||||
|
@ -1718,7 +1718,8 @@
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"eth-rpc-errors": true,
|
||||
"ethereumjs-util": true
|
||||
"ethereumjs-util": true,
|
||||
"lodash": true
|
||||
}
|
||||
},
|
||||
"@metamask/smart-transactions-controller": {
|
||||
|
@ -1908,7 +1908,8 @@
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"eth-rpc-errors": true,
|
||||
"ethereumjs-util": true
|
||||
"ethereumjs-util": true,
|
||||
"lodash": true
|
||||
}
|
||||
},
|
||||
"@metamask/smart-transactions-controller": {
|
||||
|
@ -1908,7 +1908,8 @@
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"eth-rpc-errors": true,
|
||||
"ethereumjs-util": true
|
||||
"ethereumjs-util": true,
|
||||
"lodash": true
|
||||
}
|
||||
},
|
||||
"@metamask/smart-transactions-controller": {
|
||||
|
@ -1718,7 +1718,8 @@
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"eth-rpc-errors": true,
|
||||
"ethereumjs-util": true
|
||||
"ethereumjs-util": true,
|
||||
"lodash": true
|
||||
}
|
||||
},
|
||||
"@metamask/smart-transactions-controller": {
|
||||
|
@ -1939,7 +1939,8 @@
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"eth-rpc-errors": true,
|
||||
"ethereumjs-util": true
|
||||
"ethereumjs-util": true,
|
||||
"lodash": true
|
||||
}
|
||||
},
|
||||
"@metamask/smart-transactions-controller": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "metamask-crx",
|
||||
"version": "10.33.0",
|
||||
"version": "10.33.1",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -197,7 +197,7 @@
|
||||
"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.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"
|
||||
"@metamask/signature-controller@^4.0.1": "patch:@metamask/signature-controller@npm%3A4.0.1#./.yarn/patches/@metamask-signature-controller-npm-4.0.1-013e64c9fd.patch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
@ -248,7 +248,7 @@
|
||||
"@metamask/jazzicon": "^2.0.0",
|
||||
"@metamask/key-tree": "^7.0.0",
|
||||
"@metamask/logo": "^3.1.1",
|
||||
"@metamask/message-manager": "^6.0.0",
|
||||
"@metamask/message-manager": "^7.0.2",
|
||||
"@metamask/metamask-eth-abis": "^3.0.0",
|
||||
"@metamask/notification-controller": "^3.0.0",
|
||||
"@metamask/obs-store": "^8.1.0",
|
||||
@ -261,7 +261,7 @@
|
||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1",
|
||||
"@metamask/safe-event-emitter": "^2.0.0",
|
||||
"@metamask/scure-bip39": "^2.0.3",
|
||||
"@metamask/signature-controller": "^3.0.0",
|
||||
"@metamask/signature-controller": "^4.0.1",
|
||||
"@metamask/slip44": "^3.0.0",
|
||||
"@metamask/smart-transactions-controller": "^3.1.0",
|
||||
"@metamask/snaps-controllers": "^0.32.2",
|
||||
|
@ -176,7 +176,7 @@ export async function determineTransactionType(txParams, query) {
|
||||
contractCode = resultCode;
|
||||
|
||||
if (isContractAddress) {
|
||||
const hasValue = txParams.value && txParams.value !== '0x0';
|
||||
const hasValue = txParams.value && Number(txParams.value) !== 0;
|
||||
|
||||
const tokenMethodName = [
|
||||
TransactionType.tokenMethodApprove,
|
||||
|
@ -186,6 +186,20 @@ describe('Transaction.utils', function () {
|
||||
getCodeResponse: '0xab',
|
||||
});
|
||||
|
||||
const resultWithEmptyValue2 = await determineTransactionType(
|
||||
{
|
||||
value: '0x0000',
|
||||
to: '0x9e673399f795D01116e9A8B2dD2F156705131ee9',
|
||||
data: '0xa9059cbb0000000000000000000000002f318C334780961FB129D2a6c30D0763d9a5C970000000000000000000000000000000000000000000000000000000000000000a',
|
||||
},
|
||||
new EthQuery(_provider),
|
||||
);
|
||||
|
||||
expect(resultWithEmptyValue2).toMatchObject({
|
||||
type: TransactionType.tokenMethodTransfer,
|
||||
getCodeResponse: '0xab',
|
||||
});
|
||||
|
||||
const resultWithValue = await determineTransactionType(
|
||||
{
|
||||
value: '0x12345',
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import { getCurrentQRHardwareState } from '../../../selectors';
|
||||
import Popover from '../../ui/popover';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
@ -7,11 +8,8 @@ import {
|
||||
cancelSyncQRHardware as cancelSyncQRHardwareAction,
|
||||
cancelQRHardwareSignRequest as cancelQRHardwareSignRequestAction,
|
||||
cancelTx,
|
||||
cancelPersonalMsg,
|
||||
cancelMsg,
|
||||
cancelTypedMsg,
|
||||
rejectPendingApproval,
|
||||
} from '../../../store/actions';
|
||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||
import QRHardwareWalletImporter from './qr-hardware-wallet-importer';
|
||||
import QRHardwareSignRequest from './qr-hardware-sign-request';
|
||||
|
||||
@ -43,25 +41,13 @@ const QRHardwarePopover = () => {
|
||||
);
|
||||
|
||||
const signRequestCancel = useCallback(() => {
|
||||
let action = cancelTx;
|
||||
switch (_txData.type) {
|
||||
case MESSAGE_TYPE.PERSONAL_SIGN: {
|
||||
action = cancelPersonalMsg;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE.ETH_SIGN: {
|
||||
action = cancelMsg;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_TYPE.ETH_SIGN_TYPED_DATA: {
|
||||
action = cancelTypedMsg;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
action = cancelTx;
|
||||
}
|
||||
}
|
||||
dispatch(action(_txData));
|
||||
dispatch(
|
||||
rejectPendingApproval(
|
||||
_txData.id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
),
|
||||
);
|
||||
dispatch(cancelTx(_txData));
|
||||
dispatch(cancelQRHardwareSignRequestAction());
|
||||
}, [dispatch, _txData]);
|
||||
|
||||
|
@ -96,6 +96,7 @@ const SignatureRequestOriginalWarning = ({
|
||||
<Button
|
||||
className="signature-request-warning__footer__sign-button"
|
||||
type="danger-primary"
|
||||
data-testid="signature-warning-sign-button"
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{t('sign')}
|
||||
|
@ -2,6 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classnames from 'classnames';
|
||||
import { ObjectInspector } from 'react-inspector';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import LedgerInstructionField from '../ledger-instruction-field';
|
||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||
import {
|
||||
@ -49,18 +50,19 @@ export default class SignatureRequestOriginal extends Component {
|
||||
address: PropTypes.string.isRequired,
|
||||
name: PropTypes.string,
|
||||
}).isRequired,
|
||||
cancel: PropTypes.func.isRequired,
|
||||
clearConfirmTransaction: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
mostRecentOverviewPage: PropTypes.string.isRequired,
|
||||
sign: PropTypes.func.isRequired,
|
||||
txData: PropTypes.object.isRequired,
|
||||
subjectMetadata: PropTypes.object,
|
||||
hardwareWalletRequiresConnection: PropTypes.bool,
|
||||
isLedgerWallet: PropTypes.bool,
|
||||
messagesCount: PropTypes.number,
|
||||
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)
|
||||
selectedAccount: PropTypes.object,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
@ -230,33 +232,48 @@ export default class SignatureRequestOriginal extends Component {
|
||||
);
|
||||
};
|
||||
|
||||
onSubmit = async (event) => {
|
||||
const { clearConfirmTransaction, history, mostRecentOverviewPage, sign } =
|
||||
this.props;
|
||||
onSubmit = async () => {
|
||||
const {
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
resolvePendingApproval,
|
||||
completedTx,
|
||||
txData: { id },
|
||||
} = this.props;
|
||||
|
||||
await sign(event);
|
||||
await resolvePendingApproval(id);
|
||||
completedTx(id);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
};
|
||||
|
||||
onCancel = async (event) => {
|
||||
const { clearConfirmTransaction, history, mostRecentOverviewPage, cancel } =
|
||||
this.props;
|
||||
onCancel = async () => {
|
||||
const {
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
rejectPendingApproval,
|
||||
txData: { id },
|
||||
} = this.props;
|
||||
|
||||
await cancel(event);
|
||||
await rejectPendingApproval(
|
||||
id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
};
|
||||
|
||||
renderFooter = () => {
|
||||
const {
|
||||
cancel,
|
||||
sign,
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
txData: { type },
|
||||
txData: { type, id },
|
||||
hardwareWalletRequiresConnection,
|
||||
rejectPendingApproval,
|
||||
resolvePendingApproval,
|
||||
} = this.props;
|
||||
const { t } = this.context;
|
||||
|
||||
@ -264,16 +281,19 @@ export default class SignatureRequestOriginal extends Component {
|
||||
<PageContainerFooter
|
||||
cancelText={t('reject')}
|
||||
submitText={t('sign')}
|
||||
onCancel={async (event) => {
|
||||
await cancel(event);
|
||||
onCancel={async () => {
|
||||
await rejectPendingApproval(
|
||||
id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
}}
|
||||
onSubmit={async (event) => {
|
||||
onSubmit={async () => {
|
||||
if (type === MESSAGE_TYPE.ETH_SIGN) {
|
||||
this.setState({ showSignatureRequestWarning: true });
|
||||
} else {
|
||||
await sign(event);
|
||||
await resolvePendingApproval(id);
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
}
|
||||
@ -285,19 +305,19 @@ export default class SignatureRequestOriginal extends Component {
|
||||
|
||||
handleCancelAll = () => {
|
||||
const {
|
||||
cancelAll,
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
showRejectTransactionsConfirmationModal,
|
||||
messagesCount,
|
||||
cancelAllApprovals,
|
||||
} = this.props;
|
||||
const unapprovedTxCount = messagesCount;
|
||||
|
||||
showRejectTransactionsConfirmationModal({
|
||||
unapprovedTxCount,
|
||||
onSubmit: async () => {
|
||||
await cancelAll();
|
||||
await cancelAllApprovals();
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
},
|
||||
|
@ -1,9 +1,14 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { compose } from 'redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||
import { goHome, cancelMsgs, showModal } from '../../../store/actions';
|
||||
import {
|
||||
goHome,
|
||||
showModal,
|
||||
resolvePendingApproval,
|
||||
rejectPendingApproval,
|
||||
rejectAllMessages,
|
||||
completedTx,
|
||||
} from '../../../store/actions';
|
||||
import {
|
||||
accountsWithSendEtherInfoSelector,
|
||||
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) {
|
||||
const {
|
||||
signPersonalMessage,
|
||||
signTypedMessage,
|
||||
cancelPersonalMessage,
|
||||
cancelTypedMessage,
|
||||
signMessage,
|
||||
cancelMessage,
|
||||
txData,
|
||||
} = ownProps;
|
||||
const { txData } = ownProps;
|
||||
|
||||
const { allAccounts, messagesList, ...otherStateProps } = stateProps;
|
||||
|
||||
const {
|
||||
type,
|
||||
msgParams: { from },
|
||||
} = txData;
|
||||
|
||||
const fromAccount = getAccountByAddress(allAccounts, from);
|
||||
|
||||
const { cancelAll: dispatchCancelAll } = 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;
|
||||
}
|
||||
const { cancelAllApprovals: dispatchCancelAllApprovals } = dispatchProps;
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
@ -110,9 +101,8 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
...dispatchProps,
|
||||
fromAccount,
|
||||
txData,
|
||||
cancel,
|
||||
sign,
|
||||
cancelAll: () => dispatchCancelAll(valuesFor(messagesList)),
|
||||
cancelAllApprovals: () =>
|
||||
dispatchCancelAllApprovals(valuesFor(messagesList)),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,25 @@
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import { fireEvent, screen } from '@testing-library/react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { MESSAGE_TYPE } from '../../../../shared/constants/app';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import configureStore from '../../../store/store';
|
||||
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 '.';
|
||||
|
||||
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({
|
||||
domain: {
|
||||
name: 'happydapp.website',
|
||||
@ -92,12 +104,30 @@ describe('SignatureRequestOriginal', () => {
|
||||
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();
|
||||
const signButton = screen.getByTestId('page-container-footer-next');
|
||||
|
||||
fireEvent.click(signButton);
|
||||
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', () => {
|
||||
|
@ -4,6 +4,7 @@ import { useSelector, useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import log from 'loglevel';
|
||||
import { isValidSIWEOrigin } from '@metamask/controller-utils';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import { BannerAlert, Text } from '../../component-library';
|
||||
import Popover from '../../ui/popover';
|
||||
import Checkbox from '../../ui/check-box';
|
||||
@ -25,27 +26,28 @@ import {
|
||||
SEVERITIES,
|
||||
TextVariant,
|
||||
} 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 { 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 { getMostRecentOverviewPage } from '../../../ducks/history/history';
|
||||
import { showModal, cancelMsgs } from '../../../store/actions';
|
||||
import LedgerInstructionField from '../ledger-instruction-field';
|
||||
|
||||
import SignatureRequestHeader from '../signature-request-header';
|
||||
import Header from './signature-request-siwe-header';
|
||||
import Message from './signature-request-siwe-message';
|
||||
|
||||
export default function SignatureRequestSIWE({
|
||||
txData,
|
||||
cancelPersonalMessage,
|
||||
signPersonalMessage,
|
||||
}) {
|
||||
export default function SignatureRequestSIWE({ txData }) {
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const t = useContext(I18nContext);
|
||||
|
||||
const allAccounts = useSelector(accountsWithSendEtherInfoSelector);
|
||||
const subjectMetadata = useSelector(getSubjectMetadata);
|
||||
|
||||
@ -59,6 +61,7 @@ export default function SignatureRequestSIWE({
|
||||
origin,
|
||||
siwe: { parsedMessage },
|
||||
},
|
||||
id,
|
||||
} = txData;
|
||||
|
||||
const isLedgerWallet = useSelector((state) => isAddressLedger(state, from));
|
||||
@ -82,27 +85,27 @@ export default function SignatureRequestSIWE({
|
||||
(txData?.securityProviderResponse &&
|
||||
Object.keys(txData.securityProviderResponse).length === 0);
|
||||
|
||||
const onSign = useCallback(
|
||||
async (event) => {
|
||||
try {
|
||||
await signPersonalMessage(event);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
},
|
||||
[signPersonalMessage],
|
||||
);
|
||||
const onSign = useCallback(async () => {
|
||||
try {
|
||||
await dispatch(resolvePendingApproval(id, null));
|
||||
dispatch(completedTx(id));
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}, [id, dispatch]);
|
||||
|
||||
const onCancel = useCallback(
|
||||
async (event) => {
|
||||
try {
|
||||
await cancelPersonalMessage(event);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
},
|
||||
[cancelPersonalMessage],
|
||||
);
|
||||
const onCancel = useCallback(async () => {
|
||||
try {
|
||||
await dispatch(
|
||||
rejectPendingApproval(
|
||||
id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
log.error(e);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleCancelAll = () => {
|
||||
const unapprovedTxCount = messagesCount;
|
||||
@ -112,7 +115,7 @@ export default function SignatureRequestSIWE({
|
||||
name: 'REJECT_TRANSACTIONS',
|
||||
unapprovedTxCount,
|
||||
onSubmit: async () => {
|
||||
await dispatch(cancelMsgs(valuesFor(messagesList)));
|
||||
await dispatch(rejectAllMessages(valuesFor(messagesList)));
|
||||
dispatch(clearConfirmTransaction());
|
||||
history.push(mostRecentOverviewPage);
|
||||
},
|
||||
@ -242,12 +245,4 @@ SignatureRequestSIWE.propTypes = {
|
||||
* The display content of transaction data
|
||||
*/
|
||||
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 { memoize } from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import LedgerInstructionField from '../ledger-instruction-field';
|
||||
import {
|
||||
sanitizeMessage,
|
||||
@ -62,14 +63,7 @@ export default class SignatureRequest extends PureComponent {
|
||||
* Check if the wallet is ledget wallet or not
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
@ -92,10 +86,14 @@ export default class SignatureRequest extends PureComponent {
|
||||
history: PropTypes.object,
|
||||
mostRecentOverviewPage: PropTypes.string,
|
||||
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)
|
||||
showCustodianDeepLink: PropTypes.func,
|
||||
isNotification: PropTypes.bool,
|
||||
mmiOnSignCallback: PropTypes.func,
|
||||
// Used to show a warning if the signing account is not the selected account
|
||||
// Largely relevant for contract wallet custodians
|
||||
selectedAccount: PropTypes.object,
|
||||
@ -150,18 +148,18 @@ export default class SignatureRequest extends PureComponent {
|
||||
|
||||
handleCancelAll = () => {
|
||||
const {
|
||||
cancelAll,
|
||||
clearConfirmTransaction,
|
||||
history,
|
||||
mostRecentOverviewPage,
|
||||
showRejectTransactionsConfirmationModal,
|
||||
unapprovedMessagesCount,
|
||||
cancelAllApprovals,
|
||||
} = this.props;
|
||||
|
||||
showRejectTransactionsConfirmationModal({
|
||||
unapprovedTxCount: unapprovedMessagesCount,
|
||||
onSubmit: async () => {
|
||||
await cancelAll();
|
||||
await cancelAllApprovals();
|
||||
clearConfirmTransaction();
|
||||
history.push(mostRecentOverviewPage);
|
||||
},
|
||||
@ -174,10 +172,9 @@ export default class SignatureRequest extends PureComponent {
|
||||
txData: {
|
||||
msgParams: { data, origin, version },
|
||||
type,
|
||||
id,
|
||||
},
|
||||
fromAccount: { address, balance, name },
|
||||
cancel,
|
||||
sign,
|
||||
isLedgerWallet,
|
||||
hardwareWalletRequiresConnection,
|
||||
chainId,
|
||||
@ -188,6 +185,9 @@ export default class SignatureRequest extends PureComponent {
|
||||
currentCurrency,
|
||||
conversionRate,
|
||||
unapprovedMessagesCount,
|
||||
resolvePendingApproval,
|
||||
rejectPendingApproval,
|
||||
completedTx,
|
||||
} = this.props;
|
||||
|
||||
const { t, trackEvent } = this.context;
|
||||
@ -221,8 +221,15 @@ export default class SignatureRequest extends PureComponent {
|
||||
.toBase(10)
|
||||
.toString();
|
||||
|
||||
const onSign = (event) => {
|
||||
sign(event);
|
||||
const onSign = async () => {
|
||||
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({
|
||||
category: MetaMetricsEventCategory.Transactions,
|
||||
event: 'Confirm',
|
||||
@ -235,8 +242,11 @@ export default class SignatureRequest extends PureComponent {
|
||||
});
|
||||
};
|
||||
|
||||
const onCancel = (event) => {
|
||||
cancel(event);
|
||||
const onCancel = async () => {
|
||||
await rejectPendingApproval(
|
||||
id,
|
||||
serializeError(ethErrors.provider.userRejectedRequest()),
|
||||
);
|
||||
trackEvent({
|
||||
category: MetaMetricsEventCategory.Transactions,
|
||||
event: 'Cancel',
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
getAccountType,
|
||||
getSelectedAccount,
|
||||
unapprovedTypedMessagesSelector,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../../selectors';
|
||||
import {
|
||||
@ -29,16 +30,20 @@ import {
|
||||
setTypedMessageInProgress,
|
||||
} from '../../../store/institutional/institution-background';
|
||||
import { getEnvironmentType } from '../../../../app/scripts/lib/util';
|
||||
import { checkForUnapprovedTypedMessages } from '../../../store/institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
MESSAGE_TYPE,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../../../../shared/constants/app';
|
||||
|
||||
import {
|
||||
cancelMsgs,
|
||||
showModal,
|
||||
resolvePendingApproval,
|
||||
rejectPendingApproval,
|
||||
rejectAllMessages,
|
||||
completedTx,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
goHome,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
@ -89,6 +94,7 @@ function mapStateToProps(state, ownProps) {
|
||||
accountType: getAccountType(state),
|
||||
isNotification: envType === ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
selectedAccount: getSelectedAccount(state),
|
||||
unapprovedTypedMessages: unapprovedTypedMessagesSelector(state),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
}
|
||||
@ -143,6 +149,10 @@ mapDispatchToProps = mmiMapDispatchToProps;
|
||||
|
||||
mapDispatchToProps = function (dispatch) {
|
||||
return {
|
||||
resolvePendingApproval: (id) => dispatch(resolvePendingApproval(id)),
|
||||
completedTx: (id) => dispatch(completedTx(id)),
|
||||
rejectPendingApproval: (id, error) =>
|
||||
dispatch(rejectPendingApproval(id, error)),
|
||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||
showRejectTransactionsConfirmationModal: ({
|
||||
onSubmit,
|
||||
@ -157,8 +167,9 @@ mapDispatchToProps = function (dispatch) {
|
||||
}),
|
||||
);
|
||||
},
|
||||
cancelAll: (unconfirmedMessagesList) =>
|
||||
dispatch(cancelMsgs(unconfirmedMessagesList)),
|
||||
cancelAllApprovals: (unconfirmedMessagesList) => {
|
||||
dispatch(rejectAllMessages(unconfirmedMessagesList));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -180,49 +191,33 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
accountType,
|
||||
isNotification,
|
||||
unapprovedTypedMessages,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} = stateProps;
|
||||
const {
|
||||
signPersonalMessage,
|
||||
signTypedMessage,
|
||||
cancelPersonalMessage,
|
||||
cancelTypedMessage,
|
||||
signMessage,
|
||||
cancelMessage,
|
||||
txData,
|
||||
} = ownProps;
|
||||
|
||||
const { cancelAll: dispatchCancelAll } = dispatchProps;
|
||||
const { txData } = ownProps;
|
||||
|
||||
const {
|
||||
cancelAll: dispatchCancelAll,
|
||||
cancelAllApprovals: dispatchCancelAllApprovals,
|
||||
} = dispatchProps;
|
||||
|
||||
const {
|
||||
type,
|
||||
msgParams: { from },
|
||||
} = txData;
|
||||
|
||||
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)
|
||||
const signFn = async (...opts) => {
|
||||
const mmiOnSignCallback = async (_msgData) => {
|
||||
if (accountType === 'custody') {
|
||||
try {
|
||||
let msgData = opts;
|
||||
let id = opts.custodyId;
|
||||
if (!opts.custodyId) {
|
||||
msgData = await sign(opts);
|
||||
let msgData = _msgData;
|
||||
let id = _msgData.custodyId;
|
||||
if (!_msgData.custodyId) {
|
||||
msgData = checkForUnapprovedTypedMessages(
|
||||
_msgData,
|
||||
unapprovedTypedMessages,
|
||||
);
|
||||
id = msgData.custodyId;
|
||||
}
|
||||
dispatchProps.showCustodianDeepLink({
|
||||
@ -235,7 +230,6 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
await dispatchProps.setMsgInProgress(msgData.metamaskId);
|
||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||
await goHome();
|
||||
return msgData;
|
||||
} catch (err) {
|
||||
await dispatchProps.setWaitForConfirmDeepLinkDialog(true);
|
||||
await dispatchProps.showTransactionsFailedModal({
|
||||
@ -243,11 +237,8 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
closeNotification: true,
|
||||
operationFailed: true,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return sign(opts);
|
||||
};
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
@ -256,14 +247,6 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
...dispatchProps,
|
||||
fromAccount,
|
||||
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,
|
||||
hardwareWalletRequiresConnection,
|
||||
chainId,
|
||||
@ -276,6 +259,11 @@ function mergeProps(stateProps, dispatchProps, ownProps) {
|
||||
unapprovedMessagesCount,
|
||||
mostRecentOverviewPage,
|
||||
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 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 { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import SignatureRequest from './signature-request.container';
|
||||
@ -90,6 +90,7 @@ describe('Signature Request', () => {
|
||||
clearConfirmTransaction: sinon.spy(),
|
||||
cancelMessage: sinon.spy(),
|
||||
cancel: sinon.stub().resolves(),
|
||||
rejectPendingApproval: sinon.stub().resolves(),
|
||||
showRejectTransactionsConfirmationModal: sinon.stub().resolves(),
|
||||
cancelAll: sinon.stub().resolves(),
|
||||
providerConfig: {
|
||||
@ -97,6 +98,9 @@ describe('Signature Request', () => {
|
||||
},
|
||||
unapprovedMessagesCount: 2,
|
||||
sign: sinon.stub().resolves(),
|
||||
cancelAllApprovals: sinon.stub().resolves(),
|
||||
resolvePendingApproval: sinon.stub().resolves(),
|
||||
completedTx: sinon.stub().resolves(),
|
||||
txData: {
|
||||
msgParams: {
|
||||
id: 1,
|
||||
@ -162,22 +166,24 @@ describe('Signature Request', () => {
|
||||
propsWithFiat.clearConfirmTransaction.resetHistory();
|
||||
});
|
||||
|
||||
it('cancel', () => {
|
||||
it('cancel', async () => {
|
||||
const cancelButton = screen.getByTestId('page-container-footer-cancel');
|
||||
fireEvent.click(cancelButton);
|
||||
expect(propsWithFiat.cancel.calledOnce).toStrictEqual(true);
|
||||
await act(() => {
|
||||
fireEvent.click(cancelButton);
|
||||
});
|
||||
expect(propsWithFiat.rejectPendingApproval.calledOnce).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('sign', () => {
|
||||
it('sign', async () => {
|
||||
const signButton = screen.getByTestId('page-container-footer-next');
|
||||
fireEvent.click(signButton);
|
||||
expect(propsWithFiat.sign.calledOnce).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('cancelAll', () => {
|
||||
const cancelAll = screen.getByTestId('signature-request-reject-all');
|
||||
fireEvent.click(cancelAll);
|
||||
expect(propsWithFiat.cancelAll.calledOnce).toStrictEqual(false);
|
||||
await act(() => {
|
||||
fireEvent.click(signButton);
|
||||
});
|
||||
expect(propsWithFiat.resolvePendingApproval.calledOnce).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('have user warning', () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { useHistory, withRouter } from 'react-router-dom';
|
||||
import log from 'loglevel';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import * as actions from '../../store/actions';
|
||||
@ -22,12 +22,6 @@ import { TransactionStatus } from '../../../shared/constants/transaction';
|
||||
import { getSendTo } from '../../ducks/send';
|
||||
import { getProviderConfig } from '../../ducks/metamask/metamask';
|
||||
|
||||
const SIGN_MESSAGE_TYPE = {
|
||||
MESSAGE: 'message',
|
||||
PERSONAL: 'personal',
|
||||
TYPED: 'typed',
|
||||
};
|
||||
|
||||
const signatureSelect = (txData) => {
|
||||
const {
|
||||
type,
|
||||
@ -49,12 +43,6 @@ const signatureSelect = (txData) => {
|
||||
return SignatureRequestOriginal;
|
||||
};
|
||||
|
||||
const stopPropagation = (event) => {
|
||||
if (event?.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
const ConfirmTxScreen = ({ match }) => {
|
||||
const dispatch = useDispatch();
|
||||
const { navigateToMostRecentOverviewPage } = useRouting();
|
||||
@ -81,6 +69,7 @@ const ConfirmTxScreen = ({ match }) => {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
const [prevValue, setPrevValues] = useState();
|
||||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
const unconfTxList = txHelper(
|
||||
@ -182,49 +171,16 @@ const ConfirmTxScreen = ({ match }) => {
|
||||
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);
|
||||
|
||||
return (
|
||||
<SigComponent
|
||||
history={history}
|
||||
txData={txData}
|
||||
key={txData.id}
|
||||
identities={identities}
|
||||
currentCurrency={currentCurrency}
|
||||
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)
|
||||
selectedAccount={selectedAccount}
|
||||
///: 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', () => {
|
||||
const txParams = {
|
||||
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('#setDesktopEnabled', () => {
|
||||
it('calls background setDesktopEnabled method', async () => {
|
||||
|
@ -4,6 +4,7 @@ import { captureException } from '@sentry/browser';
|
||||
import { capitalize, isEqual } from 'lodash';
|
||||
import { ThunkAction } from 'redux-thunk';
|
||||
import { Action, AnyAction } from 'redux';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import { Hex, Json } from '@metamask/utils';
|
||||
import {
|
||||
AssetsContractController,
|
||||
@ -15,14 +16,12 @@ import { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { GasFeeController } from '@metamask/gas-fee-controller';
|
||||
import { PermissionsRequest } from '@metamask/permission-controller';
|
||||
import { NonEmptyArray } from '@metamask/controller-utils';
|
||||
import { ethErrors } from 'eth-rpc-errors';
|
||||
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
||||
import switchDirection from '../../shared/lib/switch-direction';
|
||||
import {
|
||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
ORIGIN_METAMASK,
|
||||
POLLING_TOKEN_ENVIRONMENT_TYPES,
|
||||
MESSAGE_TYPE,
|
||||
} from '../../shared/constants/app';
|
||||
import { getEnvironmentType, addHexPrefix } from '../../app/scripts/lib/util';
|
||||
import {
|
||||
@ -91,10 +90,7 @@ import { CustomGasSettings } from '../../app/scripts/controllers/transactions';
|
||||
import { ThemeType } from '../../shared/constants/preferences';
|
||||
import * as actionConstants from './actionConstants';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import {
|
||||
checkForUnapprovedTypedMessages,
|
||||
updateCustodyState,
|
||||
} from './institutional/institution-actions';
|
||||
import { updateCustodyState } from './institutional/institution-actions';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
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(
|
||||
decryptedMsgData: TemporaryMessageDataType['msgParams'],
|
||||
): 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) {
|
||||
return {
|
||||
type: actionConstants.UPDATE_CUSTOM_NONCE,
|
||||
@ -1330,156 +1218,6 @@ export async function disableDesktop() {
|
||||
}
|
||||
///: 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(
|
||||
msgData: TemporaryMessageDataType,
|
||||
): 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(
|
||||
txMeta: TransactionMeta,
|
||||
_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(
|
||||
type: 'create' | 'import',
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
|
@ -166,11 +166,9 @@ describe('#checkForUnapprovedTypedMessages', () => {
|
||||
status: 'unapproved',
|
||||
};
|
||||
|
||||
expect(
|
||||
checkForUnapprovedTypedMessages(messageData, {
|
||||
unapprovedTypedMessages: { msg: 'msg' },
|
||||
}),
|
||||
).toBe(messageData);
|
||||
expect(checkForUnapprovedTypedMessages(messageData, { msg: 'msg' })).toBe(
|
||||
messageData,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
CombinedBackgroundAndReduxState,
|
||||
MetaMaskReduxState,
|
||||
TemporaryMessageDataType,
|
||||
MessagesIndexedById,
|
||||
} from '../store';
|
||||
import { toChecksumHexAddress } from '../../../shared/modules/hexstring-utils';
|
||||
|
||||
@ -110,19 +111,16 @@ export function updateCustodyState(
|
||||
|
||||
export function checkForUnapprovedTypedMessages(
|
||||
msgData: TemporaryMessageDataType['msgParams'],
|
||||
newState: MetaMaskReduxState['metamask'],
|
||||
unapprovedTypedMessages: MessagesIndexedById,
|
||||
) {
|
||||
const custodianUnapprovedMessages = Object.keys(
|
||||
newState.unapprovedTypedMessages,
|
||||
)
|
||||
.map((key) => newState.unapprovedTypedMessages[key])
|
||||
const custodianUnapprovedMessages = Object.keys(unapprovedTypedMessages)
|
||||
.map((key) => unapprovedTypedMessages[key])
|
||||
.filter((message) => message.custodyId && message.status === 'unapproved');
|
||||
|
||||
if (custodianUnapprovedMessages && custodianUnapprovedMessages.length > 0) {
|
||||
return {
|
||||
...msgData,
|
||||
custodyId:
|
||||
newState.unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
||||
custodyId: unapprovedTypedMessages[msgData.metamaskId]?.custodyId,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ export interface TemporaryMessageDataType {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
|
||||
interface MessagesIndexedById {
|
||||
export interface MessagesIndexedById {
|
||||
[id: string]: TemporaryMessageDataType;
|
||||
}
|
||||
|
||||
|
52
yarn.lock
52
yarn.lock
@ -4030,9 +4030,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/controller-utils@npm:^4.0.0, @metamask/controller-utils@npm:^4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "@metamask/controller-utils@npm:4.0.1"
|
||||
"@metamask/controller-utils@npm:^4.0.0, @metamask/controller-utils@npm:^4.0.1, @metamask/controller-utils@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "@metamask/controller-utils@npm:4.1.0"
|
||||
dependencies:
|
||||
"@metamask/utils": ^5.0.2
|
||||
"@spruceid/siwe-parser": 1.1.3
|
||||
@ -4043,7 +4043,7 @@ __metadata:
|
||||
ethereumjs-util: ^7.0.10
|
||||
ethjs-unit: ^0.1.6
|
||||
fast-deep-equal: ^3.1.3
|
||||
checksum: c0c3b8b5a363aff6a7996e349f47fdc77d3b31846546dc937669a2ab2306c3ed3c2122cf682a1146c6ba3eeeabe491f8ba7aa0157d62843689242779bb506017
|
||||
checksum: b4975e6ca860b691931254aa749e8c4faddd04279609cf197155b38150e55da0e966bf9b2d61ee1cd070f79d16e0305d5a0ff1747e0b4ab2e1c3ab46ca84e4d7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -4333,19 +4333,19 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/message-manager@npm:^6.0.0":
|
||||
version: 6.0.0
|
||||
resolution: "@metamask/message-manager@npm:6.0.0"
|
||||
"@metamask/message-manager@npm:^7.0.0, @metamask/message-manager@npm:^7.0.2":
|
||||
version: 7.0.2
|
||||
resolution: "@metamask/message-manager@npm:7.0.2"
|
||||
dependencies:
|
||||
"@metamask/base-controller": ^3.0.0
|
||||
"@metamask/controller-utils": ^4.0.0
|
||||
"@metamask/controller-utils": ^4.1.0
|
||||
"@metamask/utils": ^5.0.2
|
||||
"@types/uuid": ^8.3.0
|
||||
eth-sig-util: ^3.0.0
|
||||
ethereumjs-util: ^7.0.10
|
||||
jsonschema: ^1.2.4
|
||||
uuid: ^8.3.2
|
||||
checksum: f1601145317739e06cb83aefb99cb12ecd717a164103e6094a753197dbf1b62e8eaa1e4aff8dd849d67d21358933cba7a6e1551eede0fcc32b7657496c4a2f2e
|
||||
checksum: ee2f11a44fd7fae662aa72a0bfc02cb51327d1a42812c73aca291284a0dd2575836fd9e2a390e788da5e6515334e51863d839719762ceff65a56e60be14c046b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -4683,39 +4683,41 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/signature-controller@npm:3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "@metamask/signature-controller@npm:3.0.0"
|
||||
"@metamask/signature-controller@npm:4.0.1":
|
||||
version: 4.0.1
|
||||
resolution: "@metamask/signature-controller@npm:4.0.1"
|
||||
dependencies:
|
||||
"@metamask/approval-controller": ^3.0.0
|
||||
"@metamask/approval-controller": ^3.3.0
|
||||
"@metamask/base-controller": ^3.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
|
||||
eth-rpc-errors: ^4.0.2
|
||||
ethereumjs-util: ^7.0.10
|
||||
immer: ^9.0.6
|
||||
lodash: ^4.17.21
|
||||
peerDependencies:
|
||||
"@metamask/approval-controller": ^3.0.0
|
||||
checksum: 9afc2b8bc09d7cc6bab9d3e0bed1e70fd852cb78b0b07321afadac395cc0d7775697f99e1a846edd68afe8279929e3f763f09aa9b91eac682f0caed3e1c4fd5f
|
||||
"@metamask/approval-controller": ^3.3.0
|
||||
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."
|
||||
"@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A4.0.1#./.yarn/patches/@metamask-signature-controller-npm-4.0.1-013e64c9fd.patch::locator=metamask-crx%40workspace%3A.":
|
||||
version: 4.0.1
|
||||
resolution: "@metamask/signature-controller@patch:@metamask/signature-controller@npm%3A4.0.1#./.yarn/patches/@metamask-signature-controller-npm-4.0.1-013e64c9fd.patch::version=4.0.1&hash=7f339b&locator=metamask-crx%40workspace%3A."
|
||||
dependencies:
|
||||
"@metamask/approval-controller": ^3.0.0
|
||||
"@metamask/approval-controller": ^3.3.0
|
||||
"@metamask/base-controller": ^3.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
|
||||
eth-rpc-errors: ^4.0.2
|
||||
ethereumjs-util: ^7.0.10
|
||||
immer: ^9.0.6
|
||||
lodash: ^4.17.21
|
||||
peerDependencies:
|
||||
"@metamask/approval-controller": ^3.0.0
|
||||
checksum: 379cceaceaa4e120bbf9547b74d709f2a93117a17ec460e22e8935a54a1d10528f435563f6d9dcb1c4b9f521286033b23d5ec14063ea1c6f753953f5e0984a70
|
||||
"@metamask/approval-controller": ^3.3.0
|
||||
checksum: d678cf1763cfe9e13c0e5d357fcc44bd4580efc44a6fdca61ba6eed059c47c780fafaf08a075466a4886fbb9c6332544752bf7d25d515a37213c800cfc181665
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -24363,7 +24365,7 @@ __metadata:
|
||||
"@metamask/jazzicon": ^2.0.0
|
||||
"@metamask/key-tree": ^7.0.0
|
||||
"@metamask/logo": ^3.1.1
|
||||
"@metamask/message-manager": ^6.0.0
|
||||
"@metamask/message-manager": ^7.0.2
|
||||
"@metamask/metamask-eth-abis": ^3.0.0
|
||||
"@metamask/notification-controller": ^3.0.0
|
||||
"@metamask/obs-store": ^8.1.0
|
||||
@ -24377,7 +24379,7 @@ __metadata:
|
||||
"@metamask/rpc-methods-flask": "npm:@metamask/rpc-methods@0.34.0-flask.1"
|
||||
"@metamask/safe-event-emitter": ^2.0.0
|
||||
"@metamask/scure-bip39": ^2.0.3
|
||||
"@metamask/signature-controller": ^3.0.0
|
||||
"@metamask/signature-controller": ^4.0.1
|
||||
"@metamask/slip44": ^3.0.0
|
||||
"@metamask/smart-transactions-controller": ^3.1.0
|
||||
"@metamask/snaps-controllers": ^0.32.2
|
||||
|
Loading…
Reference in New Issue
Block a user