From 4b9a4d330c5789edc02562391d024f428ec962d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3nio=20Regadas?= Date: Tue, 25 Jul 2023 09:31:52 +0100 Subject: [PATCH] [MMI] Allows the mmi build to be generated using the dist command (#20148) * adds listeners for signatureControll and adds the handleSigningEvents method * clean up * updates signature request containers files * adds necessary methods * wip * signing flow with core methods * yarn lint * updates logic to fit latest signatureCOntroller * updates mmi extension package * updates signature-controller and message-manager packages * checkout develop lock file and run yarn * checkout develop lock file and package.json to test circleci * test fix * adds signature-controller new version * updates mmi extension package * tx-list update and runs lavamoat auto * lint fix * runs lavamoat auto * resets lavamoat/build-system/policy.jsono to develop * Update LavaMoat policies * adds back the dispatch * lint * changes needed to generate a mmi build * adds metametricsId in url param * adds necessary fence --------- Co-authored-by: MetaMask Bot --- development/build/manifest.js | 2 +- ...onfirm-page-container-content.component.js | 6 ++ .../confirm-page-container.component.js | 14 ++++- .../signature-request-original.component.js | 14 ++--- .../signature-request/signature-request.js | 4 +- .../transaction-list.component.js | 4 +- .../app/wallet-overview/eth-overview.js | 27 ++++++--- .../multichain/global-menu/global-menu.js | 7 ++- ui/pages/home/home.component.js | 57 +++++++++++-------- ui/store/actions.ts | 6 +- 10 files changed, 91 insertions(+), 50 deletions(-) diff --git a/development/build/manifest.js b/development/build/manifest.js index b3079f806..d9f0f71ca 100644 --- a/development/build/manifest.js +++ b/development/build/manifest.js @@ -137,7 +137,7 @@ function createManifestTasks({ const buildName = buildType === 'mmi' - ? `MetaMask Institutional ${mv3Str}${lavamoatStr}${snowStr}` + ? `MetaMask Institutional ${mv3Str}` : `MetaMask ${capitalize(buildType)}${mv3Str}${lavamoatStr}${snowStr}`; manifest.name = buildName; diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js index c4d907462..b100cdb6b 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js @@ -2,7 +2,9 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { Tabs, Tab } from '../../../ui/tabs'; +///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) import Button from '../../../ui/button'; +///: END:ONLY_INCLUDE_IN import ActionableMessage from '../../../ui/actionable-message/actionable-message'; import { PageContainerFooter } from '../../../ui/page-container'; import ErrorMessage from '../../../ui/error-message'; @@ -57,7 +59,9 @@ export default class ConfirmPageContainerContent extends Component { toAddress: PropTypes.string, transactionType: PropTypes.string, isBuyableChain: PropTypes.bool, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) openBuyCryptoInPdapp: PropTypes.func, + ///: END:ONLY_INCLUDE_IN txData: PropTypes.object, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) noteComponent: PropTypes.node, @@ -197,7 +201,9 @@ export default class ConfirmPageContainerContent extends Component { toAddress, transactionType, isBuyableChain, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) openBuyCryptoInPdapp, + ///: END:ONLY_INCLUDE_IN txData, } = this.props; diff --git a/ui/components/app/confirm-page-container/confirm-page-container.component.js b/ui/components/app/confirm-page-container/confirm-page-container.component.js index cd489fea8..e40dc23a2 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container.component.js @@ -1,4 +1,11 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import React, { + useCallback, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) + useContext, + ///: END:ONLY_INCLUDE_IN + useEffect, + useState, +} from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; @@ -45,11 +52,13 @@ import { getSwapsDefaultToken, } from '../../../selectors'; import useRamps from '../../../hooks/experiences/useRamps'; +///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) import { MetaMetricsContext } from '../../../contexts/metametrics'; import { MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; +///: END:ONLY_INCLUDE_IN import { ConfirmPageContainerHeader, ConfirmPageContainerContent, @@ -105,8 +114,9 @@ const ConfirmPageContainer = (props) => { } = props; const t = useI18nContext(); + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) const trackEvent = useContext(MetaMetricsContext); - + ///: END:ONLY_INCLUDE_IN const [collectionBalance, setCollectionBalance] = useState('0'); const isBuyableChain = useSelector(getIsBuyableChain); diff --git a/ui/components/app/signature-request-original/signature-request-original.component.js b/ui/components/app/signature-request-original/signature-request-original.component.js index 52d3d86fd..fbd13dba9 100644 --- a/ui/components/app/signature-request-original/signature-request-original.component.js +++ b/ui/components/app/signature-request-original/signature-request-original.component.js @@ -64,9 +64,6 @@ export default class SignatureRequestOriginal extends Component { address: PropTypes.string.isRequired, name: PropTypes.string, }).isRequired, - clearConfirmTransaction: PropTypes.func.isRequired, - history: PropTypes.object.isRequired, - mostRecentOverviewPage: PropTypes.string.isRequired, txData: PropTypes.object.isRequired, subjectMetadata: PropTypes.object, hardwareWalletRequiresConnection: PropTypes.bool, @@ -75,6 +72,9 @@ export default class SignatureRequestOriginal extends Component { showRejectTransactionsConfirmationModal: PropTypes.func.isRequired, cancelAllApprovals: PropTypes.func.isRequired, rejectPendingApproval: PropTypes.func.isRequired, + clearConfirmTransaction: PropTypes.func.isRequired, + history: PropTypes.object.isRequired, + mostRecentOverviewPage: PropTypes.string.isRequired, resolvePendingApproval: PropTypes.func.isRequired, completedTx: PropTypes.func.isRequired, ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) @@ -258,11 +258,11 @@ export default class SignatureRequestOriginal extends Component { onSubmit = async () => { const { + resolvePendingApproval, + completedTx, clearConfirmTransaction, history, mostRecentOverviewPage, - resolvePendingApproval, - completedTx, txData, } = this.props; ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) @@ -272,12 +272,10 @@ export default class SignatureRequestOriginal extends Component { } ///: END:ONLY_INCLUDE_IN - ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) await resolvePendingApproval(txData.id); completedTx(txData.id); clearConfirmTransaction(); history.push(mostRecentOverviewPage); - ///: END:ONLY_INCLUDE_IN }; onCancel = async () => { @@ -332,11 +330,9 @@ export default class SignatureRequestOriginal extends Component { } ///: END:ONLY_INCLUDE_IN - ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) await resolvePendingApproval(txData.id); clearConfirmTransaction(); history.push(mostRecentOverviewPage); - ///: END:ONLY_INCLUDE_IN } }} disabled={ diff --git a/ui/components/app/signature-request/signature-request.js b/ui/components/app/signature-request/signature-request.js index 0f00b5d9b..6838f4254 100644 --- a/ui/components/app/signature-request/signature-request.js +++ b/ui/components/app/signature-request/signature-request.js @@ -13,9 +13,11 @@ import { ethErrors, serializeError } from 'eth-rpc-errors'; import { showCustodianDeepLink } from '@metamask-institutional/extension'; ///: END:ONLY_INCLUDE_IN import { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) resolvePendingApproval, - rejectPendingApproval, completedTx, + ///: END:ONLY_INCLUDE_IN + rejectPendingApproval, } from '../../../store/actions'; import { doesAddressRequireLedgerHidConnection, diff --git a/ui/components/app/transaction-list/transaction-list.component.js b/ui/components/app/transaction-list/transaction-list.component.js index 825ace18c..93111fa6a 100644 --- a/ui/components/app/transaction-list/transaction-list.component.js +++ b/ui/components/app/transaction-list/transaction-list.component.js @@ -176,7 +176,6 @@ export default function TransactionList({ {pendingTransactions.map((dateGroup) => { return dateGroup.transactionGroups.map( (transactionGroup, index) => { - ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) if ( transactionGroup.initialTransaction.transactionType === TransactionType.smart @@ -193,7 +192,6 @@ export default function TransactionList({ ); } - ///: END:ONLY_INCLUDE_IN return ( <> {renderDateStamp(index, dateGroup)} @@ -218,7 +216,7 @@ export default function TransactionList({ <> {renderDateStamp(index, dateGroup)} {transactionGroup.initialTransaction?.transactionType === - 'smart' ? ( + TransactionType.smart ? ( { @@ -54,18 +63,20 @@ const EthOverview = ({ className, showAddress }) => { const t = useContext(I18nContext); const trackEvent = useContext(MetaMetricsContext); const history = useHistory(); + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) const location = useLocation(); + const isBridgeChain = useSelector(getIsBridgeChain); + const isBuyableChain = useSelector(getIsBuyableChain); + const metaMetricsId = useSelector(getMetaMetricsId); + ///: END:ONLY_INCLUDE_IN const keyring = useSelector(getCurrentKeyring); const usingHardwareWallet = isHardwareKeyring(keyring?.type); const balanceIsCached = useSelector(isBalanceCached); const showFiat = useSelector(getShouldShowFiat); const balance = useSelector(getSelectedAccountCachedBalance); const isSwapsChain = useSelector(getIsSwapsChain); - const isBridgeChain = useSelector(getIsBridgeChain); - const isBuyableChain = useSelector(getIsBuyableChain); const defaultSwapsToken = useSelector(getSwapsDefaultToken); const chainId = useSelector(getCurrentChainId); - const metaMetricsId = useSelector(getMetaMetricsId); ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) const mmiPortfolioEnabled = useSelector(getMmiPortfolioEnabled); @@ -95,7 +106,7 @@ const EthOverview = ({ className, showAddress }) => { onClick={() => { stakingEvent(); global.platform.openTab({ - url: 'https://metamask-institutional.io/staking', + url: 'https://metamask-institutional.io/stake', }); }} /> @@ -117,7 +128,9 @@ const EthOverview = ({ className, showAddress }) => { }; ///: END:ONLY_INCLUDE_IN + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) const { openBuyCryptoInPdapp } = useRamps(); + ///: END:ONLY_INCLUDE_IN return ( { category: MetaMetricsEventCategory.Navigation, event: MetaMetricsEventName.MMIPortfolioButtonClicked, }); - window.open(mmiPortfolioUrl, '_blank'); + window.open( + `${mmiPortfolioUrl}?metametricsId=${metaMetricsId}`, + '_blank', + ); closeMenu(); }} data-testid="global-menu-mmi-portfolio" diff --git a/ui/pages/home/home.component.js b/ui/pages/home/home.component.js index 5f4eb0c29..48f61e614 100644 --- a/ui/pages/home/home.component.js +++ b/ui/pages/home/home.component.js @@ -1,17 +1,19 @@ import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import { Redirect, Route } from 'react-router-dom'; -///: BEGIN:ONLY_INCLUDE_IN(build-main) -// eslint-disable-next-line import/no-duplicates -import { MetaMetricsContextProp } from '../../../shared/constants/metametrics'; -///: END:ONLY_INCLUDE_IN import { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-mmi) + MetaMetricsContextProp, + ///: END:ONLY_INCLUDE_IN MetaMetricsEventCategory, MetaMetricsEventName, - // eslint-disable-next-line import/no-duplicates } from '../../../shared/constants/metametrics'; import AssetList from '../../components/app/asset-list'; +///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) import NftsTab from '../../components/app/nfts-tab'; +import TermsOfUsePopup from '../../components/app/terms-of-use-popup'; +import RecoveryPhraseReminder from '../../components/app/recovery-phrase-reminder'; +///: END:ONLY_INCLUDE_IN import HomeNotification from '../../components/app/home-notification'; import MultipleNotifications from '../../components/app/multiple-notifications'; import TransactionList from '../../components/app/transaction-list'; @@ -22,8 +24,7 @@ import ConnectedAccounts from '../connected-accounts'; import { Tabs, Tab } from '../../components/ui/tabs'; import { EthOverview } from '../../components/app/wallet-overview'; import WhatsNewPopup from '../../components/app/whats-new-popup'; -import TermsOfUsePopup from '../../components/app/terms-of-use-popup'; -import RecoveryPhraseReminder from '../../components/app/recovery-phrase-reminder'; + import ActionableMessage from '../../components/ui/actionable-message/actionable-message'; import { FONT_WEIGHT, @@ -62,7 +63,9 @@ import { BUILD_QUOTE_ROUTE, VIEW_QUOTE_ROUTE, CONFIRMATION_V_NEXT_ROUTE, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) ONBOARDING_SECURE_YOUR_WALLET_ROUTE, + ///: END:ONLY_INCLUDE_IN ///: BEGIN:ONLY_INCLUDE_IN(build-mmi) CONFIRM_ADD_CUSTODIAN_TOKEN, INTERACTIVE_REPLACEMENT_TOKEN_PAGE, @@ -118,15 +121,29 @@ export default class Home extends PureComponent { hasTransactionPendingApprovals: PropTypes.bool.isRequired, hasWatchTokenPendingApprovals: PropTypes.bool, hasWatchNftPendingApprovals: PropTypes.bool, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) shouldShowSeedPhraseReminder: PropTypes.bool.isRequired, isPopup: PropTypes.bool, + connectedStatusPopoverHasBeenShown: PropTypes.bool, + showRecoveryPhraseReminder: PropTypes.bool.isRequired, + showTermsOfUsePopup: PropTypes.bool.isRequired, + seedPhraseBackedUp: (props) => { + if ( + props.seedPhraseBackedUp !== null && + typeof props.seedPhraseBackedUp !== 'boolean' + ) { + throw new Error( + `seedPhraseBackedUp is required to be null or boolean. Received ${props.seedPhraseBackedUp}`, + ); + } + }, + ///: END:ONLY_INCLUDE_IN isNotification: PropTypes.bool.isRequired, firstPermissionsRequestId: PropTypes.string, // This prop is used in the `shouldCloseNotificationPopup` function // eslint-disable-next-line react/no-unused-prop-types totalUnapprovedCount: PropTypes.number.isRequired, setConnectedStatusPopoverHasBeenShown: PropTypes.func, - connectedStatusPopoverHasBeenShown: PropTypes.bool, defaultHomeActiveTabName: PropTypes.string, firstTimeFlowType: PropTypes.string, completedOnboarding: PropTypes.bool, @@ -143,29 +160,17 @@ export default class Home extends PureComponent { infuraBlocked: PropTypes.bool.isRequired, showWhatsNewPopup: PropTypes.bool.isRequired, hideWhatsNewPopup: PropTypes.func.isRequired, - showTermsOfUsePopup: PropTypes.bool.isRequired, announcementsToShow: PropTypes.bool.isRequired, ///: BEGIN:ONLY_INCLUDE_IN(snaps) errorsToShow: PropTypes.object.isRequired, shouldShowErrors: PropTypes.bool.isRequired, removeSnapError: PropTypes.func.isRequired, ///: END:ONLY_INCLUDE_IN - showRecoveryPhraseReminder: PropTypes.bool.isRequired, setRecoveryPhraseReminderHasBeenShown: PropTypes.func.isRequired, setRecoveryPhraseReminderLastShown: PropTypes.func.isRequired, setTermsOfUseLastAgreed: PropTypes.func.isRequired, showOutdatedBrowserWarning: PropTypes.bool.isRequired, setOutdatedBrowserWarningLastShown: PropTypes.func.isRequired, - seedPhraseBackedUp: (props) => { - if ( - props.seedPhraseBackedUp !== null && - typeof props.seedPhraseBackedUp !== 'boolean' - ) { - throw new Error( - `seedPhraseBackedUp is required to be null or boolean. Received ${props.seedPhraseBackedUp}`, - ); - } - }, newNetworkAddedName: PropTypes.string, // This prop is used in the `shouldCloseNotificationPopup` function // eslint-disable-next-line react/no-unused-prop-types @@ -372,9 +377,11 @@ export default class Home extends PureComponent { const { t } = this.context; const { + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) history, shouldShowSeedPhraseReminder, isPopup, + ///: END:ONLY_INCLUDE_IN shouldShowWeb3ShimUsageNotification, setWeb3ShimUsageAlertDismissed, originOfCurrentTab, @@ -719,14 +726,16 @@ export default class Home extends PureComponent { onTabClick, forgottenPassword, history, + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) connectedStatusPopoverHasBeenShown, isPopup, + seedPhraseBackedUp, + showRecoveryPhraseReminder, + showTermsOfUsePopup, + ///: END:ONLY_INCLUDE_IN announcementsToShow, showWhatsNewPopup, hideWhatsNewPopup, - showTermsOfUsePopup, - seedPhraseBackedUp, - showRecoveryPhraseReminder, firstTimeFlowType, completedOnboarding, onboardedInThisUISession, @@ -751,8 +760,10 @@ export default class Home extends PureComponent { !process.env.IN_TEST && !newNetworkAddedConfigurationId; + ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) const showTermsOfUse = completedOnboarding && !onboardedInThisUISession && showTermsOfUsePopup; + ///: END:ONLY_INCLUDE_IN ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-mmi) // The style in activity screen for support is different diff --git a/ui/store/actions.ts b/ui/store/actions.ts index 12fdaf22a..d9a145806 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -3507,15 +3507,15 @@ export function resolvePendingApproval( id: string, value: unknown, ): ThunkAction { - return async (dispatch: MetaMaskReduxDispatch) => { + return async (_dispatch: MetaMaskReduxDispatch) => { await submitRequestToBackground('resolvePendingApproval', [id, value]); // Before closing the current window, check if any additional confirmations // are added as a result of this confirmation being accepted ///: BEGIN:ONLY_INCLUDE_IN(build-main,build-beta,build-flask) - const { pendingApprovals } = await forceUpdateMetamaskState(dispatch); + const { pendingApprovals } = await forceUpdateMetamaskState(_dispatch); if (Object.values(pendingApprovals).length === 0) { - dispatch(closeCurrentNotificationWindow()); + _dispatch(closeCurrentNotificationWindow()); } ///: END:ONLY_INCLUDE_IN };