From c81912f6c5561f70ef37acde0af8e0d723e531ec Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Mon, 14 Mar 2022 18:40:21 +0100 Subject: [PATCH 001/192] Show snap version on install (#13931) * Add version to Snap install page * Fix text sizing inconsistency * Use a localized string for shorthand versions --- app/_locales/en/messages.json | 4 +++ .../snap-settings-card/snap-settings-card.js | 2 +- .../permissions-connect-header.component.js | 33 +++++++++++++++++++ .../flask/snap-install/index.scss | 4 +++ .../flask/snap-install/snap-install.js | 17 ++++++---- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 4f7b20b11..b0d6dd9b8 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2769,6 +2769,10 @@ "settingsSearchMatchingNotFound": { "message": "No matching results found" }, + "shorthandVersion": { + "message": "v$1", + "description": "$1 is replaced by a version string (e.g. 1.2.3)" + }, "show": { "message": "Show" }, diff --git a/ui/components/app/flask/snap-settings-card/snap-settings-card.js b/ui/components/app/flask/snap-settings-card/snap-settings-card.js index 1cfde078b..210e38c9b 100644 --- a/ui/components/app/flask/snap-settings-card/snap-settings-card.js +++ b/ui/components/app/flask/snap-settings-card/snap-settings-card.js @@ -180,7 +180,7 @@ const SnapSettingsCard = ({ tag="span" className="snap-settings-card__version" > - v {version} + {t('shorthandVersion', [version])} )} diff --git a/ui/components/app/permissions-connect-header/permissions-connect-header.component.js b/ui/components/app/permissions-connect-header/permissions-connect-header.component.js index 33dc5f3b8..c5ddf0110 100644 --- a/ui/components/app/permissions-connect-header/permissions-connect-header.component.js +++ b/ui/components/app/permissions-connect-header/permissions-connect-header.component.js @@ -5,12 +5,24 @@ import Box from '../../ui/box'; import { FLEX_DIRECTION, JUSTIFY_CONTENT, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + COLORS, + TYPOGRAPHY, + TEXT_ALIGN, + ///: END:ONLY_INCLUDE_IN } from '../../../helpers/constants/design-system'; ///: BEGIN:ONLY_INCLUDE_IN(flask) import SnapsAuthorshipPill from '../flask/snaps-authorship-pill'; +import Typography from '../../ui/typography'; ///: END:ONLY_INCLUDE_IN export default class PermissionsConnectHeader extends Component { + ///: BEGIN:ONLY_INCLUDE_IN(flask) + static contextTypes = { + t: PropTypes.func, + }; + ///: END:ONLY_INCLUDE_IN + static propTypes = { iconUrl: PropTypes.string, iconName: PropTypes.string.isRequired, @@ -20,6 +32,7 @@ export default class PermissionsConnectHeader extends Component { headerText: PropTypes.string, ///: BEGIN:ONLY_INCLUDE_IN(flask) npmPackageName: PropTypes.string, + snapVersion: PropTypes.string, ///: END:ONLY_INCLUDE_IN }; @@ -47,10 +60,12 @@ export default class PermissionsConnectHeader extends Component { headerText, ///: BEGIN:ONLY_INCLUDE_IN(flask) npmPackageName, + snapVersion, ///: END:ONLY_INCLUDE_IN } = this.props; ///: BEGIN:ONLY_INCLUDE_IN(flask) const npmPackageUrl = `https://www.npmjs.com/package/${npmPackageName}`; + const { t } = this.context; ///: END:ONLY_INCLUDE_IN return ( + {t('shorthandVersion', [snapVersion])} + + ) + ///: END:ONLY_INCLUDE_IN + }
{headerText}
); diff --git a/ui/pages/permissions-connect/flask/snap-install/index.scss b/ui/pages/permissions-connect/flask/snap-install/index.scss index 6466f5a86..711e900fc 100644 --- a/ui/pages/permissions-connect/flask/snap-install/index.scss +++ b/ui/pages/permissions-connect/flask/snap-install/index.scss @@ -22,6 +22,10 @@ } } + .version { + font-family: monospace; + } + .page-container__footer { width: 100%; margin-top: 12px; diff --git a/ui/pages/permissions-connect/flask/snap-install/snap-install.js b/ui/pages/permissions-connect/flask/snap-install/snap-install.js index 950f8d317..497ca45af 100644 --- a/ui/pages/permissions-connect/flask/snap-install/snap-install.js +++ b/ui/pages/permissions-connect/flask/snap-install/snap-install.js @@ -75,16 +75,18 @@ export default function SnapInstall({ headerText={null} // TODO(ritave): Add header text when snaps support description siteOrigin={targetSubjectMetadata.origin} npmPackageName={npmId} + snapVersion={targetSubjectMetadata.version} boxProps={{ alignItems: ALIGN_ITEMS.CENTER }} /> - - - {t('snapRequestsPermission')} - + {t('snapRequestsPermission')} + @@ -149,5 +151,6 @@ SnapInstall.propTypes = { name: PropTypes.string, origin: PropTypes.string.isRequired, sourceCode: PropTypes.string, + version: PropTypes.string, }).isRequired, }; From 060c6d651c2b51fde8f46077178fc23efb3cb775 Mon Sep 17 00:00:00 2001 From: VSaric <92527393+VSaric@users.noreply.github.com> Date: Mon, 14 Mar 2022 19:12:38 +0100 Subject: [PATCH 002/192] Remove usages of useMetricEvent hook (#13930) --- .../app/asset-list-item/asset-list-item.js | 23 ++++---- ui/components/app/asset-list/asset-list.js | 37 ++++++------ .../edit-gas-display.component.js | 21 ++++--- .../import-token-link.component.js | 21 +++---- .../app/menu-bar/account-options-menu.js | 59 +++++++++---------- ui/components/app/menu-bar/menu-bar.js | 21 +++---- .../transaction-list-item.component.js | 42 ++++++------- .../app/wallet-overview/eth-overview.js | 39 ++++++------ .../app/wallet-overview/token-overview.js | 23 ++++---- ui/hooks/useMetricEvent.js | 11 ---- .../creation-successful.js | 19 +++--- .../amount-max-button/amount-max-button.js | 21 +++---- ui/pages/send/send.js | 21 +++---- 13 files changed, 175 insertions(+), 183 deletions(-) diff --git a/ui/components/app/asset-list-item/asset-list-item.js b/ui/components/app/asset-list-item/asset-list-item.js index a571ee42b..2badb8bb4 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { useMemo, useContext } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { useDispatch } from 'react-redux'; @@ -9,11 +9,11 @@ import Tooltip from '../../ui/tooltip'; import InfoIcon from '../../ui/icon/info-icon.component'; import Button from '../../ui/button'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send'; import { SEND_ROUTE } from '../../../helpers/constants/routes'; import { SEVERITIES } from '../../../helpers/constants/design-system'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; const AssetListItem = ({ className, @@ -33,13 +33,7 @@ const AssetListItem = ({ const t = useI18nContext(); const dispatch = useDispatch(); const history = useHistory(); - const sendTokenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Home', - name: 'Clicked Send: Token', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const titleIcon = warning ? ( { e.stopPropagation(); - sendTokenEvent(); + trackEvent({ + event: 'Clicked Send: Token', + category: 'Navigation', + properties: { + action: 'Home', + legacy_event: true, + }, + }); try { await dispatch( updateSendAsset({ @@ -93,7 +94,7 @@ const AssetListItem = ({ ); }, [ tokenSymbol, - sendTokenEvent, + trackEvent, tokenAddress, tokenDecimals, history, diff --git a/ui/components/app/asset-list/asset-list.js b/ui/components/app/asset-list/asset-list.js index c0b1347d0..75be4008d 100644 --- a/ui/components/app/asset-list/asset-list.js +++ b/ui/components/app/asset-list/asset-list.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; @@ -7,7 +7,6 @@ import TokenList from '../token-list'; import { IMPORT_TOKEN_ROUTE } from '../../../helpers/constants/routes'; import AssetListItem from '../asset-list-item'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import { useUserPreferencedCurrency } from '../../../hooks/useUserPreferencedCurrency'; import { getCurrentAccountWithSendEtherInfo, @@ -26,6 +25,7 @@ import { JUSTIFY_CONTENT, } from '../../../helpers/constants/design-system'; import { useI18nContext } from '../../../hooks/useI18nContext'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; const AssetList = ({ onClickAsset }) => { const t = useI18nContext(); @@ -35,20 +35,7 @@ const AssetList = ({ onClickAsset }) => { ); const nativeCurrency = useSelector(getNativeCurrency); const showFiat = useSelector(getShouldShowFiat); - const selectTokenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Token Menu', - name: 'Clicked Token', - }, - }); - const addTokenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Token Menu', - name: 'Clicked "Add Token"', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const { currency: primaryCurrency, @@ -94,7 +81,14 @@ const AssetList = ({ onClickAsset }) => { { onClickAsset(tokenAddress); - selectTokenEvent(); + trackEvent({ + event: 'Clicked Token', + category: 'Navigation', + properties: { + action: 'Token Menu', + legacy_event: true, + }, + }); }} /> @@ -111,7 +105,14 @@ const AssetList = ({ onClickAsset }) => { isMainnet={isMainnet} onClick={() => { history.push(IMPORT_TOKEN_ROUTE); - addTokenEvent(); + trackEvent({ + event: 'Clicked "Add Token"', + category: 'Navigation', + properties: { + action: 'Token Menu', + legacy_event: true, + }, + }); }} /> diff --git a/ui/components/app/edit-gas-display/edit-gas-display.component.js b/ui/components/app/edit-gas-display/edit-gas-display.component.js index f7fc433c9..f6913b2d8 100644 --- a/ui/components/app/edit-gas-display/edit-gas-display.component.js +++ b/ui/components/app/edit-gas-display/edit-gas-display.component.js @@ -35,8 +35,7 @@ import ActionableMessage from '../../ui/actionable-message/actionable-message'; import { I18nContext } from '../../../contexts/i18n'; import GasTiming from '../gas-timing'; - -import { useMetricEvent } from '../../../hooks/useMetricEvent'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; export default function EditGasDisplay({ mode = EDIT_GAS_MODES.MODIFY_IN_PLACE, @@ -133,14 +132,7 @@ export default function EditGasDisplay({ errorKey = 'gasEstimatesUnavailableWarning'; } - const clickedAdvancedOptionsMetricsEvent = useMetricEvent({ - eventOpts: { - category: 'Transactions', - action: 'Edit Screen', - name: 'Clicked "Advanced Options"', - }, - }); - + const trackEvent = useContext(MetaMetricsContext); return (
@@ -286,7 +278,14 @@ export default function EditGasDisplay({ className="edit-gas-display__advanced-button" onClick={() => { setShowAdvancedForm(!showAdvancedForm); - clickedAdvancedOptionsMetricsEvent(); + trackEvent({ + event: 'Clicked "Advanced Options"', + category: 'Transactions', + properties: { + action: 'Edit Screen', + legacy_event: true, + }, + }); }} > {t('advancedOptions')}{' '} diff --git a/ui/components/app/import-token-link/import-token-link.component.js b/ui/components/app/import-token-link/import-token-link.component.js index 40e153000..4147a9256 100644 --- a/ui/components/app/import-token-link/import-token-link.component.js +++ b/ui/components/app/import-token-link/import-token-link.component.js @@ -1,22 +1,16 @@ -import React from 'react'; +import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { IMPORT_TOKEN_ROUTE } from '../../../helpers/constants/routes'; import Button from '../../ui/button'; import Box from '../../ui/box/box'; import { TEXT_ALIGN } from '../../../helpers/constants/design-system'; import { detectNewTokens } from '../../../store/actions'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; export default function ImportTokenLink({ isMainnet }) { - const addTokenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Token Menu', - name: 'Clicked "Add Token"', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const t = useI18nContext(); const history = useHistory(); @@ -39,7 +33,14 @@ export default function ImportTokenLink({ isMainnet }) { type="link" onClick={() => { history.push(IMPORT_TOKEN_ROUTE); - addTokenEvent(); + trackEvent({ + event: 'Clicked "Add Token"', + category: 'Navigation', + properties: { + action: 'Token Menu', + legacy_event: true, + }, + }); }} > {isMainnet diff --git a/ui/components/app/menu-bar/account-options-menu.js b/ui/components/app/menu-bar/account-options-menu.js index 5e83f8aec..394958427 100644 --- a/ui/components/app/menu-bar/account-options-menu.js +++ b/ui/components/app/menu-bar/account-options-menu.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import PropTypes from 'prop-types'; import { useHistory } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; @@ -15,12 +15,10 @@ import { getSelectedIdentity, } from '../../../selectors'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { - useMetricEvent, - useNewMetricEvent, -} from '../../../hooks/useMetricEvent'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_FULLSCREEN } from '../../../../shared/constants/app'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; export default function AccountOptionsMenu({ anchorElement, onClose }) { const t = useI18nContext(); @@ -35,29 +33,7 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { const addressLink = getAccountLink(address, chainId, rpcPrefs); const { blockExplorerUrl } = rpcPrefs; const blockExplorerUrlSubTitle = getURLHostName(blockExplorerUrl); - - const openFullscreenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Account Options', - name: 'Clicked Expand View', - }, - }); - const viewAccountDetailsEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Account Options', - name: 'Viewed Account Details', - }, - }); - - const openConnectedSitesEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Account Options', - name: 'Opened Connected Sites', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const blockExplorerLinkClickedEvent = useNewMetricEvent({ category: 'Navigation', @@ -101,7 +77,14 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { {getEnvironmentType() === ENVIRONMENT_TYPE_FULLSCREEN ? null : ( { - openFullscreenEvent(); + trackEvent({ + event: 'Clicked Expand View', + category: 'Navigation', + properties: { + action: 'Account Options', + legacy_event: true, + }, + }); global.platform.openExtensionInBrowser(); onClose(); }} @@ -114,7 +97,14 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { data-testid="account-options-menu__account-details" onClick={() => { dispatch(showModal({ name: 'ACCOUNT_DETAILS' })); - viewAccountDetailsEvent(); + trackEvent({ + event: 'Viewed Account Details', + category: 'Navigation', + properties: { + action: 'Account Options', + legacy_event: true, + }, + }); onClose(); }} iconClassName="fas fa-qrcode" @@ -124,7 +114,14 @@ export default function AccountOptionsMenu({ anchorElement, onClose }) { { - openConnectedSitesEvent(); + trackEvent({ + event: 'Opened Connected Sites', + category: 'Navigation', + properties: { + action: 'Account Options', + legacy_event: true, + }, + }); history.push(CONNECTED_ROUTE); onClose(); }} diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index b5e3fdb7c..bc3af6362 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useContext } from 'react'; import extension from 'extensionizer'; import { useHistory } from 'react-router-dom'; import { useSelector } from 'react-redux'; @@ -8,19 +8,13 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import { CONNECTED_ACCOUNTS_ROUTE } from '../../../helpers/constants/routes'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import { getOriginOfCurrentTab } from '../../../selectors'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; import AccountOptionsMenu from './account-options-menu'; export default function MenuBar() { const t = useI18nContext(); - const openAccountOptionsEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Home', - name: 'Opened Account Options', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const history = useHistory(); const [ accountOptionsButtonElement, @@ -50,7 +44,14 @@ export default function MenuBar() { ref={setAccountOptionsButtonElement} title={t('accountOptions')} onClick={() => { - openAccountOptionsEvent(); + trackEvent({ + event: 'Opened Account Options', + category: 'Navigation', + properties: { + action: 'Home', + legacy_event: true, + }, + }); setAccountOptionsMenuOpen(true); }} /> diff --git a/ui/components/app/transaction-list-item/transaction-list-item.component.js b/ui/components/app/transaction-list-item/transaction-list-item.component.js index e503c294c..f911dcff8 100644 --- a/ui/components/app/transaction-list-item/transaction-list-item.component.js +++ b/ui/components/app/transaction-list-item/transaction-list-item.component.js @@ -1,4 +1,4 @@ -import React, { useMemo, useState, useCallback } from 'react'; +import React, { useMemo, useState, useCallback, useContext } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { useHistory } from 'react-router-dom'; @@ -31,13 +31,13 @@ import { getEIP1559V2Enabled, } from '../../../selectors'; import { isLegacyTransaction } from '../../../helpers/utils/transactions.util'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import Button from '../../ui/button'; import AdvancedGasFeePopover from '../advanced-gas-fee-popover'; import CancelButton from '../cancel-button'; import CancelSpeedupPopover from '../cancel-speedup-popover'; import EditGasFeePopover from '../edit-gas-fee-popover'; import EditGasPopover from '../edit-gas-popover'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; function TransactionListItemInner({ transactionGroup, @@ -60,26 +60,19 @@ function TransactionListItemInner({ primaryTransaction: { err, status }, } = transactionGroup; - const speedUpMetricsEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Activity Log', - name: 'Clicked "Speed Up"', - }, - }); - - const cancelMetricsEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Activity Log', - name: 'Clicked "Cancel"', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const retryTransaction = useCallback( async (event) => { event.stopPropagation(); - speedUpMetricsEvent(); + trackEvent({ + event: 'Clicked "Speed Up"', + category: 'Navigation', + properties: { + action: 'Activity Log', + legacy_event: true, + }, + }); if (supportsEIP1559V2) { setEditGasMode(EDIT_GAS_MODES.SPEED_UP); openModal('cancelSpeedUpTransaction'); @@ -87,13 +80,20 @@ function TransactionListItemInner({ setShowRetryEditGasPopover(true); } }, - [openModal, setEditGasMode, speedUpMetricsEvent, supportsEIP1559V2], + [openModal, setEditGasMode, trackEvent, supportsEIP1559V2], ); const cancelTransaction = useCallback( (event) => { event.stopPropagation(); - cancelMetricsEvent(); + trackEvent({ + event: 'Clicked "Cancel"', + category: 'Navigation', + properties: { + action: 'Activity Log', + legacy_event: true, + }, + }); if (supportsEIP1559V2) { setEditGasMode(EDIT_GAS_MODES.CANCEL); openModal('cancelSpeedUpTransaction'); @@ -101,7 +101,7 @@ function TransactionListItemInner({ setShowCancelEditGasPopover(true); } }, - [cancelMetricsEvent, openModal, setEditGasMode, supportsEIP1559V2], + [trackEvent, openModal, setEditGasMode, supportsEIP1559V2], ); const shouldShowSpeedUp = useShouldShowSpeedUp( diff --git a/ui/components/app/wallet-overview/eth-overview.js b/ui/components/app/wallet-overview/eth-overview.js index 001f84694..8345021bf 100644 --- a/ui/components/app/wallet-overview/eth-overview.js +++ b/ui/components/app/wallet-overview/eth-overview.js @@ -10,10 +10,7 @@ import { SEND_ROUTE, BUILD_QUOTE_ROUTE, } from '../../../helpers/constants/routes'; -import { - useMetricEvent, - useNewMetricEvent, -} from '../../../hooks/useMetricEvent'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import Tooltip from '../../ui/tooltip'; import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; @@ -34,25 +31,13 @@ import SendIcon from '../../ui/icon/overview-send-icon.component'; import { setSwapsFromToken } from '../../../ducks/swaps/swaps'; import IconButton from '../../ui/icon-button'; import { isHardwareKeyring } from '../../../helpers/utils/hardware'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; import WalletOverview from './wallet-overview'; const EthOverview = ({ className }) => { const dispatch = useDispatch(); const t = useContext(I18nContext); - const sendEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Home', - name: 'Clicked Send: Eth', - }, - }); - const depositEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Home', - name: 'Clicked Deposit', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const history = useHistory(); const keyring = useSelector(getCurrentKeyring); const usingHardwareWallet = isHardwareKeyring(keyring?.type); @@ -119,7 +104,14 @@ const EthOverview = ({ className }) => { disabled={!isBuyableChain} label={t('buy')} onClick={() => { - depositEvent(); + trackEvent({ + event: 'Clicked Deposit', + category: 'Navigation', + properties: { + action: 'Home', + legacy_event: true, + }, + }); dispatch(showModal({ name: 'DEPOSIT_ETHER' })); }} /> @@ -129,7 +121,14 @@ const EthOverview = ({ className }) => { Icon={SendIcon} label={t('send')} onClick={() => { - sendEvent(); + trackEvent({ + event: 'Clicked Send: Eth', + category: 'Navigation', + properties: { + action: 'Home', + legacy_event: true, + }, + }); history.push(SEND_ROUTE); }} /> diff --git a/ui/components/app/wallet-overview/token-overview.js b/ui/components/app/wallet-overview/token-overview.js index 5fae06d63..0f4baf3ce 100644 --- a/ui/components/app/wallet-overview/token-overview.js +++ b/ui/components/app/wallet-overview/token-overview.js @@ -12,10 +12,7 @@ import { SEND_ROUTE, BUILD_QUOTE_ROUTE, } from '../../../helpers/constants/routes'; -import { - useMetricEvent, - useNewMetricEvent, -} from '../../../hooks/useMetricEvent'; +import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { useTokenTracker } from '../../../hooks/useTokenTracker'; import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send'; @@ -31,18 +28,13 @@ import SendIcon from '../../ui/icon/overview-send-icon.component'; import IconButton from '../../ui/icon-button'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; import { showModal } from '../../../store/actions'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; import WalletOverview from './wallet-overview'; const TokenOverview = ({ className, token }) => { const dispatch = useDispatch(); const t = useContext(I18nContext); - const sendTokenEvent = useMetricEvent({ - eventOpts: { - category: 'Navigation', - action: 'Home', - name: 'Clicked Send: Token', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const history = useHistory(); const keyring = useSelector(getCurrentKeyring); const usingHardwareWallet = isHardwareKeyring(keyring.type); @@ -95,7 +87,14 @@ const TokenOverview = ({ className, token }) => { { - sendTokenEvent(); + trackEvent({ + event: 'Clicked Send: Token', + category: 'Navigation', + properties: { + action: 'Home', + legacy_event: true, + }, + }); try { await dispatch( updateSendAsset({ diff --git a/ui/hooks/useMetricEvent.js b/ui/hooks/useMetricEvent.js index f6e44574a..a4cc077c8 100644 --- a/ui/hooks/useMetricEvent.js +++ b/ui/hooks/useMetricEvent.js @@ -1,7 +1,6 @@ import { useContext, useCallback } from 'react'; import { useSelector } from 'react-redux'; import { useRouteMatch } from 'react-router-dom'; -import { MetaMetricsContext } from '../contexts/metametrics'; import { MetaMetricsContext as NewMetaMetricsContext } from '../contexts/metametrics.new'; import { PATH_NAME_MAP } from '../helpers/constants/routes'; import { txDataSelector } from '../selectors'; @@ -13,16 +12,6 @@ import { useEqualityCheck } from './useEqualityCheck'; * @typedef {import('../../shared/constants/metametrics').MetaMetricsEventOptions} MetaMetricsEventOptions */ -export function useMetricEvent(config = {}, overrides = {}) { - const metricsEvent = useContext(MetaMetricsContext); - const trackEvent = useCallback(() => metricsEvent(config, overrides), [ - config, - metricsEvent, - overrides, - ]); - return trackEvent; -} - /** * track a metametrics event using segment * e.g metricsEvent({ event: 'Unlocked MetaMask', category: 'Navigation' }) diff --git a/ui/pages/onboarding-flow/creation-successful/creation-successful.js b/ui/pages/onboarding-flow/creation-successful/creation-successful.js index fad8fe801..e5d858d86 100644 --- a/ui/pages/onboarding-flow/creation-successful/creation-successful.js +++ b/ui/pages/onboarding-flow/creation-successful/creation-successful.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { useHistory } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; import Box from '../../../components/ui/box'; @@ -15,8 +15,8 @@ import { ONBOARDING_PRIVACY_SETTINGS_ROUTE, } from '../../../helpers/constants/routes'; import { setCompletedOnboarding } from '../../../store/actions'; -import { useMetricEvent } from '../../../hooks/useMetricEvent'; import { getFirstTimeFlowType } from '../../../selectors'; +import { MetaMetricsContext } from '../../../contexts/metametrics.new'; export default function CreationSuccessful() { const firstTimeFlowTypeNameMap = { @@ -28,15 +28,18 @@ export default function CreationSuccessful() { const dispatch = useDispatch(); const firstTimeFlowType = useSelector(getFirstTimeFlowType); - const onboardingCompletedEvent = useMetricEvent({ - category: 'Onboarding', - action: 'Onboarding Complete', - name: firstTimeFlowTypeNameMap[firstTimeFlowType], - }); + const trackEvent = useContext(MetaMetricsContext); const onComplete = async () => { await dispatch(setCompletedOnboarding()); - onboardingCompletedEvent(); + trackEvent({ + event: firstTimeFlowTypeNameMap[firstTimeFlowType], + category: 'Onboarding', + properties: { + action: 'Onboarding Complete', + legacy_event: true, + }, + }); history.push(ONBOARDING_PIN_EXTENSION_ROUTE); }; return ( diff --git a/ui/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.js b/ui/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.js index f7b763d70..5144ae928 100644 --- a/ui/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.js +++ b/ui/pages/send/send-content/send-amount-row/amount-max-button/amount-max-button.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useContext } from 'react'; import classnames from 'classnames'; import { useDispatch, useSelector } from 'react-redux'; import { @@ -7,23 +7,24 @@ import { toggleSendMaxMode, } from '../../../../../ducks/send'; import { useI18nContext } from '../../../../../hooks/useI18nContext'; -import { useMetricEvent } from '../../../../../hooks/useMetricEvent'; +import { MetaMetricsContext } from '../../../../../contexts/metametrics.new'; export default function AmountMaxButton() { const isDraftTransactionInvalid = useSelector(isSendFormInvalid); const maxModeOn = useSelector(getSendMaxModeState); const dispatch = useDispatch(); - const trackClickedMax = useMetricEvent({ - eventOpts: { - category: 'Transactions', - action: 'Edit Screen', - name: 'Clicked "Amount Max"', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const t = useI18nContext(); const onMaxClick = () => { - trackClickedMax(); + trackEvent({ + event: 'Clicked "Amount Max"', + category: 'Transactions', + properties: { + action: 'Edit Screen', + legacy_event: true, + }, + }); dispatch(toggleSendMaxMode()); }; diff --git a/ui/pages/send/send.js b/ui/pages/send/send.js index 3c5515867..aa9c38c6b 100644 --- a/ui/pages/send/send.js +++ b/ui/pages/send/send.js @@ -1,4 +1,4 @@ -import React, { useEffect, useCallback } from 'react'; +import React, { useEffect, useCallback, useContext } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, useLocation } from 'react-router-dom'; import { @@ -16,7 +16,7 @@ import { import { getCurrentChainId, isCustomPriceExcessive } from '../../selectors'; import { getSendHexDataFeatureFlagState } from '../../ducks/metamask/metamask'; import { showQrScanner } from '../../store/actions'; -import { useMetricEvent } from '../../hooks/useMetricEvent'; +import { MetaMetricsContext } from '../../contexts/metametrics.new'; import SendHeader from './send-header'; import AddRecipient from './send-content/add-recipient'; import SendContent from './send-content'; @@ -38,13 +38,7 @@ export default function SendTransactionScreen() { const showHexData = useSelector(getSendHexDataFeatureFlagState); const userInput = useSelector(getRecipientUserInput); const location = useLocation(); - const trackUsedQRScanner = useMetricEvent({ - eventOpts: { - category: 'Transactions', - action: 'Edit Screen', - name: 'Used QR scanner', - }, - }); + const trackEvent = useContext(MetaMetricsContext); const dispatch = useDispatch(); @@ -109,7 +103,14 @@ export default function SendTransactionScreen() { onPaste={(text) => updateRecipient({ address: text, nickname: '' })} onReset={() => dispatch(resetRecipientInput())} scanQrCode={() => { - trackUsedQRScanner(); + trackEvent({ + event: 'Used QR scanner', + category: 'Transactions', + properties: { + action: 'Edit Screen', + legacy_event: true, + }, + }); dispatch(showQrScanner()); }} /> From 69c2cd3a94619c29203d9a5afbc30c79bcd45d51 Mon Sep 17 00:00:00 2001 From: Ariella Vu <20778143+digiwand@users.noreply.github.com> Date: Mon, 14 Mar 2022 15:26:02 -0300 Subject: [PATCH 003/192] Permissions: convert hook to util (#13906) * Permissions: convert hook into helper util - instantiate once - freeze - alphabetize - add additional comments to @param https://github.com/MetaMask/metamask-extension/pull/13906#pullrequestreview-906554847 --- .../connected-accounts-permissions.js | 6 +- .../permissions-connect-permission-list.js | 6 +- ui/helpers/utils/permission.js | 92 +++++++++++++++++ ui/hooks/usePermissionDescriptions.js | 98 ------------------- 4 files changed, 98 insertions(+), 104 deletions(-) create mode 100644 ui/helpers/utils/permission.js delete mode 100644 ui/hooks/usePermissionDescriptions.js diff --git a/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js b/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js index feb781ab7..dce984c47 100644 --- a/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js +++ b/ui/components/app/connected-accounts-permissions/connected-accounts-permissions.js @@ -3,14 +3,12 @@ import PropTypes from 'prop-types'; import React, { useState } from 'react'; import CheckBox from '../../ui/check-box'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { usePermissionDescriptions } from '../../../hooks/usePermissionDescriptions'; +import { getPermissionDescription } from '../../../helpers/utils/permission'; const ConnectedAccountsPermissions = ({ permissions }) => { const t = useI18nContext(); const [expanded, setExpanded] = useState(false); - const getPermissionDescription = usePermissionDescriptions(); - const toggleExpanded = () => { setExpanded((_expanded) => !_expanded); }; @@ -56,7 +54,7 @@ const ConnectedAccountsPermissions = ({ permissions }) => { className="connected-accounts-permissions__checkbox" /> ))} diff --git a/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js b/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js index 49ab4c003..d2459025d 100644 --- a/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js +++ b/ui/components/app/permissions-connect-permission-list/permissions-connect-permission-list.js @@ -1,14 +1,16 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { usePermissionDescriptions } from '../../../hooks/usePermissionDescriptions'; +import { getPermissionDescription } from '../../../helpers/utils/permission'; +import { useI18nContext } from '../../../hooks/useI18nContext'; export default function PermissionsConnectPermissionList({ permissions }) { - const getPermissionDescription = usePermissionDescriptions(); + const t = useI18nContext(); return (
{Object.keys(permissions).map((permission) => { const { label, leftIcon, rightIcon } = getPermissionDescription( + t, permission, ); diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js new file mode 100644 index 000000000..baa21dc18 --- /dev/null +++ b/ui/helpers/utils/permission.js @@ -0,0 +1,92 @@ +import deepFreeze from 'deep-freeze-strict'; +import { + RestrictedMethods, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + EndowmentPermissions, + PermissionNamespaces, + ///: END:ONLY_INCLUDE_IN +} from '../../../shared/constants/permissions'; +///: BEGIN:ONLY_INCLUDE_IN(flask) +import { coinTypeToProtocolName } from './util'; +///: END:ONLY_INCLUDE_IN + +const UNKNOWN_PERMISSION = Symbol('unknown'); + +const PERMISSION_DESCRIPTIONS = deepFreeze({ + [RestrictedMethods.eth_accounts]: { + label: (t) => t('permission_ethereumAccounts'), + leftIcon: 'fas fa-eye', + rightIcon: null, + }, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + [RestrictedMethods.snap_confirm]: { + label: (t) => t('permission_customConfirmation'), + leftIcon: 'fas fa-user-check', + rightIcon: null, + }, + [RestrictedMethods['snap_getBip44Entropy_*']]: { + label: (t, permissionName) => { + const coinType = permissionName.split('_').slice(-1); + return t('permission_manageBip44Keys', [ + coinTypeToProtocolName(coinType) || + `${coinType} (Unrecognized protocol)`, + ]); + }, + leftIcon: 'fas fa-door-open', + rightIcon: null, + }, + [RestrictedMethods.snap_manageState]: { + label: (t) => t('permission_manageState'), + leftIcon: 'fas fa-download', + rightIcon: null, + }, + [RestrictedMethods['wallet_snap_*']]: { + label: (t, permissionName) => { + const snapId = permissionName.split('_').slice(-1); + return t('permission_accessSnap', [snapId]); + }, + leftIcon: 'fas fa-bolt', + rightIcon: null, + }, + [EndowmentPermissions['endowment:network-access']]: { + label: (t) => t('permission_accessNetwork'), + leftIcon: 'fas fa-wifi', + rightIcon: null, + }, + ///: END:ONLY_INCLUDE_IN + [UNKNOWN_PERMISSION]: { + label: (t, permissionName) => + t('permission_unknown', [permissionName ?? 'undefined']), + leftIcon: 'fas fa-times-circle', + rightIcon: null, + }, +}); + +/** + * @typedef {Object} PermissionLabelObject + * @property {string} label - The text label. + * @property {string} leftIcon - The left icon. + * @property {string} rightIcon - The right icon. + */ + +/** + * @param {Function} t - The translation function + * @param {string} permissionName - The name of the permission to request + * @returns {(permissionName:string) => PermissionLabelObject} + */ +export const getPermissionDescription = (t, permissionName) => { + let value = PERMISSION_DESCRIPTIONS[UNKNOWN_PERMISSION]; + + if (Object.hasOwnProperty.call(PERMISSION_DESCRIPTIONS, permissionName)) { + value = PERMISSION_DESCRIPTIONS[permissionName]; + } + ///: BEGIN:ONLY_INCLUDE_IN(flask) + for (const namespace of Object.keys(PermissionNamespaces)) { + if (permissionName.startsWith(namespace)) { + value = PERMISSION_DESCRIPTIONS[PermissionNamespaces[namespace]]; + } + } + ///: END:ONLY_INCLUDE_IN + + return { ...value, label: value.label(t, permissionName) }; +}; diff --git a/ui/hooks/usePermissionDescriptions.js b/ui/hooks/usePermissionDescriptions.js deleted file mode 100644 index 054f47bfe..000000000 --- a/ui/hooks/usePermissionDescriptions.js +++ /dev/null @@ -1,98 +0,0 @@ -import { useMemo } from 'react'; -import { - RestrictedMethods, - ///: BEGIN:ONLY_INCLUDE_IN(flask) - EndowmentPermissions, - PermissionNamespaces, - ///: END:ONLY_INCLUDE_IN -} from '../../shared/constants/permissions'; -///: BEGIN:ONLY_INCLUDE_IN(flask) -import { coinTypeToProtocolName } from '../helpers/utils/util'; -///: END:ONLY_INCLUDE_IN -import { useI18nContext } from './useI18nContext'; - -const UNKNOWN_PERMISSION = Symbol('unknown'); - -/** - * @typedef {Object} PermissionLabelObject - * @property {string} label - The text label. - * @property {string} leftIcon - The left icon. - * @property {string} rightIcon - The right icon. - */ - -/** - * @returns {(permissionName:string) => PermissionLabelObject} - */ -export const usePermissionDescriptions = () => { - const t = useI18nContext(); - - return useMemo(() => { - const permissionDescriptions = { - [RestrictedMethods.eth_accounts]: { - leftIcon: 'fas fa-eye', - label: t('permission_ethereumAccounts'), - rightIcon: null, - }, - ///: BEGIN:ONLY_INCLUDE_IN(flask) - [RestrictedMethods.snap_confirm]: { - leftIcon: 'fas fa-user-check', - label: t('permission_customConfirmation'), - rightIcon: null, - }, - [RestrictedMethods['snap_getBip44Entropy_*']]: (permissionName) => { - const coinType = permissionName.split('_').slice(-1); - return { - leftIcon: 'fas fa-door-open', - label: t('permission_manageBip44Keys', [ - coinTypeToProtocolName(coinType) || - `${coinType} (Unrecognized protocol)`, - ]), - rightIcon: null, - }; - }, - [RestrictedMethods.snap_manageState]: { - leftIcon: 'fas fa-download', - label: t('permission_manageState'), - rightIcon: null, - }, - [RestrictedMethods['wallet_snap_*']]: (permissionName) => { - const snapId = permissionName.split('_').slice(-1); - return { - leftIcon: 'fas fa-bolt', - label: t('permission_accessSnap', [snapId]), - rightIcon: null, - }; - }, - [EndowmentPermissions['endowment:network-access']]: { - leftIcon: 'fas fa-wifi', - label: t('permission_accessNetwork'), - rightIcon: null, - }, - ///: END:ONLY_INCLUDE_IN - [UNKNOWN_PERMISSION]: (permissionName) => { - return { - leftIcon: 'fas fa-times-circle', - label: t('permission_unknown', [permissionName ?? 'undefined']), - rightIcon: null, - }; - }, - }; - - return (permissionName) => { - let value = permissionDescriptions[UNKNOWN_PERMISSION]; - - if (Object.hasOwnProperty.call(permissionDescriptions, permissionName)) { - value = permissionDescriptions[permissionName]; - } - ///: BEGIN:ONLY_INCLUDE_IN(flask) - for (const namespace of Object.keys(PermissionNamespaces)) { - if (permissionName.startsWith(namespace)) { - value = permissionDescriptions[PermissionNamespaces[namespace]]; - } - } - ///: END:ONLY_INCLUDE_IN - - return typeof value === 'function' ? value(permissionName) : value; - }; - }, [t]); -}; From 118480280c9506574e160531969abd37f87404ac Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Mon, 14 Mar 2022 12:37:19 -0700 Subject: [PATCH 004/192] snaps-skunkworks@0.10.2 (#13901) --- .../permissions/caveat-mutators.js | 2 +- .../permissions/caveat-mutators.test.js | 2 +- .../permissions/flask/snap-permissions.js | 11 ++- .../controllers/permissions/specifications.js | 5 +- .../createMethodMiddleware.js | 4 +- app/scripts/metamask-controller.js | 3 +- lavamoat/browserify/beta/policy.json | 7 +- lavamoat/browserify/flask/policy.json | 9 +- lavamoat/browserify/main/policy.json | 7 +- package.json | 12 ++- shared/constants/permissions.js | 3 + shared/constants/permissions.test.js | 12 ++- yarn.lock | 99 +++++++++++-------- 13 files changed, 103 insertions(+), 73 deletions(-) diff --git a/app/scripts/controllers/permissions/caveat-mutators.js b/app/scripts/controllers/permissions/caveat-mutators.js index fe61df6df..84f9a0ddb 100644 --- a/app/scripts/controllers/permissions/caveat-mutators.js +++ b/app/scripts/controllers/permissions/caveat-mutators.js @@ -1,4 +1,4 @@ -import { CaveatMutatorOperation } from '@metamask/snap-controllers'; +import { CaveatMutatorOperation } from '@metamask/controllers'; import { CaveatTypes } from '../../../../shared/constants/permissions'; /** diff --git a/app/scripts/controllers/permissions/caveat-mutators.test.js b/app/scripts/controllers/permissions/caveat-mutators.test.js index 93c3d0dad..476b3e1f6 100644 --- a/app/scripts/controllers/permissions/caveat-mutators.test.js +++ b/app/scripts/controllers/permissions/caveat-mutators.test.js @@ -1,4 +1,4 @@ -import { CaveatMutatorOperation } from '@metamask/snap-controllers'; +import { CaveatMutatorOperation } from '@metamask/controllers'; import { CaveatTypes } from '../../../../shared/constants/permissions'; import { CaveatMutatorFactories } from './caveat-mutators'; diff --git a/app/scripts/controllers/permissions/flask/snap-permissions.js b/app/scripts/controllers/permissions/flask/snap-permissions.js index bea6ba7a3..bde8c4c91 100644 --- a/app/scripts/controllers/permissions/flask/snap-permissions.js +++ b/app/scripts/controllers/permissions/flask/snap-permissions.js @@ -1,8 +1,9 @@ +import { endowmentPermissionBuilders } from '@metamask/controllers'; import { restrictedMethodPermissionBuilders, selectHooks, } from '@metamask/rpc-methods'; -import { endowmentPermissionBuilders } from '@metamask/snap-controllers'; +import { ExcludedSnapPermissions } from '../../../../../shared/constants/permissions'; /** * @returns {Record>} All endowment permission @@ -24,9 +25,11 @@ export const buildSnapEndowmentSpecifications = () => export function buildSnapRestrictedMethodSpecifications(hooks) { return Object.values(restrictedMethodPermissionBuilders).reduce( (specifications, { targetKey, specificationBuilder, methodHooks }) => { - specifications[targetKey] = specificationBuilder({ - methodHooks: selectHooks(hooks, methodHooks), - }); + if (!ExcludedSnapPermissions.has(targetKey)) { + specifications[targetKey] = specificationBuilder({ + methodHooks: selectHooks(hooks, methodHooks), + }); + } return specifications; }, {}, diff --git a/app/scripts/controllers/permissions/specifications.js b/app/scripts/controllers/permissions/specifications.js index 201810e54..bab176db2 100644 --- a/app/scripts/controllers/permissions/specifications.js +++ b/app/scripts/controllers/permissions/specifications.js @@ -1,7 +1,4 @@ -import { - constructPermission, - PermissionType, -} from '@metamask/snap-controllers'; +import { constructPermission, PermissionType } from '@metamask/controllers'; import { CaveatTypes, RestrictedMethods, diff --git a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js index 74587ed73..642fdb1ce 100644 --- a/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js +++ b/app/scripts/lib/rpc-method-middleware/createMethodMiddleware.js @@ -1,10 +1,10 @@ ///: BEGIN:ONLY_INCLUDE_IN(flask) import { handlers as permittedSnapMethods } from '@metamask/rpc-methods/dist/permitted'; ///: END:ONLY_INCLUDE_IN -import { flatten } from 'lodash'; -import { permissionRpcMethods } from '@metamask/snap-controllers'; +import { permissionRpcMethods } from '@metamask/controllers'; import { selectHooks } from '@metamask/rpc-methods'; import { ethErrors } from 'eth-rpc-errors'; +import { flatten } from 'lodash'; import { UNSUPPORTED_RPC_METHODS } from '../../../../shared/constants/network'; import localHandlers from './handlers'; diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index eb5381a6b..8297a21fe 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -589,7 +589,7 @@ export default class MetamaskController extends EventEmitter { this.workerController = new IframeExecutionService({ onError: this.onExecutionEnvironmentError.bind(this), iframeUrl: new URL( - 'https://metamask.github.io/iframe-execution-environment/0.3.1', + 'https://metamask.github.io/iframe-execution-environment/0.4.0', ), messenger: this.controllerMessenger.getRestricted({ name: 'ExecutionService', @@ -607,6 +607,7 @@ export default class MetamaskController extends EventEmitter { `${this.permissionController.name}:getEndowments`, `${this.permissionController.name}:getPermissions`, `${this.permissionController.name}:hasPermission`, + `${this.permissionController.name}:hasPermissions`, `${this.permissionController.name}:requestPermissions`, `${this.permissionController.name}:revokeAllPermissions`, ], diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 86a77a3df..eaa8a7633 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -695,6 +695,7 @@ }, "@metamask/rpc-methods": { "packages": { + "@metamask/controllers": true, "@metamask/key-tree": true, "@metamask/snap-controllers": true, "eth-rpc-errors": true @@ -734,25 +735,23 @@ "clearTimeout": true, "console.error": true, "console.log": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/controllers": true, + "@metamask/execution-environments": true, "@metamask/object-multiplex": true, "@metamask/obs-store": true, "@metamask/post-message-stream": true, "@metamask/safe-event-emitter": true, - "@metamask/snap-workers": true, "ajv": true, "buffer": true, "concat-stream": true, + "cross-fetch": true, "crypto-browserify": true, - "deep-freeze-strict": true, "eth-rpc-errors": true, "fast-deep-equal": true, "gunzip-maybe": true, - "immer": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, "nanoid": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 9882d00ed..28f79890d 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -637,9 +637,9 @@ "setTimeout": true }, "packages": { + "@metamask/execution-environments": true, "@metamask/post-message-stream": true, "@metamask/snap-controllers": true, - "@metamask/snap-workers": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, "nanoid": true, @@ -714,6 +714,7 @@ }, "@metamask/rpc-methods": { "packages": { + "@metamask/controllers": true, "@metamask/key-tree": true, "@metamask/snap-controllers": true, "eth-rpc-errors": true @@ -753,25 +754,23 @@ "clearTimeout": true, "console.error": true, "console.log": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/controllers": true, + "@metamask/execution-environments": true, "@metamask/object-multiplex": true, "@metamask/obs-store": true, "@metamask/post-message-stream": true, "@metamask/safe-event-emitter": true, - "@metamask/snap-workers": true, "ajv": true, "buffer": true, "concat-stream": true, + "cross-fetch": true, "crypto-browserify": true, - "deep-freeze-strict": true, "eth-rpc-errors": true, "fast-deep-equal": true, "gunzip-maybe": true, - "immer": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, "nanoid": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 86a77a3df..eaa8a7633 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -695,6 +695,7 @@ }, "@metamask/rpc-methods": { "packages": { + "@metamask/controllers": true, "@metamask/key-tree": true, "@metamask/snap-controllers": true, "eth-rpc-errors": true @@ -734,25 +735,23 @@ "clearTimeout": true, "console.error": true, "console.log": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/controllers": true, + "@metamask/execution-environments": true, "@metamask/object-multiplex": true, "@metamask/obs-store": true, "@metamask/post-message-stream": true, "@metamask/safe-event-emitter": true, - "@metamask/snap-workers": true, "ajv": true, "buffer": true, "concat-stream": true, + "cross-fetch": true, "crypto-browserify": true, - "deep-freeze-strict": true, "eth-rpc-errors": true, "fast-deep-equal": true, "gunzip-maybe": true, - "immer": true, "json-rpc-engine": true, "json-rpc-middleware-stream": true, "nanoid": true, diff --git a/package.json b/package.json index d461d37f4..0ef86bc43 100644 --- a/package.json +++ b/package.json @@ -117,16 +117,16 @@ "@metamask/eth-ledger-bridge-keyring": "^0.10.0", "@metamask/eth-token-tracker": "^4.0.0", "@metamask/etherscan-link": "^2.1.0", - "@metamask/iframe-execution-environment-service": "^0.9.0", + "@metamask/iframe-execution-environment-service": "^0.10.2", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^3.1.1", "@metamask/obs-store": "^5.0.0", "@metamask/post-message-stream": "^4.0.0", "@metamask/providers": "^8.1.1", - "@metamask/rpc-methods": "^0.9.0", + "@metamask/rpc-methods": "^0.10.0", "@metamask/slip44": "^2.0.0", "@metamask/smart-transactions-controller": "^1.9.1", - "@metamask/snap-controllers": "^0.9.0", + "@metamask/snap-controllers": "^0.10.2", "@ngraveio/bc-ur": "^1.1.6", "@popperjs/core": "^2.4.0", "@reduxjs/toolkit": "^1.6.2", @@ -423,7 +423,11 @@ "ganache>leveldown": false, "geckodriver": true, "react-devtools>electron": true, - "eth-trezor-keyring>trezor-connect>@trezor/transport>protobufjs": false + "eth-trezor-keyring>trezor-connect>@trezor/transport>protobufjs": false, + "@metamask/iframe-execution-environment-service>@metamask/execution-environments": false, + "@metamask/snap-controllers>@metamask/execution-environments": false, + "@metamask/iframe-execution-environment-service>@metamask/snap-controllers>@metamask/execution-environments": false, + "@metamask/rpc-methods>@metamask/snap-controllers>@metamask/execution-environments": false } } } diff --git a/shared/constants/permissions.js b/shared/constants/permissions.js index ddfb12e23..982f20e7b 100644 --- a/shared/constants/permissions.js +++ b/shared/constants/permissions.js @@ -21,4 +21,7 @@ export const PermissionNamespaces = Object.freeze({ export const EndowmentPermissions = Object.freeze({ 'endowment:network-access': 'endowment:network-access', }); + +// Methods / permissions in external packages that we are temporarily excluding. +export const ExcludedSnapPermissions = new Set(['snap_notify']); ///: END:ONLY_INCLUDE_IN diff --git a/shared/constants/permissions.test.js b/shared/constants/permissions.test.js index 2c3b408f0..c6ace6243 100644 --- a/shared/constants/permissions.test.js +++ b/shared/constants/permissions.test.js @@ -1,6 +1,10 @@ -import { endowmentPermissionBuilders } from '@metamask/snap-controllers'; +import { endowmentPermissionBuilders } from '@metamask/controllers'; import { restrictedMethodPermissionBuilders } from '@metamask/rpc-methods'; -import { EndowmentPermissions, RestrictedMethods } from './permissions'; +import { + EndowmentPermissions, + ExcludedSnapPermissions, + RestrictedMethods, +} from './permissions'; describe('EndowmentPermissions', () => { it('has the expected permission keys', () => { @@ -15,7 +19,9 @@ describe('RestrictedMethods', () => { expect(Object.keys(RestrictedMethods).sort()).toStrictEqual( [ 'eth_accounts', - ...Object.keys(restrictedMethodPermissionBuilders), + ...Object.keys(restrictedMethodPermissionBuilders).filter( + (targetKey) => !ExcludedSnapPermissions.has(targetKey), + ), ].sort(), ); }); diff --git a/yarn.lock b/yarn.lock index 96e8e18a3..85005f7b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2811,22 +2811,37 @@ resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-2.1.0.tgz#c0be8e68445b7b83cf85bcc03a56cdf8e256c973" integrity sha512-ADuWlTUkFfN2vXlz81Bg/0BA+XRor+CdK1055p6k7H6BLIPoDKn9SBOFld9haQFuR9cKh/JYHcnlSIv5R4fUEw== +"@metamask/execution-environments@^0.10.1", "@metamask/execution-environments@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@metamask/execution-environments/-/execution-environments-0.10.2.tgz#dfa4750a0eee4f51d9bc7e3c75a0e80a18798093" + integrity sha512-4bqDTk0oPRiju21M8KNaoxT8eiGaygyC2pldIrCDByfDqiIVkIpv8neol6EEH7ebMQkNiC4sr8IhfNFL7cJIdA== + dependencies: + "@metamask/object-multiplex" "^1.2.0" + "@metamask/post-message-stream" "^4.0.0" + "@metamask/providers" "^8.1.1" + "@metamask/snap-types" "^0.10.1" + cross-fetch "^3.1.5" + eth-rpc-errors "^4.0.3" + pump "^3.0.0" + ses "^0.15.7" + stream-browserify "^3.0.0" + "@metamask/forwarder@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@metamask/forwarder/-/forwarder-1.1.0.tgz#13829d8244bbf19ea658c0b20d21a77b67de0bdd" integrity sha512-Hggj4y0QIjDzKGTXzarhEPIQyFSB2bi2y6YLJNwaT4JmP30UB5Cj6gqoY0M4pj3QT57fzp0BUuGp7F/AUe28tw== -"@metamask/iframe-execution-environment-service@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@metamask/iframe-execution-environment-service/-/iframe-execution-environment-service-0.9.0.tgz#721e15ee4651741a599940dbcfa524cc55eaaa47" - integrity sha512-a240sg83sX1dxfBDdRd0uoujaN4V9VtHKELMcTMgpYCI0uE83//Q01a7L8MiBtLhzr8o4D/xXRUIDR0Y9NKc3Q== +"@metamask/iframe-execution-environment-service@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@metamask/iframe-execution-environment-service/-/iframe-execution-environment-service-0.10.2.tgz#85e38616af2a46b170c4940e2d7c5cd8eeaa4c48" + integrity sha512-99hAcMyeqacmhh4dsD4my55Y6g5v2L6ftXmTu7cfl+EKy39t5miWSKTGbL4dDocsAiKI/7nI9LMyyWFgcDCx8Q== dependencies: - "@metamask/controllers" "^25.1.0" + "@metamask/controllers" "^26.0.0" + "@metamask/execution-environments" "^0.10.2" "@metamask/object-multiplex" "^1.2.0" "@metamask/post-message-stream" "^4.0.0" - "@metamask/snap-controllers" "^0.9.0" - "@metamask/snap-types" "^0.9.0" - "@metamask/snap-workers" "^0.9.0" + "@metamask/snap-controllers" "^0.10.2" + "@metamask/snap-types" "^0.10.1" eth-rpc-errors "^4.0.3" json-rpc-engine "^6.1.0" json-rpc-middleware-stream "^3.0.0" @@ -2920,13 +2935,15 @@ pump "^3.0.0" webextension-polyfill-ts "^0.25.0" -"@metamask/rpc-methods@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@metamask/rpc-methods/-/rpc-methods-0.9.0.tgz#eb55cc39d2ea9a663211e8d805bdf566af70c764" - integrity sha512-wii0TMuRscet8+x3tqfAcEmY0TrMFzOnD3QFpFVUy3fznv4b/EzDD/XLQToafd2yUaDjUrrS9FHwU9omqzPxcg== +"@metamask/rpc-methods@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@metamask/rpc-methods/-/rpc-methods-0.10.0.tgz#8d7ea5e378a9144b4171f4f846d06d10657ed02e" + integrity sha512-nHFO8Dg4L422cKMgLXnfkX0F3z7j3N/7KyLPgxCoOhHvFz35uwC1jxz9WWF2+yv7j1Y8hVkRg4umyg76/IXZLg== dependencies: + "@metamask/controllers" "^26.0.0" "@metamask/key-tree" "^3.0.1" - "@metamask/snap-controllers" "^0.9.0" + "@metamask/snap-controllers" "^0.10.0" + "@metamask/types" "^1.1.0" eth-rpc-errors "^4.0.2" "@metamask/safe-event-emitter@^2.0.0": @@ -2952,20 +2969,22 @@ isomorphic-fetch "^3.0.0" lodash "^4.17.21" -"@metamask/snap-controllers@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@metamask/snap-controllers/-/snap-controllers-0.9.0.tgz#e0006fc9991e995dd86dff792106990aae2aeda0" - integrity sha512-os3fEai0w4ctpyy6ExlthY8tnww98Vm+RVwOZgrCKDY5dAXqlSXpyWc1uOfkQyiPhUEJtdznJTWzaWzNIO9MfQ== +"@metamask/snap-controllers@^0.10.0", "@metamask/snap-controllers@^0.10.2": + version "0.10.2" + resolved "https://registry.yarnpkg.com/@metamask/snap-controllers/-/snap-controllers-0.10.2.tgz#0261ff82dd384f8a9398116967cfa2f7eb44b063" + integrity sha512-KFM7U6hCmUjevLK2hYUMcqRKtxK3/J2cI8uUbE1rx4zwBfDuN58RfI1s+69rZtblucqpnuqKs+Mc56lxb6+6oQ== dependencies: - "@metamask/controllers" "^25.1.0" + "@metamask/controllers" "^26.0.0" + "@metamask/execution-environments" "^0.10.2" "@metamask/object-multiplex" "^1.1.0" "@metamask/obs-store" "^7.0.0" "@metamask/post-message-stream" "4.0.0" "@metamask/safe-event-emitter" "^2.0.0" - "@metamask/snap-workers" "^0.9.0" "@types/deep-freeze-strict" "^1.1.0" + "@types/semver" "^7.3.9" ajv "^8.8.2" concat-stream "^2.0.0" + cross-fetch "^3.1.5" deep-freeze-strict "^1.1.1" eth-rpc-errors "^4.0.2" fast-deep-equal "^3.1.3" @@ -2979,17 +2998,12 @@ semver "^7.3.5" tar-stream "^2.2.0" -"@metamask/snap-types@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@metamask/snap-types/-/snap-types-0.9.0.tgz#aa164111be1b5c53fbaaf03c1bccbdbd0741daa4" - integrity sha512-pK4tvurUhcKMEkTD0XvQze5HCbtrgmpFWDztBekNIMJTXDrnYIEw4Dxn+LwCX7WJ0DN/03brQSEzmIrYbcBw7Q== +"@metamask/snap-types@^0.10.1": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@metamask/snap-types/-/snap-types-0.10.1.tgz#dd170813d38091473f9ae1fd1e9d64c46666ba0c" + integrity sha512-DsTAMSNmVWH/wXL4OWvnI4Wxh247d7PPD0jjxlMC3hEKB6hSdbCW3umwxqBCxgrU18gJOGwNJMygTolxO0SUrA== dependencies: - "@metamask/controllers" "^25.1.0" - -"@metamask/snap-workers@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@metamask/snap-workers/-/snap-workers-0.9.0.tgz#215407b632fef4723dd75af7accf1f02a6a46916" - integrity sha512-+4YY5CQ7OPFPWh4QF5e4COgc0aWL6Df7Oc8/y//Sabp1rmXWI429OzCOlBi+NGJfQ1K7ORBMlRtOwYB9ZmWyLA== + "@metamask/controllers" "^26.0.0" "@metamask/test-dapp@^5.0.0": version "5.0.0" @@ -4667,6 +4681,11 @@ dependencies: "@types/node" "*" +"@types/semver@^7.3.9": + version "7.3.9" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" + integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -8847,12 +8866,12 @@ cross-fetch@^2.1.0: node-fetch "2.1.2" whatwg-fetch "2.0.4" -cross-fetch@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" - integrity sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ== +cross-fetch@^3.1.4, cross-fetch@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== dependencies: - node-fetch "2.6.1" + node-fetch "2.6.7" cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" @@ -19719,12 +19738,7 @@ node-fetch@2.1.2: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U= -node-fetch@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - -node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@~2.6.1: +node-fetch@2.6.7, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@~2.6.1: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== @@ -24567,6 +24581,11 @@ ses@^0.12.4: "@agoric/make-hardener" "^0.1.2" "@agoric/transform-module" "^0.4.1" +ses@^0.15.7: + version "0.15.11" + resolved "https://registry.yarnpkg.com/ses/-/ses-0.15.11.tgz#851cb6a20d8967537075d25bb0185051c28c23db" + integrity sha512-lQg6q8/PVf+n18EjP+5Uv1tN9oVQ3br5QxJzPXoAVQleSYnlf20JY9coe7n1B9A6CtIKIHyr6m/TfskcRCufgA== + set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" From da1b8dd4bbdfb6fbd877ff9cb84dbe7207e41f94 Mon Sep 17 00:00:00 2001 From: Erik Marks <25517051+rekmarks@users.noreply.github.com> Date: Mon, 14 Mar 2022 17:59:53 -0700 Subject: [PATCH 005/192] Fix yarn.lock (#13941) --- yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 85005f7b0..3588b6b2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2811,7 +2811,7 @@ resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-2.1.0.tgz#c0be8e68445b7b83cf85bcc03a56cdf8e256c973" integrity sha512-ADuWlTUkFfN2vXlz81Bg/0BA+XRor+CdK1055p6k7H6BLIPoDKn9SBOFld9haQFuR9cKh/JYHcnlSIv5R4fUEw== -"@metamask/execution-environments@^0.10.1", "@metamask/execution-environments@^0.10.2": +"@metamask/execution-environments@^0.10.2": version "0.10.2" resolved "https://registry.yarnpkg.com/@metamask/execution-environments/-/execution-environments-0.10.2.tgz#dfa4750a0eee4f51d9bc7e3c75a0e80a18798093" integrity sha512-4bqDTk0oPRiju21M8KNaoxT8eiGaygyC2pldIrCDByfDqiIVkIpv8neol6EEH7ebMQkNiC4sr8IhfNFL7cJIdA== From 8143222f9232bc1d7384dbee35c9c98751a30f57 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 14 Mar 2022 20:26:51 -0500 Subject: [PATCH 006/192] Dark Mode: Fix currently selected network color (#13918) --- ui/pages/settings/networks-tab/index.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/pages/settings/networks-tab/index.scss b/ui/pages/settings/networks-tab/index.scss index 60bd8d67e..645901b72 100644 --- a/ui/pages/settings/networks-tab/index.scss +++ b/ui/pages/settings/networks-tab/index.scss @@ -239,7 +239,7 @@ &__networks-list-name--selected { font-weight: bold; - color: #000; + color: var(--color-text-default); } &__networks-list-name--disabled { From cd11f90f8f0bab7276ebae1f2a32b39d7cc93eca Mon Sep 17 00:00:00 2001 From: David Walsh Date: Mon, 14 Mar 2022 20:27:02 -0500 Subject: [PATCH 007/192] Add labels to provide better accessibility during onboarding v2 (#13890) --- .../create-password/create-password.js | 42 ++++++++++--------- .../create-password/index.scss | 4 ++ .../secure-your-wallet/index.scss | 4 ++ .../skip-srp-backup-popover.js | 28 ++++++------- 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/ui/pages/onboarding-flow/create-password/create-password.js b/ui/pages/onboarding-flow/create-password/create-password.js index e91e31004..a275dba85 100644 --- a/ui/pages/onboarding-flow/create-password/create-password.js +++ b/ui/pages/onboarding-flow/create-password/create-password.js @@ -216,26 +216,28 @@ export default function CreatePassword({ justifyContent={JUSTIFY_CONTENT.SPACE_BETWEEN} marginBottom={4} > - setTermsChecked(!termsChecked)} - checked={termsChecked} - /> - - {t('passwordTermsWarning', [ - e.stopPropagation()} - key="create-password__link-text" - href={ZENDESK_URLS.PASSWORD_ARTICLE} - target="_blank" - rel="noopener noreferrer" - > - - {t('learnMoreUpperCase')} - - , - ])} - + +
+ +
); } @@ -161,14 +151,6 @@ class NetworkDropdown extends Component { const isCurrentRpcTarget = provider.type === NETWORK_TYPE_RPC && rpcUrl === provider.rpcUrl; - let borderColor = COLORS.UI2; - if (isCurrentRpcTarget) { - borderColor = COLORS.WHITE; - } - if (opts.isLocalHost) { - borderColor = 'localhost'; - } - return ( {isCurrentRpcTarget ? ( @@ -192,15 +174,16 @@ class NetworkDropdown extends Component {
)} {nickname || rpcUrl} @@ -267,12 +250,14 @@ class NetworkDropdown extends Component { color={network} size={SIZES.LG} type={ColorIndicator.TYPES.FILLED} - borderColor={providerType === network ? COLORS.WHITE : network} /> {this.context.t(network)} @@ -323,7 +308,7 @@ class NetworkDropdown extends Component { zIndex: '55px', }} innerStyle={{ - padding: '18px 8px', + padding: '16px 0', }} >
@@ -345,12 +330,12 @@ class NetworkDropdown extends Component { {t('showHide')} , ])} - +
) : null}
diff --git a/ui/components/app/dropdowns/network-dropdown.test.js b/ui/components/app/dropdowns/network-dropdown.test.js index 7a0eaf3ef..1a963c9e8 100644 --- a/ui/components/app/dropdowns/network-dropdown.test.js +++ b/ui/components/app/dropdowns/network-dropdown.test.js @@ -76,7 +76,9 @@ describe('Network Dropdown', () => { let i = 1; let found = false; while (!found) { - if (_wrapper.find(ColorIndicator).at(i).prop('color') === 'ui-2') { + if ( + _wrapper.find(ColorIndicator).at(i).prop('color') === 'text-muted' + ) { i += 1; } else { found = true; @@ -94,14 +96,12 @@ describe('Network Dropdown', () => { it('checks background color for first ColorIndicator', () => { const colorIndicator = wrapper.find(ColorIndicator).at(0); expect(colorIndicator.prop('color')).toStrictEqual('mainnet'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('mainnet'); }); it('checks background color for second ColorIndicator', () => { // find where test networks start in case there are custom RPCs const colorIndicator = wrapper.find(ColorIndicator).at(testNetworkIndex); expect(colorIndicator.prop('color')).toStrictEqual('ropsten'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('ropsten'); }); it('checks background color for third ColorIndicator', () => { @@ -109,7 +109,6 @@ describe('Network Dropdown', () => { .find(ColorIndicator) .at(testNetworkIndex + 1); expect(colorIndicator.prop('color')).toStrictEqual('kovan'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('kovan'); }); it('checks background color for fourth ColorIndicator', () => { @@ -117,7 +116,6 @@ describe('Network Dropdown', () => { .find(ColorIndicator) .at(testNetworkIndex + 2); expect(colorIndicator.prop('color')).toStrictEqual('rinkeby'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('rinkeby'); }); it('checks background color for fifth ColorIndicator', () => { @@ -125,7 +123,6 @@ describe('Network Dropdown', () => { .find(ColorIndicator) .at(testNetworkIndex + 3); expect(colorIndicator.prop('color')).toStrictEqual('goerli'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('goerli'); }); it('checks background color for sixth ColorIndicator', () => { @@ -133,7 +130,6 @@ describe('Network Dropdown', () => { .find(ColorIndicator) .at(testNetworkIndex + 4); expect(colorIndicator.prop('color')).toStrictEqual('localhost'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('localhost'); expect( wrapper .find(DropdownMenuItem) @@ -186,7 +182,6 @@ describe('Network Dropdown', () => { it('checks background color for first ColorIndicator', () => { const colorIndicator = wrapper.find(ColorIndicator).at(0); expect(colorIndicator.prop('color')).toStrictEqual('mainnet'); - expect(colorIndicator.prop('borderColor')).toStrictEqual('mainnet'); expect(wrapper.find(DropdownMenuItem).at(0).text()).toStrictEqual( '✓mainnet', ); diff --git a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss index 86acf50ee..409de3744 100644 --- a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss +++ b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss @@ -1,7 +1,7 @@ .edit-gas-item { border-radius: 24px; - background: white; - color: var(--ui-4); + background: var(--color-background-default); + color: var(--color-text-alternative); cursor: pointer; font-size: 12px; display: flex; @@ -16,7 +16,7 @@ } &--selected { - background-color: var(--ui-1); + background-color: var(--color-background-alternative); } button.edit-gas-item--disabled[disabled] { @@ -27,7 +27,7 @@ &__name { display: inline-flex; align-items: center; - color: var(--ui-black); + color: var(--color-text-default); font-size: 12px; font-weight: bold; white-space: nowrap; @@ -78,7 +78,7 @@ &__time-estimate-low, &__fee-estimate-high { - color: var(--secondary-1); + color: var(--color-secondary-default); } &__time-estimate-medium, diff --git a/ui/components/app/menu-bar/index.scss b/ui/components/app/menu-bar/index.scss index 11f0b14da..1902a833d 100644 --- a/ui/components/app/menu-bar/index.scss +++ b/ui/components/app/menu-bar/index.scss @@ -3,7 +3,7 @@ grid-template-columns: 30% minmax(30%, 1fr) 30%; column-gap: 5px; padding: 0 8px; - border-bottom: 1px solid var(--Grey-100); + border-bottom: 1px solid var(--color-border-muted); height: 64px; .menu-bar__account-options { @@ -11,6 +11,7 @@ font-size: inherit; padding: 0 8px 0 5px; place-self: center end; + color: var(--color-text-default); } .selected-account { @@ -32,6 +33,6 @@ &__explorer-origin { @include H7; - color: var(--Grey-500); + color: var(--color-text-alternative); } } diff --git a/ui/components/app/modals/new-account-modal/index.scss b/ui/components/app/modals/new-account-modal/index.scss index de08a672c..02c8e29e1 100644 --- a/ui/components/app/modals/new-account-modal/index.scss +++ b/ui/components/app/modals/new-account-modal/index.scss @@ -1,7 +1,7 @@ .new-account-modal { display: flex; flex-flow: column nowrap; - background-color: var(--white); + background-color: var(--color-background-default); border-radius: 10px; box-shadow: 0 5px 16px rgba($black, 0.25); @@ -9,7 +9,7 @@ @extend %col-nowrap; padding: 1.5rem; - border-bottom: 1px solid var(--Grey-100); + border-bottom: 1px solid var(--color-border-muted); &__header { @include H4; @@ -29,22 +29,22 @@ } &__input-label { - color: var(--Grey-600); + color: var(--color-text-alternative); margin-top: 1.25rem; } &__input { @include H4; - background: var(--white); - border: 1px solid var(--Grey-100); + background: var(--color-background-default); + border: 1px solid var(--color-border-muted); box-sizing: border-box; border-radius: 8px; padding: 0.625rem 0.75rem; margin-top: 0.75rem; &::placeholder { - color: var(--Grey-300); + color: var(--color-text-muted); } } diff --git a/ui/components/app/selected-account/index.scss b/ui/components/app/selected-account/index.scss index cd5d39548..ab61b7721 100644 --- a/ui/components/app/selected-account/index.scss +++ b/ui/components/app/selected-account/index.scss @@ -14,7 +14,7 @@ width: 100%; font-weight: 500; - color: var(--black); + color: var(--color-text-default); text-overflow: ellipsis; overflow: hidden; white-space: nowrap; @@ -42,12 +42,9 @@ width: 100%; background-color: unset; - &:hover { - background-color: var(--Grey-000); - } - + &:hover, &:active { - background-color: #d9d7da; + background-color: var(--color-background-alternative); } } diff --git a/ui/components/app/signature-request-original/index.scss b/ui/components/app/signature-request-original/index.scss index da6d3512e..ce40fd424 100644 --- a/ui/components/app/signature-request-original/index.scss +++ b/ui/components/app/signature-request-original/index.scss @@ -2,7 +2,7 @@ &__container { width: 380px; border-radius: 8px; - background-color: var(--white); + background-color: var(--color-background-default); box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08); display: flex; flex-flow: column nowrap; @@ -76,7 +76,7 @@ &__header__tip { height: 25px; width: 25px; - background: var(--athens-grey); + background: var(--color-background-alternative); transform: rotate(45deg); position: absolute; bottom: -8px; @@ -103,7 +103,7 @@ @include H7; height: 22px; - background-color: var(--white); + background-color: var(--color-background-default); width: 124px; .account-list-item { diff --git a/ui/components/app/transaction-breakdown/index.scss b/ui/components/app/transaction-breakdown/index.scss index 75c6be56b..5bc00da50 100644 --- a/ui/components/app/transaction-breakdown/index.scss +++ b/ui/components/app/transaction-breakdown/index.scss @@ -5,7 +5,7 @@ padding-bottom: 4px; padding-top: 8px; font-size: 14px; - color: var(--Black-100); + color: var(--color-text-default); font-weight: bold; text-transform: capitalize; } @@ -23,12 +23,12 @@ &--eth-total { font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); } &--amount { font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); } } } diff --git a/ui/components/app/transaction-breakdown/transaction-breakdown-row/index.scss b/ui/components/app/transaction-breakdown/transaction-breakdown-row/index.scss index cb8c763a7..a39c73685 100644 --- a/ui/components/app/transaction-breakdown/transaction-breakdown-row/index.scss +++ b/ui/components/app/transaction-breakdown/transaction-breakdown-row/index.scss @@ -1,13 +1,13 @@ .transaction-breakdown-row { @include H7; - color: var(--Grey-500); + color: var(--color-text-alternative); display: flex; justify-content: space-between; padding: 8px 0; &--with-bottom-border { - border-bottom: 1px solid #d8d8d8; + border-bottom: 1px solid var(---color-border-muted); } &__title { diff --git a/ui/components/app/transaction-list-item-details/index.scss b/ui/components/app/transaction-list-item-details/index.scss index 1ac29436d..506b1bbdc 100644 --- a/ui/components/app/transaction-list-item-details/index.scss +++ b/ui/components/app/transaction-list-item-details/index.scss @@ -16,7 +16,7 @@ &__sender-to-recipient-header { display: flex; font-size: 14px; - color: var(--Black-100); + color: var(--color-text-default); font-weight: bold; padding-bottom: 7px; @@ -34,7 +34,7 @@ & > div:first-child { font-size: 14px; - color: var(--Black-100); + color: var(--color-text-default); font-weight: bold; } diff --git a/ui/components/app/transaction-list-item/index.scss b/ui/components/app/transaction-list-item/index.scss index 2a8e9d7d9..69413b1e1 100644 --- a/ui/components/app/transaction-list-item/index.scss +++ b/ui/components/app/transaction-list-item/index.scss @@ -1,6 +1,6 @@ .transaction-list-item { &__primary-currency { - color: var(--Black-100); + color: var(--color-text-default); overflow: hidden; text-overflow: ellipsis; } @@ -9,15 +9,15 @@ @include H7; margin-top: 4px; - color: var(--Grey-500); + color: var(--color-text-alternative); } & &--unconfirmed { - color: var(--Grey-500); + color: var(--color-text-alternative); } &--unconfirmed &__primary-currency { - color: var(--Grey-500); + color: var(--color-text-alternative); } &__pending-actions { diff --git a/ui/components/app/transaction-list/index.scss b/ui/components/app/transaction-list/index.scss index 431c4cc2b..ee932bc3b 100644 --- a/ui/components/app/transaction-list/index.scss +++ b/ui/components/app/transaction-list/index.scss @@ -13,8 +13,8 @@ @include H6; flex: 0 0 auto; - color: var(--Grey-400); - border-bottom: 1px solid var(--Grey-100); + color: var(--color-text-muted); + border-bottom: 1px solid var(--color-border-muted); padding: 8px 0 8px 20px; @media screen and (max-width: $break-small) { @@ -41,7 +41,7 @@ grid-row-start: 2; display: flex; justify-content: center; - color: var(--silver); + color: var(--color-text-muted); } &__view-more { diff --git a/ui/components/app/wallet-overview/index.scss b/ui/components/app/wallet-overview/index.scss index b99ad8ca6..43ef04d76 100644 --- a/ui/components/app/wallet-overview/index.scss +++ b/ui/components/app/wallet-overview/index.scss @@ -56,7 +56,7 @@ &__primary-balance { @include H2; - color: var(--black); + color: var(--color-text-default); width: 100%; justify-content: center; } @@ -67,19 +67,19 @@ &__cached-balance, &__cached-star { - color: var(--web-orange); + color: var(--color-secondary-default); } &__cached-secondary-balance { @include Paragraph; - color: rgba(220, 153, 18, 0.6901960784313725); + color: var(--color-secondary-muted); } &__secondary-balance { @include Paragraph; - color: var(--Grey-400); + color: var(--color-text-muted); } &__button { @@ -117,7 +117,7 @@ &__primary-balance { @include H2; - color: var(--black); + color: var(--color-text-default); width: 100%; justify-content: center; } @@ -125,7 +125,7 @@ &__secondary-balance { @include H5; - color: var(--Grey-400); + color: var(--color-text-muted); } &__button { diff --git a/ui/components/ui/list-item/index.scss b/ui/components/ui/list-item/index.scss index 243bd305a..3499ea299 100644 --- a/ui/components/ui/list-item/index.scss +++ b/ui/components/ui/list-item/index.scss @@ -2,14 +2,14 @@ width: 100%; min-height: 86px; margin: 0; - background: #fff; + background: var(--color-background-default); padding: 24px 16px; @include Paragraph; - border-top: 1px solid var(--mercury); - border-bottom: 1px solid var(--mercury); - color: var(--Black-100); + border-top: 1px solid var(--color-border-muted); + border-bottom: 1px solid var(--color-border-muted); + color: var(--color-text-default); display: grid; grid-template-columns: 0fr repeat(11, 1fr); grid-template-areas: @@ -21,7 +21,7 @@ &:hover, &:focus-within { - background-color: var(--Grey-000); + background-color: var(--color-background-alternative); } &__icon { @@ -67,7 +67,7 @@ @include H7; grid-area: sub; - color: var(--Grey-500); + color: var(--color-icon-default); margin-top: 4px; // all direct descendants should be truncated with ellipses // allows flexibility in consuming components to use h3/other tag @@ -86,7 +86,7 @@ @include H7; grid-area: mid; - color: var(--Grey-500); + color: var(--color-icon-default); } &__right-content { diff --git a/ui/components/ui/menu/menu.scss b/ui/components/ui/menu/menu.scss index c98738b09..c1f415c3e 100644 --- a/ui/components/ui/menu/menu.scss +++ b/ui/components/ui/menu/menu.scss @@ -2,11 +2,11 @@ &__container { @include H6; - background: var(--white); + background: var(--color-background-default); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.214); border-radius: 8px; width: 225px; - color: var(--Black-100); + color: var(--color-text-default); display: flex; flex-direction: column; align-items: center; @@ -38,7 +38,7 @@ &__icon { margin-right: 8px; grid-row: 1 / span 2; - color: var(--Grey-500); + color: var(--color-icon-default); } .disconnect-icon { diff --git a/ui/components/ui/nickname-popover/index.scss b/ui/components/ui/nickname-popover/index.scss index 9410cddd1..21ea6da34 100644 --- a/ui/components/ui/nickname-popover/index.scss +++ b/ui/components/ui/nickname-popover/index.scss @@ -2,7 +2,7 @@ &__popover-wrap { height: 232px; border-radius: 4px; - background: var(--ui-white); + background: var(--color-background-default); display: flex; justify-content: center; width: auto; @@ -23,7 +23,7 @@ font-weight: bold; display: flex; align-items: center; - color: var(--Black-100); + color: var(--color-text-default); padding-top: 8px; } @@ -34,7 +34,7 @@ flex-direction: row; align-items: center; min-height: 25px; - background: var(--Grey-000); + background: var(--color-background-alternative); border-radius: 40px; padding-left: 8px; padding-right: 2px; @@ -47,14 +47,14 @@ &__constant { @include H8; - color: var(--Grey-500); + color: var(--color-text-alternative); } } &__view-on-block-explorer { @include H7; - color: var(--primary-1); + color: var(--color-primary-default); margin-top: 12px; } @@ -69,6 +69,6 @@ width: 152px; height: 40px; border-radius: 100px; - background: var(--primary-1); + background: var(--color-primary-default); } } diff --git a/ui/components/ui/page-container/index.scss b/ui/components/ui/page-container/index.scss index 45f5f8854..33821275a 100644 --- a/ui/components/ui/page-container/index.scss +++ b/ui/components/ui/page-container/index.scss @@ -1,6 +1,6 @@ .page-container { width: 408px; - background-color: var(--white); + background-color: var(--color-background-default); box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); z-index: 25; display: flex; @@ -11,7 +11,7 @@ &__header { display: flex; flex-flow: column; - border-bottom: 1px solid var(--geyser); + border-bottom: 1px solid var(--color-border-muted); padding: 16px; flex: 0 0 auto; position: relative; @@ -22,7 +22,7 @@ } &__header-close { - color: var(--tundora); + color: var(--color-icon-default); position: absolute; top: 16px; right: 16px; @@ -54,7 +54,7 @@ display: flex; flex-flow: column; justify-content: center; - border-top: 1px solid var(--geyser); + border-top: 1px solid var(--color-border-muted); flex: 0 0 auto; footer { @@ -79,7 +79,7 @@ text-decoration: none; cursor: pointer; text-transform: uppercase; - color: #2f9ae0; + color: var(--color-primary-alternative); } } } @@ -102,7 +102,7 @@ &__title { @include H2; - color: var(--black); + color: var(--color-text-default); font-weight: 500; margin-right: 1.5rem; @@ -115,7 +115,7 @@ @include H6; padding-top: 0.5rem; - color: var(--gray); + color: var(--color-text-alternative); } &__tabs { @@ -127,7 +127,7 @@ @include Paragraph; min-width: 5rem; - color: var(--dusty-gray); + color: var(--color-text-alternative); border-bottom: none; margin-right: 16px; @@ -152,7 +152,7 @@ } &__warning-container { - background: var(--linen); + background: var(--color-warning-muted); padding: 20px; display: flex; align-items: start; @@ -193,7 +193,7 @@ .page-container { height: 100%; width: 100%; - background-color: var(--white); + background-color: var(--color-background-default); border-radius: 0; flex: 1; overflow-y: auto; diff --git a/ui/components/ui/popover/index.scss b/ui/components/ui/popover/index.scss index 9e0142075..35b170a44 100644 --- a/ui/components/ui/popover/index.scss +++ b/ui/components/ui/popover/index.scss @@ -7,7 +7,7 @@ ::-webkit-scrollbar-thumb { -webkit-border-radius: 10px; border-radius: 10px; - background: #c4c4c4; + background: var(--color-icon-muted); } display: flex; @@ -17,7 +17,7 @@ max-height: 94vh; box-shadow: 0 4px 30px rgba(0, 0, 0, 0.25); border-radius: 10px; - background: white; + background: var(--color-background-default); } &-header { @@ -56,6 +56,7 @@ background: none; font-size: inherit; padding: 0; + color: var(--color-icon-default); } i { @@ -90,7 +91,7 @@ } &-footer { - border-top: 1px solid #d2d8dd; + border-top: 1px solid var(--color-border-muted); > :only-child { margin: 0 auto; @@ -100,7 +101,7 @@ &-arrow { width: 22px; height: 22px; - background: white; + background: var(--color-background-default); position: absolute; transform: rotate(45deg); box-shadow: 0 4px 30px rgba(0, 0, 0, 0.25); diff --git a/ui/components/ui/tabs/index.scss b/ui/components/ui/tabs/index.scss index d65697096..fd579d15d 100644 --- a/ui/components/ui/tabs/index.scss +++ b/ui/components/ui/tabs/index.scss @@ -8,8 +8,8 @@ &__list { display: flex; justify-content: flex-start; - border-bottom: 1px solid var(--geyser); - background-color: var(--white); + border-bottom: 1px solid var(--color-border-default); + background-color: var(--color-background-default); position: sticky; top: 0; z-index: 1; diff --git a/ui/components/ui/tabs/tab/index.scss b/ui/components/ui/tabs/tab/index.scss index ba7460c64..0fba0aea0 100644 --- a/ui/components/ui/tabs/tab/index.scss +++ b/ui/components/ui/tabs/tab/index.scss @@ -12,7 +12,7 @@ } &--active { - color: var(--black); - border-bottom: 2px solid var(--primary-blue); + color: var(--color-text-default); + border-bottom: 2px solid var(--color-primary-default); } } diff --git a/ui/components/ui/update-nickname-popover/index.scss b/ui/components/ui/update-nickname-popover/index.scss index 650edf11d..a3684a68f 100644 --- a/ui/components/ui/update-nickname-popover/index.scss +++ b/ui/components/ui/update-nickname-popover/index.scss @@ -8,7 +8,7 @@ width: auto; .popover-header { - border-bottom: 1px solid #d2d8dd; + border-bottom: 1px solid var(--color-border-muted); margin-bottom: 16px; border-radius: 10px; } @@ -42,7 +42,7 @@ &__address { margin-top: 8px; font-size: 13px; - color: #bbc0c5; + color: var(--color-text-alternative); margin-bottom: 16px; overflow-wrap: break-word; } @@ -51,13 +51,13 @@ &__label--capitalized { text-transform: capitalize; margin-top: 16px; - color: #24292e; + color: var(--color-text-default); font-size: 14px; } &__nickname-label { margin-bottom: 8px; - color: #24292e; + color: var(--color-text-default); font-size: 14px; } } diff --git a/ui/css/base-styles.scss b/ui/css/base-styles.scss index 3ab475169..7e06d33ba 100644 --- a/ui/css/base-styles.scss +++ b/ui/css/base-styles.scss @@ -63,7 +63,7 @@ a { } a:hover { - color: var(--Blue-400); + color: var(--color-primary-alternative); } input.large-input, diff --git a/ui/css/itcss/components/network.scss b/ui/css/itcss/components/network.scss index 7c3c5f7f7..624a3b597 100644 --- a/ui/css/itcss/components/network.scss +++ b/ui/css/itcss/components/network.scss @@ -7,7 +7,7 @@ } .network-component.pointer { - border: 1px solid var(--Grey-200); + border: 1px solid var(--color-border-muted); border-radius: 82px; padding: 6px 3px; flex: 0 0 auto; @@ -46,6 +46,7 @@ } .dropdown-menu-item .fa.delete { + color: var(--color-icon-default); margin-right: 10px; display: none; } @@ -55,6 +56,8 @@ } .network-droppo { + background-color: var(--color-background-default); + border-radius: 4px; right: 2px; .color-indicator { @@ -76,7 +79,6 @@ .network-name-item { flex: 1; - color: var(--dusty-gray); text-overflow: ellipsis; overflow: hidden; white-space: nowrap; @@ -99,8 +101,8 @@ } .menu-icon-circle--active { - border: 1px solid var(--white); - background: rgba(100, 100, 100, 0.4); + border: 1px solid var(--color-border-default); + background: var(--color-background-default); } .menu-icon-circle div, @@ -131,7 +133,7 @@ width: 100%; height: 1px; margin: 10px 0; - background-color: var(--scorpion); + background-color: var(--color-border-default); } .network-dropdown-title { @@ -139,7 +141,7 @@ height: 25px; width: 120px; - color: var(--white); + color: var(--color-text-default); text-align: center; } @@ -148,26 +150,24 @@ min-height: 36px; width: 265px; - color: var(--dusty-gray); + color: var(--color-text-default); &--link { - color: var(--white); + color: var(--color-primary-default); cursor: pointer; text-decoration: underline; &:hover { - color: var(--white); + color: var(--color-primary-alternative); } } &--dismiss { - color: inherit; - background: inherit; position: absolute; top: 63px; right: 10px; - border: 1px solid var(--dusty-gray); - border-radius: 10px; + padding: 2px 8px; + width: auto; } } @@ -191,3 +191,7 @@ left: -6px; } } + +.network__add-network-button { + padding: 0 16px; +} diff --git a/ui/css/itcss/components/newui-sections.scss b/ui/css/itcss/components/newui-sections.scss index 7271c6a3b..284168093 100644 --- a/ui/css/itcss/components/newui-sections.scss +++ b/ui/css/itcss/components/newui-sections.scss @@ -22,7 +22,7 @@ $sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (ma left: 0; width: 1px; height: 1px; - background-color: var(--Grey-000); + background-color: var(--color-background-alternative); animation: emptySpinningDiv 1s infinite linear; } @@ -95,7 +95,7 @@ $sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (ma .main-container { width: 100%; overflow-y: auto; - background-color: var(--white); + background-color: var(--color-background-default); } .main-container-wrapper { @@ -140,7 +140,7 @@ $sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (ma justify-content: center; align-items: center; flex: 1 0 auto; - background: #f7f7f7; + background: var(--color-background-alternative); width: 100%; } @@ -158,5 +158,5 @@ $sub-mid-size-breakpoint-range: "screen and (min-width: #{$break-large}) and (ma height: 100%; justify-content: center; padding: 0 10px; - background: white; + background: var(--color-background-default); } diff --git a/ui/pages/asset/asset.scss b/ui/pages/asset/asset.scss index 3f69fdcd7..c717f9650 100644 --- a/ui/pages/asset/asset.scss +++ b/ui/pages/asset/asset.scss @@ -1,6 +1,6 @@ .asset { &__container { - background-color: white; + background-color: var(--color-background-default); } &__overview { @@ -19,7 +19,7 @@ .asset-breadcrumb { @include H6; - color: var(--Black-100); + color: var(--color-text-default); background-color: inherit; &__chevron { @@ -35,7 +35,7 @@ .asset-options { &__button { font-size: $font-size-paragraph; - color: var(--Black-100); + color: var(--color-text-default); background-color: inherit; padding: 2px 0 2px 8px; } diff --git a/ui/pages/create-account/index.scss b/ui/pages/create-account/index.scss index 0f01587a9..1b24822f5 100644 --- a/ui/pages/create-account/index.scss +++ b/ui/pages/create-account/index.scss @@ -3,7 +3,7 @@ .new-account { width: 375px; - background-color: #fff; + background-color: var(--color-background-default); box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); z-index: 25; height: unset; @@ -21,7 +21,7 @@ &__header { display: flex; flex-flow: column; - border-bottom: 1px solid var(--geyser); + border-bottom: 1px solid var(--color-border-muted); } &__title { @@ -43,19 +43,19 @@ height: 54px; padding: 15px 10px; - color: var(--dusty-gray); + color: var(--color-text-muted); text-align: center; cursor: pointer; } &__tab:hover { - color: var(--black); + color: var(--color-text-default); border-bottom: none; } &__selected { - color: var(--primary-blue); - border-bottom: 3px solid var(--primary-blue); + color: var(--color-primary-default); + border-bottom: 3px solid var(--color-primary-default); cursor: initial; pointer-events: none; } @@ -72,7 +72,7 @@ &__input-label { @include Paragraph; - color: var(--scorpion); + color: var(--color-text-alternative); align-self: flex-start; } @@ -81,15 +81,15 @@ height: 54px; width: 315.84px; - border: 1px solid var(--geyser); + border: 1px solid var(--color-border-muted); border-radius: 4px; - background-color: var(--white); - color: var(--scorpion); + background-color: var(--color-background-default); + color: var(--color-text-muted); margin-top: 15px; padding: 0 20px; &__error { - border: 1px solid var(--error-3); + border: 1px solid var(--color-error-alternative); } } @@ -97,7 +97,7 @@ @include H7; left: 8px; - color: var(--red); + color: var(--color-error-default); } &__error-amount { diff --git a/ui/pages/home/index.scss b/ui/pages/home/index.scss index 2625059c6..c184d0226 100644 --- a/ui/pages/home/index.scss +++ b/ui/pages/home/index.scss @@ -6,7 +6,7 @@ &__main-view { flex: 1 1 66.5%; - background: var(--white); + background: var(--color-background-default); min-width: 0; display: flex; flex-direction: column; @@ -30,12 +30,12 @@ @include H6; flex-grow: 1; - color: var(--Grey-500); + color: var(--color-icon-default); font-weight: 500; } &__main-view &__tab--active { - color: var(--Blue-500); + color: var(--color-primary-default); } &__main-view &__tab button { @@ -50,7 +50,7 @@ padding-left: 24px; padding-right: 24px; - color: var(--Grey-800); + color: var(--color-text-default); div { margin-bottom: 20px; @@ -103,7 +103,7 @@ a, a:hover { - color: var(--dodger-blue); + color: var(--color-primary-alternative); cursor: pointer; } } @@ -130,7 +130,7 @@ text-align: center; a { - color: var(--primary-1); + color: var(--color-primary-default); } } @@ -148,7 +148,7 @@ } &__close { - color: var(--ui-black); + color: var(--color-text-default); background: none; margin-left: 20px; } diff --git a/ui/pages/permissions-connect/index.scss b/ui/pages/permissions-connect/index.scss index 5921bee95..fc07dede8 100644 --- a/ui/pages/permissions-connect/index.scss +++ b/ui/pages/permissions-connect/index.scss @@ -6,7 +6,7 @@ width: 100%; height: 100%; position: relative; - background: white; + background: var(--color-background-default); display: flex; flex-direction: column; @@ -27,7 +27,7 @@ &__back { @include H7; - color: var(--Grey-500); + color: var(--color-text-default); font-weight: bold; cursor: pointer; @@ -39,7 +39,7 @@ &__page-count { @include H7; - color: var(--Grey-500); + color: var(--color-icon-default); grid-column: 2; justify-self: end; font-weight: bold; diff --git a/ui/pages/send/send.scss b/ui/pages/send/send.scss index bfc57a488..f2a508cac 100644 --- a/ui/pages/send/send.scss +++ b/ui/pages/send/send.scss @@ -5,7 +5,7 @@ position: relative; display: flex; justify-content: center; - background-color: var(--Grey-000); + background-color: var(--color-background-alternative); border-bottom: none; padding: 14px 0 3px 0; @@ -39,8 +39,8 @@ margin: 0; padding: 0.5rem; flex: 0 0 auto; - background-color: var(--Grey-000); - border-bottom: 1px solid var(--alto); + background-color: var(--color-background-alternative); + border-bottom: 1px solid var(--color-border-muted); } &__select-recipient-wrapper { @@ -58,7 +58,7 @@ @extend %row-nowrap; padding: 1rem; - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-muted); border-radius: 0; align-items: center; justify-content: flex-start; @@ -84,7 +84,7 @@ padding: 0.5rem; text-align: center; - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-muted); justify-content: flex-start; } } @@ -96,13 +96,13 @@ &__group-label { @include H8; - background-color: var(--Grey-000); - color: var(--Grey-600); + background-color: var(--color-background-alternative); + color: var(--color-text-alternative); padding: 0.5rem 1rem; - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-muted); &:first-of-type { - border-top: 1px solid var(--alto); + border-top: 1px solid var(--color-border-muted); } } @@ -112,7 +112,7 @@ padding: 0.75rem 1rem; align-items: center; - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-muted); cursor: pointer; &:hover { @@ -138,13 +138,13 @@ text-overflow: ellipsis; overflow: hidden; white-space: nowrap; - color: var(--black); + color: var(--color-text-default); } &__subtitle { @include H8; - color: var(--Grey-500); + color: var(--color-text-muted); } } @@ -164,14 +164,14 @@ flex: 1 1 auto; width: 0; align-items: center; - background: var(--white); + background: var(--color-background-default); border-radius: 0.5rem; padding: 0.75rem 0.5rem; - border: 1px solid var(--Grey-100); + border: 1px solid var(--color-border-muted); transition: border-color 150ms ease-in-out; &:focus-within { - border-color: var(--Grey-500); + border-color: var(--color-border-default); } &__status-icon { @@ -223,7 +223,7 @@ } &--valid { - border-color: var(--Blue-500); + border-color: var(--color-primary-default); .ens-input__wrapper { &__status-icon { @@ -235,7 +235,7 @@ @include H7; - color: var(--Blue-500); + color: var(--color-primary-default); } } } @@ -254,7 +254,7 @@ &__subtitle { @include H7; - color: var(--Grey-500); + color: var(--color-icon-default); margin-top: 0.25rem; } } diff --git a/ui/pages/settings/index.scss b/ui/pages/settings/index.scss index 42e53069b..f547ae53a 100644 --- a/ui/pages/settings/index.scss +++ b/ui/pages/settings/index.scss @@ -8,7 +8,7 @@ .settings-page { position: relative; - background: var(--white); + background: var(--color-background-default); display: flex; flex-flow: column nowrap; @@ -17,7 +17,7 @@ position: relative; @media screen and (max-width: $break-small) { - background: var(--ui-1); + background: var(--color-background-alternative); } &__title-container { @@ -33,7 +33,7 @@ &__close-button::after { content: '\00D7'; font-size: 40px; - color: var(--ui-4); + color: var(--color-icon-default); cursor: pointer; } @@ -68,7 +68,7 @@ } &__list { - background: var(--ui-white); + background: var(--color-background-default); box-sizing: border-box; box-shadow: 0 0 14px rgba(0, 0, 0, 0.18); border-radius: 6px; @@ -78,7 +78,7 @@ > div { &:hover { - background: var(--ui-1); + background: var(--color-background-alternative); } } @@ -87,13 +87,13 @@ display: grid; align-items: center; padding: 16px; - border-top: 1px solid var(--ui-2); + border-top: 1px solid var(--color-border-muted); cursor: pointer; grid-template-columns: 16px max-content 24px auto; gap: 8px; &__icon { - background: --ui-2; + background: var(--color-background-alternative); height: 15px; width: 15px; margin-right: 16px; @@ -105,7 +105,7 @@ &__no-matching { @include H6; - color: var(--ui-4); + color: var(--color-icon-default); } &__section-multiple-lines { @@ -124,7 +124,7 @@ @include H6; display: inline; - color: var(--primary-blue); + color: var(--color-primary-default); margin-left: 3px; } } @@ -137,7 +137,7 @@ @include H4; padding: 16px 4px; - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-muted); margin-right: 24px; height: 72px; align-items: center; @@ -156,7 +156,7 @@ &__subheader--link:hover { cursor: pointer; - color: var(--primary-blue); + color: var(--color-primary-default); } &__subheader--break { @@ -214,7 +214,7 @@ flex-flow: row nowrap; height: 100%; overflow: auto; - border-top: 1px solid #d8d8d8; + border-top: 1px solid var(--color-border-muted); &__tabs { display: flex; @@ -310,7 +310,7 @@ height: 40px; width: 40px; border-radius: 40px; - border: 2px solid #037dd6; + border: 2px solid var(--color-primary-default); display: flex; justify-content: center; align-items: center; @@ -324,7 +324,7 @@ margin-top: 8px; margin-bottom: 12px; - color: var(--dusty-gray); + color: var(--color-icon-default); } } @@ -335,11 +335,11 @@ &__content-description { @include H6; - color: var(--dusty-gray); + color: var(--color-icon-default); padding-top: 5px; a { - color: var(--Blue-500); + color: var(--color-primary-default); } } diff --git a/yarn.lock b/yarn.lock index 8bf1e85df..15b1f74f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2787,7 +2787,7 @@ web3 "^0.20.7" web3-provider-engine "^16.0.3" -"@metamask/design-tokens@^1.3.0": +"@metamask/design-tokens@^1.4.2": version "1.4.2" resolved "https://registry.yarnpkg.com/@metamask/design-tokens/-/design-tokens-1.4.2.tgz#023030f3eca181b10bf89c5813a9656f4e7e2852" integrity sha512-kS63Tx+WOUloBTz4pDDG3DcisoXwaT+06/a2KTSDI0n1t3IQPLo1FCMsijqtYWFPfAI06tWOjtaslpFTB+dsAg== From ce587a854587f285df111e1e315e38309c6af859 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Wed, 16 Mar 2022 17:05:34 +0100 Subject: [PATCH 019/192] Make Edit Gas Fee testcase independent of arbitrary Wait time for Gas Editing (#13888) * Added Wait for Element Containing certain value function and made more robust Edit-Gas-Fee test * Fix: changed wait for containing value and included extra waitforelements * Fix: fix lint issue --- test/e2e/tests/edit-gas-fee.spec.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/e2e/tests/edit-gas-fee.spec.js b/test/e2e/tests/edit-gas-fee.spec.js index f6898344b..6b79fcbd8 100644 --- a/test/e2e/tests/edit-gas-fee.spec.js +++ b/test/e2e/tests/edit-gas-fee.spec.js @@ -40,9 +40,11 @@ describe('Editing Confirm Transaction', function () { // update estimates to high await driver.clickElement('[data-testid="edit-gas-fee-button"]'); - await driver.delay(regularDelayMs); + await driver.waitForSelector({ + text: 'sec', + tag: 'span', + }); await driver.clickElement('[data-testid="edit-gas-fee-item-high"]'); - await driver.delay(regularDelayMs); await driver.waitForSelector({ text: '🦍' }); await driver.waitForSelector({ text: 'Aggressive', @@ -50,9 +52,7 @@ describe('Editing Confirm Transaction', function () { // update estimates to medium await driver.clickElement('[data-testid="edit-gas-fee-button"]'); - await driver.delay(regularDelayMs); await driver.clickElement('[data-testid="edit-gas-fee-item-medium"]'); - await driver.delay(regularDelayMs); await driver.waitForSelector({ text: '🦊' }); await driver.waitForSelector({ text: 'Market', @@ -60,9 +60,7 @@ describe('Editing Confirm Transaction', function () { // update estimates to low await driver.clickElement('[data-testid="edit-gas-fee-button"]'); - await driver.delay(regularDelayMs); await driver.clickElement('[data-testid="edit-gas-fee-item-low"]'); - await driver.delay(regularDelayMs); await driver.waitForSelector({ text: '🐢' }); await driver.waitForSelector({ text: 'Low', @@ -121,7 +119,10 @@ describe('Editing Confirm Transaction', function () { // update estimates to high await driver.clickElement('[data-testid="edit-gas-fee-button"]'); - await driver.delay(regularDelayMs); + await driver.waitForSelector({ + text: 'sec', + tag: 'span', + }); await driver.clickElement('[data-testid="edit-gas-fee-item-custom"]'); await driver.delay(regularDelayMs); @@ -231,7 +232,10 @@ describe('Editing Confirm Transaction', function () { }); await driver.clickElement('[data-testid="edit-gas-fee-button"]'); - await driver.delay(regularDelayMs); + await driver.waitForSelector({ + text: 'sec', + tag: 'span', + }); await driver.clickElement( '[data-testid="edit-gas-fee-item-dappSuggested"]', ); From 819878de68df8ff7322a1a3638014267f5d16886 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Wed, 16 Mar 2022 17:06:13 +0100 Subject: [PATCH 020/192] E2e Swap Api mockup response for suggestedGasFees (#13991) * Mock Suggested Gas Fees response * Included Option request mocked * Update suggestedGasFee mock response --- test/e2e/mock-e2e.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/e2e/mock-e2e.js b/test/e2e/mock-e2e.js index 012115e74..fa0d0b30f 100644 --- a/test/e2e/mock-e2e.js +++ b/test/e2e/mock-e2e.js @@ -20,6 +20,43 @@ async function setupMocking(server, testSpecificMock) { }; }); + await server + .forGet( + 'https://gas-api.metaswap.codefi.network/networks/1/suggestedGasFees', + ) + .thenCallback(() => { + return { + statusCode: 200, + json: { + low: { + suggestedMaxPriorityFeePerGas: '1', + suggestedMaxFeePerGas: '20.44436136', + minWaitTimeEstimate: 15000, + maxWaitTimeEstimate: 30000, + }, + medium: { + suggestedMaxPriorityFeePerGas: '1.5', + suggestedMaxFeePerGas: '25.80554517', + minWaitTimeEstimate: 15000, + maxWaitTimeEstimate: 45000, + }, + high: { + suggestedMaxPriorityFeePerGas: '2', + suggestedMaxFeePerGas: '27.277766977', + minWaitTimeEstimate: 15000, + maxWaitTimeEstimate: 60000, + }, + estimatedBaseFee: '19.444436136', + networkCongestion: 0.14685, + latestPriorityFeeRange: ['0.378818859', '6.555563864'], + historicalPriorityFeeRange: ['0.1', '248.262969261'], + historicalBaseFeeRange: ['14.146999781', '28.825256275'], + priorityFeeTrend: 'down', + baseFeeTrend: 'up', + }, + }; + }); + testSpecificMock(server); } From e2fd3f987f99f8ddcae98c8dafe37de7cf69a623 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Wed, 16 Mar 2022 18:37:50 +0100 Subject: [PATCH 021/192] Fix permission list shrinking with less text (#13996) * Fix permission list shrinking with text * Fix linting issue --- ui/components/app/permission-page-container/index.scss | 2 ++ .../app/permissions-connect-permission-list/index.scss | 3 +++ 2 files changed, 5 insertions(+) diff --git a/ui/components/app/permission-page-container/index.scss b/ui/components/app/permission-page-container/index.scss index aaf2753bd..5a087b18c 100644 --- a/ui/components/app/permission-page-container/index.scss +++ b/ui/components/app/permission-page-container/index.scss @@ -53,6 +53,7 @@ } &__requested { + width: 100%; text-align: left; } @@ -91,6 +92,7 @@ } &__permissions-container { + width: 100%; display: flex; flex-direction: column; margin-top: 38px; diff --git a/ui/components/app/permissions-connect-permission-list/index.scss b/ui/components/app/permissions-connect-permission-list/index.scss index adbe224b7..17be8eda6 100644 --- a/ui/components/app/permissions-connect-permission-list/index.scss +++ b/ui/components/app/permissions-connect-permission-list/index.scss @@ -1,7 +1,10 @@ .permissions-connect-permission-list { + width: 100%; + .permission { @include H6; + width: 100%; padding-bottom: 16px; border-bottom: 1px solid var(--Grey-100); display: flex; From 13e9a2a4798ef0dae888a2e1aec5daa09cbd94b5 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 14:03:10 -0500 Subject: [PATCH 022/192] Dark Mode: Update login screeen colors (#13992) --- ui/pages/unlock-page/index.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/pages/unlock-page/index.scss b/ui/pages/unlock-page/index.scss index 6d816a21f..8e3932715 100644 --- a/ui/pages/unlock-page/index.scss +++ b/ui/pages/unlock-page/index.scss @@ -6,10 +6,10 @@ width: 357px; padding: 30px; font-weight: 400; - color: var(--silver-chalice); + color: var(--color-text-default); &__container { - background: var(--white); + background: var(--color-background-default); display: flex; align-self: stretch; justify-content: center; @@ -25,7 +25,7 @@ margin-top: 5px; font-weight: 800; - color: var(--tundora); + color: var(--color-text-alternative); } &__form { @@ -50,7 +50,7 @@ font-size: 0.75rem; a { - color: var(--Blue-500); + color: var(--color-primary-default); } } } From 4807002a5ecced7b610cbd67a404fbace4f7e7cc Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 14:03:23 -0500 Subject: [PATCH 023/192] Dark Mode: Depost modal (#13989) --- .../app/modals/deposit-ether-modal/index.scss | 38 +------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/ui/components/app/modals/deposit-ether-modal/index.scss b/ui/components/app/modals/deposit-ether-modal/index.scss index 212c4a679..74e534d13 100644 --- a/ui/components/app/modals/deposit-ether-modal/index.scss +++ b/ui/components/app/modals/deposit-ether-modal/index.scss @@ -4,40 +4,6 @@ flex-flow: column; height: 100%; - &__header { - width: 100%; - border-radius: 8px 8px 0 0; - background-color: var(--mid-gray); - display: flex; - position: relative; - padding: 25px; - flex-flow: column; - align-items: flex-start; - - &__title { - @include H3; - - color: var(--white); - } - - &__description { - @include Paragraph; - - color: var(--white); - margin-top: 10px; - } - - &__close::after { - content: '\00D7'; - font-size: 2em; - color: var(--white); - position: absolute; - top: 20.8px; - right: 28px; - cursor: pointer; - } - } - &__buy-rows { width: 100%; padding: 0 30px; @@ -63,7 +29,7 @@ } &__buy-row { - border-bottom: 1px solid var(--alto); + border-bottom: 1px solid var(--color-border-default); display: flex; justify-content: space-between; align-items: center; @@ -105,7 +71,7 @@ } &__description { - color: var(--cape-cod); + color: var(--color-text-alternative); padding-bottom: 20px; align-self: flex-start; From 383a21f7359eb7660bf5925ca38fa64dbf672dd9 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 14:08:05 -0500 Subject: [PATCH 024/192] Dark Mode: Fix colors in threedot asset menu (#13990) --- ui/components/ui/menu/menu.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/components/ui/menu/menu.scss b/ui/components/ui/menu/menu.scss index c1f415c3e..ad43434c0 100644 --- a/ui/components/ui/menu/menu.scss +++ b/ui/components/ui/menu/menu.scss @@ -34,6 +34,7 @@ width: 100%; padding: 14px 0; cursor: pointer; + color: inherit; &__icon { margin-right: 8px; From 13bb4662a83fd2bb051081e7a585c67fb81cd656 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Wed, 16 Mar 2022 19:13:21 -0230 Subject: [PATCH 025/192] Add `pasteIntoField` webdriver method (#14004) A new method has been added to the e2e webdriver for pasting text into a field. This will be required to properly test a change to the SRP input, which will be coming in a separate PR. A few existing e2e tests have been updated to use this method to input the SRP, to show that it works properly. --- test/e2e/helpers.js | 2 +- test/e2e/metamask-ui.spec.js | 3 +-- test/e2e/tests/add-account.spec.js | 3 +-- test/e2e/tests/metamask-responsive-ui.spec.js | 2 +- test/e2e/webdriver/driver.js | 22 ++++++++++++++++++- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js index fc4b1d8db..89e5491aa 100644 --- a/test/e2e/helpers.js +++ b/test/e2e/helpers.js @@ -226,7 +226,7 @@ const completeImportSRPOnboardingFlow = async ( await driver.clickElement('.btn-secondary'); // Import Secret Recovery Phrase - await driver.fill( + await driver.pasteIntoField( 'input[placeholder="Enter your Secret Recovery Phrase"]', seedPhrase, ); diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index 30ca8d43b..01a3a9cac 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -202,11 +202,10 @@ describe('MetaMask', function () { await restoreSeedLink.click(); await driver.delay(regularDelayMs); - await driver.fill( + await driver.pasteIntoField( 'input[placeholder="Enter your Secret Recovery Phrase"]', testSeedPhrase, ); - await driver.delay(regularDelayMs); await driver.fill('#password', 'correct horse battery staple'); await driver.fill('#confirm-password', 'correct horse battery staple'); diff --git a/test/e2e/tests/add-account.spec.js b/test/e2e/tests/add-account.spec.js index 5c0d3fcb9..f9318cc7f 100644 --- a/test/e2e/tests/add-account.spec.js +++ b/test/e2e/tests/add-account.spec.js @@ -129,11 +129,10 @@ describe('Add account', function () { await restoreSeedLink.click(); await driver.delay(regularDelayMs); - await driver.fill( + await driver.pasteIntoField( 'input[placeholder="Enter your Secret Recovery Phrase"]', testSeedPhrase, ); - await driver.delay(regularDelayMs); await driver.fill('#password', 'correct horse battery staple'); await driver.fill('#confirm-password', 'correct horse battery staple'); diff --git a/test/e2e/tests/metamask-responsive-ui.spec.js b/test/e2e/tests/metamask-responsive-ui.spec.js index e01e5b307..38f1f350f 100644 --- a/test/e2e/tests/metamask-responsive-ui.spec.js +++ b/test/e2e/tests/metamask-responsive-ui.spec.js @@ -169,7 +169,7 @@ describe('Metamask Responsive UI', function () { assert.equal(await restoreSeedLink.getText(), 'Forgot password?'); await restoreSeedLink.click(); - await driver.fill( + await driver.pasteIntoField( 'input[placeholder="Enter your Secret Recovery Phrase"]', testSeedPhrase, ); diff --git a/test/e2e/webdriver/driver.js b/test/e2e/webdriver/driver.js index 84342ae69..8f23f3cdc 100644 --- a/test/e2e/webdriver/driver.js +++ b/test/e2e/webdriver/driver.js @@ -1,6 +1,6 @@ const { promises: fs } = require('fs'); const { strict: assert } = require('assert'); -const { until, error: webdriverError, By } = require('selenium-webdriver'); +const { until, error: webdriverError, By, Key } = require('selenium-webdriver'); const cssToXPath = require('css-to-xpath'); /** @@ -257,6 +257,26 @@ class Driver { } } + /** + * Paste a string into a field. + * + * @param {string} element - The element locator. + * @param {string} contentToPaste - The content to paste. + */ + async pasteIntoField(element, contentToPaste) { + // Throw if double-quote is present in content to paste + // so that we don't have to worry about escaping double-quotes + if (contentToPaste.includes('"')) { + throw new Error('Cannot paste content with double-quote'); + } + // Click to focus the field + await this.clickElement(element); + await this.executeScript( + `navigator.clipboard.writeText("${contentToPaste}")`, + ); + await this.fill(element, Key.chord(Key.CONTROL, 'v')); + } + // Navigation async navigate(page = Driver.PAGES.HOME) { From 116d6b0eb8ee4baef9cfb8ae3b1a898e0a7bb896 Mon Sep 17 00:00:00 2001 From: Brad Decker Date: Wed, 16 Mar 2022 17:15:03 -0500 Subject: [PATCH 026/192] add asset_type to transactions (#13858) --- app/scripts/controllers/transactions/index.js | 10 +++ .../controllers/transactions/index.test.js | 16 ++++ app/scripts/metamask-controller.js | 3 + shared/constants/transaction.js | 15 ++++ shared/modules/transaction.utils.js | 86 ++++++++++++++++++- .../app/asset-list-item/asset-list-item.js | 3 +- .../collectible-details.js | 3 +- ...gas-modal-page-container-container.test.js | 4 +- .../gas-modal-page-container.container.js | 6 +- .../app/wallet-overview/token-overview.js | 3 +- ui/contexts/metametrics.js | 3 +- ui/ducks/send/send.js | 17 +--- ui/ducks/send/send.test.js | 2 +- ui/helpers/constants/common.js | 7 ++ .../confirm-send-ether.container.js | 3 +- .../confirm-send-token.container.js | 3 +- .../confirm-send-token/confirm-send-token.js | 3 +- .../send-amount-row.component.js | 2 +- .../send-amount-row.component.test.js | 2 +- .../send-asset-row.component.js | 2 +- .../send-content/send-content.component.js | 2 +- .../send/send-header/send-header.component.js | 2 +- .../send-header/send-header.component.test.js | 3 +- 23 files changed, 169 insertions(+), 31 deletions(-) diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index 24fb0cf78..3310b38d2 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -46,6 +46,7 @@ import { CHAIN_ID_TO_GAS_LIMIT_BUFFER_MAP, } from '../../../../shared/constants/network'; import { + determineTransactionAssetType, determineTransactionType, isEIP1559Transaction, } from '../../../../shared/modules/transaction.utils'; @@ -130,6 +131,7 @@ export default class TransactionController extends EventEmitter { this.getEventFragmentById = opts.getEventFragmentById; this.getDeviceModel = opts.getDeviceModel; this.getAccountType = opts.getAccountType; + this.getTokenStandardAndDetails = opts.getTokenStandardAndDetails; this.memStore = new ObservableStore({}); this.query = new EthQuery(this.provider); @@ -1833,6 +1835,12 @@ export default class TransactionController extends EventEmitter { } = txMeta; const source = referrer === 'metamask' ? 'user' : 'dapp'; + const { assetType, tokenStandard } = await determineTransactionAssetType( + txMeta, + this.query, + this.getTokenStandardAndDetails, + ); + const gasParams = {}; if (isEIP1559Transaction(txMeta)) { @@ -1906,6 +1914,8 @@ export default class TransactionController extends EventEmitter { gas_edit_attempted: 'none', account_type: await this.getAccountType(this.getSelectedAddress()), device_model: await this.getDeviceModel(this.getSelectedAddress()), + asset_type: assetType, + token_standard: tokenStandard, }; const sensitiveProperties = { diff --git a/app/scripts/controllers/transactions/index.test.js b/app/scripts/controllers/transactions/index.test.js index 7ebcde2b0..def07386e 100644 --- a/app/scripts/controllers/transactions/index.test.js +++ b/app/scripts/controllers/transactions/index.test.js @@ -15,6 +15,7 @@ import { TRANSACTION_TYPES, TRANSACTION_ENVELOPE_TYPES, TRANSACTION_EVENTS, + ASSET_TYPES, } from '../../../../shared/constants/transaction'; import { SECOND } from '../../../../shared/constants/time'; @@ -24,6 +25,7 @@ import { } from '../../../../shared/constants/gas'; import { TRANSACTION_ENVELOPE_TYPE_NAMES } from '../../../../ui/helpers/constants/transactions'; import { METAMASK_CONTROLLER_EVENTS } from '../../metamask-controller'; +import { TOKEN_STANDARDS } from '../../../../ui/helpers/constants/common'; import TransactionController from '.'; const noop = () => true; @@ -1469,6 +1471,8 @@ describe('Transaction Controller', function () { source: 'user', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1546,6 +1550,8 @@ describe('Transaction Controller', function () { source: 'user', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1633,6 +1639,8 @@ describe('Transaction Controller', function () { source: 'dapp', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1712,6 +1720,8 @@ describe('Transaction Controller', function () { source: 'dapp', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1791,6 +1801,8 @@ describe('Transaction Controller', function () { source: 'dapp', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1852,6 +1864,8 @@ describe('Transaction Controller', function () { gas_edit_attempted: 'none', gas_edit_type: 'none', account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { @@ -1923,6 +1937,8 @@ describe('Transaction Controller', function () { source: 'dapp', type: TRANSACTION_TYPES.SIMPLE_SEND, account_type: 'MetaMask', + asset_type: ASSET_TYPES.NATIVE, + token_standard: TOKEN_STANDARDS.NONE, device_model: 'N/A', }, sensitiveProperties: { diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 8297a21fe..1f4441c2e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -717,6 +717,9 @@ export default class MetamaskController extends EventEmitter { ), getAccountType: this.getAccountType.bind(this), getDeviceModel: this.getDeviceModel.bind(this), + getTokenStandardAndDetails: this.assetsContractController.getTokenStandardAndDetails.bind( + this.assetsContractController, + ), }); this.txController.on('newUnapprovedTx', () => opts.showUserConfirmation()); diff --git a/shared/constants/transaction.js b/shared/constants/transaction.js index 8ac9defc1..b1ea01c39 100644 --- a/shared/constants/transaction.js +++ b/shared/constants/transaction.js @@ -305,3 +305,18 @@ export const TRANSACTION_EVENTS = { REJECTED: 'Transaction Rejected', SUBMITTED: 'Transaction Submitted', }; + +/** + * The types of assets that a user can send + * 1. NATIVE - The native asset for the current network, such as ETH + * 2. TOKEN - An ERC20 token. + * 3. COLLECTIBLE - An ERC721 or ERC1155 token. + * 4. UNKNOWN - A transaction interacting with a contract that isn't a token + * method interaction will be marked as dealing with an unknown asset type. + */ +export const ASSET_TYPES = { + NATIVE: 'NATIVE', + TOKEN: 'TOKEN', + COLLECTIBLE: 'COLLECTIBLE', + UNKNOWN: 'UNKNOWN', +}; diff --git a/shared/modules/transaction.utils.js b/shared/modules/transaction.utils.js index 8995b6c02..e79e569c3 100644 --- a/shared/modules/transaction.utils.js +++ b/shared/modules/transaction.utils.js @@ -2,7 +2,8 @@ import { isHexString } from 'ethereumjs-util'; import { ethers } from 'ethers'; import abi from 'human-standard-token-abi'; import log from 'loglevel'; -import { TRANSACTION_TYPES } from '../constants/transaction'; +import { TOKEN_STANDARDS } from '../../ui/helpers/constants/common'; +import { ASSET_TYPES, TRANSACTION_TYPES } from '../constants/transaction'; import { readAddressAsContract } from './contract-utils'; import { isEqualCaseInsensitive } from './string-utils'; @@ -131,3 +132,86 @@ export async function determineTransactionType(txParams, query) { return { type: result, getCodeResponse: contractCode }; } + +const INFERRABLE_TRANSACTION_TYPES = [ + TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + TRANSACTION_TYPES.CONTRACT_INTERACTION, + TRANSACTION_TYPES.SIMPLE_SEND, +]; + +/** + * Given a transaction meta object, determine the asset type that the + * transaction is dealing with, as well as the standard for the token if it + * is a token transaction. + * + * @param {import('../constants/transaction').TransactionMeta} txMeta - + * transaction meta object + * @param {EthQuery} query - EthQuery instance + * @param {Function} getTokenStandardAndDetails - function to get token + * standards and details. + * @returns {{ assetType: string, tokenStandard: string}} + */ +export async function determineTransactionAssetType( + txMeta, + query, + getTokenStandardAndDetails, +) { + // If the transaction type is already one of the inferrable types, then we do + // not need to re-establish the type. + let inferrableType = txMeta.type; + if (INFERRABLE_TRANSACTION_TYPES.includes(txMeta.type) === false) { + // Because we will deal with all types of transactions (including swaps) + // we want to get an inferrable type of transaction that isn't special cased + // that way we can narrow the number of logic gates required. + const result = await determineTransactionType(txMeta.txParams, query); + inferrableType = result.type; + } + + // If the inferred type of the transaction is one of those that are part of + // the token contract standards, we can use the getTokenStandardAndDetails + // method to get the asset type. + const isTokenMethod = [ + TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, + TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + ].find((methodName) => methodName === inferrableType); + + if ( + isTokenMethod || + // We can also check any contract interaction type to see if the to address + // is a token contract. If it isn't, then the method will throw and we can + // fall through to the other checks. + inferrableType === TRANSACTION_TYPES.CONTRACT_INTERACTION + ) { + try { + // We don't need a balance check, so the second parameter to + // getTokenStandardAndDetails is omitted. + const details = await getTokenStandardAndDetails(txMeta.txParams.to); + if (details.standard) { + return { + assetType: + details.standard === TOKEN_STANDARDS.ERC20 + ? ASSET_TYPES.TOKEN + : ASSET_TYPES.COLLECTIBLE, + tokenStandard: details.standard, + }; + } + } catch { + // noop, We expect errors here but we don't need to report them or do + // anything in response. + } + } + + // If the transaction is interacting with a contract but isn't a token method + // we use the 'UNKNOWN' value to show that it isn't a transaction sending any + // particular asset. + if (inferrableType === TRANSACTION_TYPES.CONTRACT_INTERACTION) { + return { + assetType: ASSET_TYPES.UNKNOWN, + tokenStandard: TOKEN_STANDARDS.NONE, + }; + } + return { assetType: ASSET_TYPES.NATIVE, tokenStandard: TOKEN_STANDARDS.NONE }; +} diff --git a/ui/components/app/asset-list-item/asset-list-item.js b/ui/components/app/asset-list-item/asset-list-item.js index 2badb8bb4..8b743ac7a 100644 --- a/ui/components/app/asset-list-item/asset-list-item.js +++ b/ui/components/app/asset-list-item/asset-list-item.js @@ -9,10 +9,11 @@ import Tooltip from '../../ui/tooltip'; import InfoIcon from '../../ui/icon/info-icon.component'; import Button from '../../ui/button'; import { useI18nContext } from '../../../hooks/useI18nContext'; -import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send'; +import { updateSendAsset } from '../../../ducks/send'; import { SEND_ROUTE } from '../../../helpers/constants/routes'; import { SEVERITIES } from '../../../helpers/constants/design-system'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; const AssetListItem = ({ diff --git a/ui/components/app/collectible-details/collectible-details.js b/ui/components/app/collectible-details/collectible-details.js index be538d852..0207f0cef 100644 --- a/ui/components/app/collectible-details/collectible-details.js +++ b/ui/components/app/collectible-details/collectible-details.js @@ -45,12 +45,13 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util'; import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app'; import CollectibleOptions from '../collectible-options/collectible-options'; import Button from '../../ui/button'; -import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send'; +import { updateSendAsset } from '../../../ducks/send'; import InfoTooltip from '../../ui/info-tooltip'; import { ERC721 } from '../../../helpers/constants/common'; import { usePrevious } from '../../../hooks/usePrevious'; import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard'; import { isEqualCaseInsensitive } from '../../../../shared/modules/string-utils'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; export default function CollectibleDetails({ collectible }) { const { diff --git a/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js b/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js index 52f2b0fb4..ef78b166a 100644 --- a/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js +++ b/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container-container.test.js @@ -60,7 +60,9 @@ jest.mock('../../../../ducks/gas/gas.duck', () => ({ })); jest.mock('../../../../ducks/send', () => { - const { ASSET_TYPES } = jest.requireActual('../../../../ducks/send'); + const { ASSET_TYPES } = jest.requireActual( + '../../../../../shared/constants/transaction', + ); return { useCustomGas: jest.fn(), updateGasLimit: jest.fn(), diff --git a/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 3d77f1214..37540c8df 100644 --- a/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -19,7 +19,6 @@ import { updateGasPrice, useCustomGas, getSendAsset, - ASSET_TYPES, } from '../../../../ducks/send'; import { conversionRateSelector as getConversionRate, @@ -54,7 +53,10 @@ import { isBalanceSufficient, } from '../../../../pages/send/send.utils'; import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; -import { TRANSACTION_STATUSES } from '../../../../../shared/constants/transaction'; +import { + ASSET_TYPES, + TRANSACTION_STATUSES, +} from '../../../../../shared/constants/transaction'; import { GAS_LIMITS } from '../../../../../shared/constants/gas'; import { updateTransactionGasFees } from '../../../../ducks/metamask/metamask'; import GasModalPageContainer from './gas-modal-page-container.component'; diff --git a/ui/components/app/wallet-overview/token-overview.js b/ui/components/app/wallet-overview/token-overview.js index 0f4baf3ce..a9b76cd13 100644 --- a/ui/components/app/wallet-overview/token-overview.js +++ b/ui/components/app/wallet-overview/token-overview.js @@ -15,7 +15,7 @@ import { import { useNewMetricEvent } from '../../../hooks/useMetricEvent'; import { useTokenTracker } from '../../../hooks/useTokenTracker'; import { useTokenFiatAmount } from '../../../hooks/useTokenFiatAmount'; -import { ASSET_TYPES, updateSendAsset } from '../../../ducks/send'; +import { updateSendAsset } from '../../../ducks/send'; import { setSwapsFromToken } from '../../../ducks/swaps/swaps'; import { getCurrentKeyring, @@ -29,6 +29,7 @@ import IconButton from '../../ui/icon-button'; import { INVALID_ASSET_TYPE } from '../../../helpers/constants/error-keys'; import { showModal } from '../../../store/actions'; import { MetaMetricsContext } from '../../../contexts/metametrics.new'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; import WalletOverview from './wallet-overview'; const TokenOverview = ({ className, token }) => { diff --git a/ui/contexts/metametrics.js b/ui/contexts/metametrics.js index bb23afef8..869cb84e2 100644 --- a/ui/contexts/metametrics.js +++ b/ui/contexts/metametrics.js @@ -15,11 +15,12 @@ import { getNumberOfAccounts, getNumberOfTokens, } from '../selectors/selectors'; -import { getSendAsset, ASSET_TYPES } from '../ducks/send'; +import { getSendAsset } from '../ducks/send'; import { txDataSelector } from '../selectors/confirm-transaction'; import { getEnvironmentType } from '../../app/scripts/lib/util'; import { trackMetaMetricsEvent } from '../store/actions'; import { getNativeCurrency } from '../ducks/metamask/metamask'; +import { ASSET_TYPES } from '../../shared/constants/transaction'; export const MetaMetricsContext = createContext(() => { captureException( diff --git a/ui/ducks/send/send.js b/ui/ducks/send/send.js index d4b4c1084..3a0f07c2e 100644 --- a/ui/ducks/send/send.js +++ b/ui/ducks/send/send.js @@ -99,7 +99,10 @@ import { ETH, GWEI, } from '../../helpers/constants/common'; -import { TRANSACTION_ENVELOPE_TYPES } from '../../../shared/constants/transaction'; +import { + ASSET_TYPES, + TRANSACTION_ENVELOPE_TYPES, +} from '../../../shared/constants/transaction'; import { readAddressAsContract } from '../../../shared/modules/contract-utils'; import { INVALID_ASSET_TYPE } from '../../helpers/constants/error-keys'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; @@ -164,18 +167,6 @@ export const GAS_INPUT_MODES = { CUSTOM: 'CUSTOM', }; -/** - * The types of assets that a user can send - * 1. NATIVE - The native asset for the current network, such as ETH - * 2. TOKEN - An ERC20 token. - * 2. COLLECTIBLE - An ERC721 or ERC1155 token. - */ -export const ASSET_TYPES = { - NATIVE: 'NATIVE', - TOKEN: 'TOKEN', - COLLECTIBLE: 'COLLECTIBLE', -}; - /** * The modes that the amount field can be set by * 1. INPUT - the user provides the amount by typing in the field diff --git a/ui/ducks/send/send.test.js b/ui/ducks/send/send.test.js index 8e901b9dc..98f4fb794 100644 --- a/ui/ducks/send/send.test.js +++ b/ui/ducks/send/send.test.js @@ -16,6 +16,7 @@ import { } from '../../../shared/constants/network'; import { GAS_ESTIMATE_TYPES, GAS_LIMITS } from '../../../shared/constants/gas'; import { + ASSET_TYPES, TRANSACTION_ENVELOPE_TYPES, TRANSACTION_TYPES, } from '../../../shared/constants/transaction'; @@ -34,7 +35,6 @@ import sendReducer, { toggleSendMaxMode, signTransaction, SEND_STATUSES, - ASSET_TYPES, SEND_STAGES, AMOUNT_MODES, RECIPIENT_SEARCH_MODES, diff --git a/ui/helpers/constants/common.js b/ui/helpers/constants/common.js index b62e053f1..3deae2356 100644 --- a/ui/helpers/constants/common.js +++ b/ui/helpers/constants/common.js @@ -9,6 +9,13 @@ export const ERC20 = 'ERC20'; export const ERC721 = 'ERC721'; export const ERC1155 = 'ERC1155'; +export const TOKEN_STANDARDS = { + ERC20, + ERC721, + ERC1155, + NONE: 'NONE', +}; + export const GAS_ESTIMATE_TYPES = { SLOW: 'SLOW', AVERAGE: 'AVERAGE', diff --git a/ui/pages/confirm-send-ether/confirm-send-ether.container.js b/ui/pages/confirm-send-ether/confirm-send-ether.container.js index a637fbb12..eb794b6ce 100644 --- a/ui/pages/confirm-send-ether/confirm-send-ether.container.js +++ b/ui/pages/confirm-send-ether/confirm-send-ether.container.js @@ -1,8 +1,9 @@ import { connect } from 'react-redux'; import { compose } from 'redux'; import { withRouter } from 'react-router-dom'; -import { ASSET_TYPES, editTransaction } from '../../ducks/send'; +import { editTransaction } from '../../ducks/send'; import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; +import { ASSET_TYPES } from '../../../shared/constants/transaction'; import ConfirmSendEther from './confirm-send-ether.component'; const mapStateToProps = (state) => { diff --git a/ui/pages/confirm-send-token/confirm-send-token.container.js b/ui/pages/confirm-send-token/confirm-send-token.container.js index d823e25aa..d8a498424 100644 --- a/ui/pages/confirm-send-token/confirm-send-token.container.js +++ b/ui/pages/confirm-send-token/confirm-send-token.container.js @@ -3,8 +3,9 @@ import { compose } from 'redux'; import { withRouter } from 'react-router-dom'; import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; import { showSendTokenPage } from '../../store/actions'; -import { ASSET_TYPES, editTransaction } from '../../ducks/send'; +import { editTransaction } from '../../ducks/send'; import { sendTokenTokenAmountAndToAddressSelector } from '../../selectors'; +import { ASSET_TYPES } from '../../../shared/constants/transaction'; import ConfirmSendToken from './confirm-send-token.component'; const mapStateToProps = (state) => { diff --git a/ui/pages/confirm-send-token/confirm-send-token.js b/ui/pages/confirm-send-token/confirm-send-token.js index a03fb9835..8d40d36c9 100644 --- a/ui/pages/confirm-send-token/confirm-send-token.js +++ b/ui/pages/confirm-send-token/confirm-send-token.js @@ -4,7 +4,7 @@ import { useDispatch, useSelector } from 'react-redux'; import { useHistory } from 'react-router-dom'; import ConfirmTokenTransactionBase from '../confirm-token-transaction-base/confirm-token-transaction-base'; import { SEND_ROUTE } from '../../helpers/constants/routes'; -import { ASSET_TYPES, editTransaction } from '../../ducks/send'; +import { editTransaction } from '../../ducks/send'; import { contractExchangeRateSelector, getCurrentCurrency, @@ -16,6 +16,7 @@ import { import { ERC20, ERC721 } from '../../helpers/constants/common'; import { clearConfirmTransaction } from '../../ducks/confirm-transaction/confirm-transaction.duck'; import { showSendTokenPage } from '../../store/actions'; +import { ASSET_TYPES } from '../../../shared/constants/transaction'; export default function ConfirmSendToken({ assetStandard, diff --git a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js index 711437e46..469cf1174 100644 --- a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js +++ b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import SendRowWrapper from '../send-row-wrapper'; import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input'; import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input'; -import { ASSET_TYPES } from '../../../../ducks/send'; +import { ASSET_TYPES } from '../../../../../shared/constants/transaction'; import AmountMaxButton from './amount-max-button'; export default class SendAmountRow extends Component { diff --git a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.test.js b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.test.js index c6e8e23be..21d7db8f3 100644 --- a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.test.js +++ b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.test.js @@ -3,7 +3,7 @@ import { shallow } from 'enzyme'; import sinon from 'sinon'; import SendRowWrapper from '../send-row-wrapper/send-row-wrapper.component'; import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input'; -import { ASSET_TYPES } from '../../../../ducks/send'; +import { ASSET_TYPES } from '../../../../../shared/constants/transaction'; import SendAmountRow from './send-amount-row.component'; import AmountMaxButton from './amount-max-button/amount-max-button'; diff --git a/ui/pages/send/send-content/send-asset-row/send-asset-row.component.js b/ui/pages/send/send-content/send-asset-row/send-asset-row.component.js index 34b77eff2..351f3024f 100644 --- a/ui/pages/send/send-content/send-asset-row/send-asset-row.component.js +++ b/ui/pages/send/send-content/send-asset-row/send-asset-row.component.js @@ -6,8 +6,8 @@ import TokenBalance from '../../../../components/ui/token-balance'; import TokenListDisplay from '../../../../components/app/token-list-display'; import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'; import { ERC20, ERC721, PRIMARY } from '../../../../helpers/constants/common'; -import { ASSET_TYPES } from '../../../../ducks/send'; import { isEqualCaseInsensitive } from '../../../../../shared/modules/string-utils'; +import { ASSET_TYPES } from '../../../../../shared/constants/transaction'; export default class SendAssetRow extends Component { static propTypes = { diff --git a/ui/pages/send/send-content/send-content.component.js b/ui/pages/send/send-content/send-content.component.js index dca6d4a91..3b54b4a78 100644 --- a/ui/pages/send/send-content/send-content.component.js +++ b/ui/pages/send/send-content/send-content.component.js @@ -9,7 +9,7 @@ import { GAS_PRICE_EXCESSIVE_ERROR_KEY, INSUFFICIENT_FUNDS_FOR_GAS_ERROR_KEY, } from '../../../helpers/constants/error-keys'; -import { ASSET_TYPES } from '../../../ducks/send'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; import SendAmountRow from './send-amount-row'; import SendHexDataRow from './send-hex-data-row'; import SendAssetRow from './send-asset-row'; diff --git a/ui/pages/send/send-header/send-header.component.js b/ui/pages/send/send-header/send-header.component.js index b89816656..f4528a6c4 100644 --- a/ui/pages/send/send-header/send-header.component.js +++ b/ui/pages/send/send-header/send-header.component.js @@ -5,12 +5,12 @@ import PageContainerHeader from '../../../components/ui/page-container/page-cont import { getMostRecentOverviewPage } from '../../../ducks/history/history'; import { useI18nContext } from '../../../hooks/useI18nContext'; import { - ASSET_TYPES, getSendAsset, getSendStage, resetSendState, SEND_STAGES, } from '../../../ducks/send'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; export default function SendHeader() { const history = useHistory(); diff --git a/ui/pages/send/send-header/send-header.component.test.js b/ui/pages/send/send-header/send-header.component.test.js index c718018cb..5ec8bdc69 100644 --- a/ui/pages/send/send-header/send-header.component.test.js +++ b/ui/pages/send/send-header/send-header.component.test.js @@ -3,8 +3,9 @@ import configureMockStore from 'redux-mock-store'; import thunk from 'redux-thunk'; import { fireEvent } from '@testing-library/react'; -import { ASSET_TYPES, initialState, SEND_STAGES } from '../../../ducks/send'; +import { initialState, SEND_STAGES } from '../../../ducks/send'; import { renderWithProvider } from '../../../../test/jest'; +import { ASSET_TYPES } from '../../../../shared/constants/transaction'; import SendHeader from './send-header.component'; const middleware = [thunk]; From cd4deef03143421242243cfef8e7338ef46c67fc Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 17:21:34 -0500 Subject: [PATCH 027/192] Dark Mode: Update the loading screen colors (#13987) --- ui/components/ui/loading-screen/index.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/components/ui/loading-screen/index.scss b/ui/components/ui/loading-screen/index.scss index dd3f40d58..f3bcd65bc 100644 --- a/ui/components/ui/loading-screen/index.scss +++ b/ui/components/ui/loading-screen/index.scss @@ -9,7 +9,8 @@ flex: 1 1 auto; width: 100%; height: 100%; - background: rgba(255, 255, 255, 0.8); + background: var(--color-background-alternative); + opacity: 0.8; &__screen-content { display: flex; From 157c40d666a5c9126ce8946ecf90cc6af24c5a81 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 17:21:46 -0500 Subject: [PATCH 028/192] Ensure accounts still line up in dropdown (#13986) --- ui/components/app/account-menu/index.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/components/app/account-menu/index.scss b/ui/components/app/account-menu/index.scss index 676349627..1d7bac0f7 100644 --- a/ui/components/app/account-menu/index.scss +++ b/ui/components/app/account-menu/index.scss @@ -187,6 +187,7 @@ &__check-mark { margin-right: 8px; flex: 0 0 auto; + min-width: 24px; } .identicon { From e2a6bcfc6bc5ceb6503d9c8599adc1fae15e1854 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 17:21:55 -0500 Subject: [PATCH 029/192] Dark Mode: ENS Input (#13984) --- ui/pages/send/send.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ui/pages/send/send.scss b/ui/pages/send/send.scss index f2a508cac..95ac88442 100644 --- a/ui/pages/send/send.scss +++ b/ui/pages/send/send.scss @@ -182,6 +182,10 @@ height: 1.125rem; margin: 0.25rem 0.5rem 0.25rem 0.25rem; + [data-theme='dark'] & { + background-image: url('/images/search.svg'); + } + &--valid { background-image: url('/images/check-green-solid.svg'); } @@ -194,6 +198,8 @@ width: 0; border: 0; outline: none; + color: var(--color-text-default); + background-color: var(--color-background-default); &::placeholder { color: var(--Grey-200); From a5ee4097f5ccba9ddfe9491c936148c1f337526c Mon Sep 17 00:00:00 2001 From: David Walsh Date: Wed, 16 Mar 2022 17:22:13 -0500 Subject: [PATCH 030/192] Dark Mode: Fix Onboarding image text color (#13983) --- ui/pages/onboarding-flow/pin-extension/pin-billboard.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/pages/onboarding-flow/pin-extension/pin-billboard.js b/ui/pages/onboarding-flow/pin-extension/pin-billboard.js index 347a0d02a..5d1f7c600 100644 --- a/ui/pages/onboarding-flow/pin-extension/pin-billboard.js +++ b/ui/pages/onboarding-flow/pin-extension/pin-billboard.js @@ -43,7 +43,7 @@ export default function OnboardingPinBillboard() { Date: Wed, 16 Mar 2022 15:27:11 -0700 Subject: [PATCH 031/192] Better 712 errors (#13939) * Added more info for EIP-712 schema errors * Changed EthereumProviderError to EthereumRpcError * Fixed error code to not be hardcoded for signTypedData --- app/scripts/lib/typed-message-manager.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index a0a22edb8..db65544df 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -1,7 +1,7 @@ import EventEmitter from 'events'; import { strict as assert } from 'assert'; import { ObservableStore } from '@metamask/obs-store'; -import { ethErrors } from 'eth-rpc-errors'; +import { EthereumRpcError, ethErrors } from 'eth-rpc-errors'; import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util'; import log from 'loglevel'; import jsonschema from 'jsonschema'; @@ -192,11 +192,13 @@ export default class TypedMessageManager extends EventEmitter { data.primaryType in data.types, `Primary type of "${data.primaryType}" has no type definition.`, ); - assert.equal( - validation.errors.length, - 0, - 'Signing data must conform to EIP-712 schema. See https://git.io/fNtcx.', - ); + if (validation.errors.length !== 0) { + throw new EthereumRpcError( + ethErrors.rpc.invalidParams, + 'Signing data must conform to EIP-712 schema. See https://git.io/fNtcx.', + validation.errors.map((v) => v.message.toString()), + ); + } let { chainId } = data.domain; if (chainId) { const activeChainId = parseInt(this._getCurrentChainId(), 16); From bba8b214b9c2302aa0f1befff948da295fe7f72f Mon Sep 17 00:00:00 2001 From: Shane Date: Wed, 16 Mar 2022 16:42:55 -0700 Subject: [PATCH 032/192] Fixed error thrown for 712 errors (#14008) --- app/scripts/lib/typed-message-manager.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js index db65544df..01ff3cc87 100644 --- a/app/scripts/lib/typed-message-manager.js +++ b/app/scripts/lib/typed-message-manager.js @@ -1,7 +1,7 @@ import EventEmitter from 'events'; import { strict as assert } from 'assert'; import { ObservableStore } from '@metamask/obs-store'; -import { EthereumRpcError, ethErrors } from 'eth-rpc-errors'; +import { ethErrors } from 'eth-rpc-errors'; import { typedSignatureHash, TYPED_MESSAGE_SCHEMA } from 'eth-sig-util'; import log from 'loglevel'; import jsonschema from 'jsonschema'; @@ -193,11 +193,11 @@ export default class TypedMessageManager extends EventEmitter { `Primary type of "${data.primaryType}" has no type definition.`, ); if (validation.errors.length !== 0) { - throw new EthereumRpcError( - ethErrors.rpc.invalidParams, - 'Signing data must conform to EIP-712 schema. See https://git.io/fNtcx.', - validation.errors.map((v) => v.message.toString()), - ); + throw ethErrors.rpc.invalidParams({ + message: + 'Signing data must conform to EIP-712 schema. See https://git.io/fNtcx.', + data: validation.errors.map((v) => v.message.toString()), + }); } let { chainId } = data.domain; if (chainId) { From 8b1230acab1d7646b80f7f71b265b6050d57eee3 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Thu, 17 Mar 2022 08:41:50 -0230 Subject: [PATCH 033/192] Add `ShowHideToggle` component (#13979) Add a new component for controlling whether a field should be shown or hidden. This will be used in later PRs as a control for sensitive fields that are hidden by default. This component should be fully accessible. Both mouse and keyboard interactions have been tested, and `aria-label` attributes have been added to explain the two "eye" icons that don't have any corresponding text. Thorough unit tests have been written, testing all props except `className` (I don't know how to test that using Jest/`jsdom`). --- ui/components/ui/show-hide-toggle/index.js | 1 + ui/components/ui/show-hide-toggle/index.scss | 34 ++ .../ui/show-hide-toggle/show-hide-toggle.js | 86 +++++ .../show-hide-toggle.stories.js | 51 +++ .../show-hide-toggle/show-hide-toggle.test.js | 314 ++++++++++++++++++ ui/components/ui/ui-components.scss | 1 + 6 files changed, 487 insertions(+) create mode 100644 ui/components/ui/show-hide-toggle/index.js create mode 100644 ui/components/ui/show-hide-toggle/index.scss create mode 100644 ui/components/ui/show-hide-toggle/show-hide-toggle.js create mode 100644 ui/components/ui/show-hide-toggle/show-hide-toggle.stories.js create mode 100644 ui/components/ui/show-hide-toggle/show-hide-toggle.test.js diff --git a/ui/components/ui/show-hide-toggle/index.js b/ui/components/ui/show-hide-toggle/index.js new file mode 100644 index 000000000..21767a970 --- /dev/null +++ b/ui/components/ui/show-hide-toggle/index.js @@ -0,0 +1 @@ +export { default } from './show-hide-toggle'; diff --git a/ui/components/ui/show-hide-toggle/index.scss b/ui/components/ui/show-hide-toggle/index.scss new file mode 100644 index 000000000..88ec8a068 --- /dev/null +++ b/ui/components/ui/show-hide-toggle/index.scss @@ -0,0 +1,34 @@ +.show-hide-toggle { + position: relative; + display: inline-flex; + + &__input { + appearance: none; + + + .show-hide-toggle__label { + cursor: pointer; + user-select: none; + } + + /* Focused when tabbing with keyboard */ + &:focus, + &:focus-visible { + outline: none; + + + .show-hide-toggle__label { + outline: Highlight auto 1px; + } + } + + &:disabled { + + label { + opacity: 0.5; + cursor: auto; + } + } + } + + &__icon { + color: var(--color-icon-default); + } +} diff --git a/ui/components/ui/show-hide-toggle/show-hide-toggle.js b/ui/components/ui/show-hide-toggle/show-hide-toggle.js new file mode 100644 index 000000000..61477b205 --- /dev/null +++ b/ui/components/ui/show-hide-toggle/show-hide-toggle.js @@ -0,0 +1,86 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; + +import IconEye from '../icon/icon-eye'; +import IconEyeSlash from '../icon/icon-eye-slash'; + +const ShowHideToggle = ({ + id, + shown, + onChange, + ariaLabelHidden, + ariaLabelShown, + className, + 'data-testid': dataTestId, + disabled, + title, +}) => { + return ( +
+ + +
+ ); +}; + +ShowHideToggle.propTypes = { + /** + * The id of the ShowHideToggle for htmlFor + */ + id: PropTypes.string.isRequired, + /** + * If the ShowHideToggle is in the "shown" state or not + */ + shown: PropTypes.bool.isRequired, + /** + * The onChange handler of the ShowHideToggle + */ + onChange: PropTypes.func.isRequired, + /** + * The aria-label of the icon representing the "hidden" state + */ + ariaLabelHidden: PropTypes.string.isRequired, + /** + * The aria-label of the icon representing the "shown" state + */ + ariaLabelShown: PropTypes.string.isRequired, + /** + * An additional className to give the ShowHideToggle + */ + className: PropTypes.string, + /** + * The data test id of the input + */ + 'data-testid': PropTypes.string, + /** + * Whether the input is disabled or not + */ + disabled: PropTypes.bool, + /** + * The title for the toggle. This is shown in a tooltip on hover. + */ + title: PropTypes.string, +}; + +export default ShowHideToggle; diff --git a/ui/components/ui/show-hide-toggle/show-hide-toggle.stories.js b/ui/components/ui/show-hide-toggle/show-hide-toggle.stories.js new file mode 100644 index 000000000..4eb06c5c0 --- /dev/null +++ b/ui/components/ui/show-hide-toggle/show-hide-toggle.stories.js @@ -0,0 +1,51 @@ +import React from 'react'; +import { useArgs } from '@storybook/client-api'; +import ShowHideToggle from '.'; + +export default { + title: 'Components/UI/ShowHideToggle', // title should follow the folder structure location of the component. Don't use spaces. + id: __filename, + argTypes: { + id: { + control: 'text', + }, + ariaLabelHidden: { + control: 'text', + }, + ariaLabelShown: { + control: 'text', + }, + className: { + control: 'text', + }, + dataTestId: { + control: 'text', + }, + disabled: { + control: 'boolean', + }, + onChange: { + action: 'onChange', + }, + shown: { + control: 'boolean', + }, + }, +}; + +export const DefaultStory = (args) => { + const [{ shown }, updateArgs] = useArgs(); + const handleOnToggle = () => { + updateArgs({ shown: !shown }); + }; + return ; +}; + +DefaultStory.args = { + id: 'showHideToggle', + ariaLabelHidden: 'hidden', + ariaLabelShown: 'shown', + shown: false, +}; + +DefaultStory.storyName = 'Default'; diff --git a/ui/components/ui/show-hide-toggle/show-hide-toggle.test.js b/ui/components/ui/show-hide-toggle/show-hide-toggle.test.js new file mode 100644 index 000000000..8ead1b7b5 --- /dev/null +++ b/ui/components/ui/show-hide-toggle/show-hide-toggle.test.js @@ -0,0 +1,314 @@ +import React from 'react'; +import { isInaccessible, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import ShowHideToggle from '.'; + +describe('ShowHideToggle', () => { + beforeEach(() => { + jest.resetAllMocks(); + }); + + it('should set title', async () => { + const onChange = jest.fn(); + const { queryByTitle } = render( + , + ); + + expect(queryByTitle('example-title')).toBeInTheDocument(); + }); + + it('should set test ID', async () => { + const onChange = jest.fn(); + const { queryByTestId } = render( + , + ); + + expect(queryByTestId('example-test-id')).toBeInTheDocument(); + }); + + it('should show correct aria-label when shown', () => { + const onChange = jest.fn(); + const { queryByLabelText } = render( + , + ); + + expect(queryByLabelText('hidden')).not.toBeInTheDocument(); + expect(queryByLabelText('shown')).toBeInTheDocument(); + }); + + it('should show correct aria-label when hidden', () => { + const onChange = jest.fn(); + const { queryByLabelText } = render( + , + ); + + expect(queryByLabelText('hidden')).toBeInTheDocument(); + expect(queryByLabelText('shown')).not.toBeInTheDocument(); + }); + + it('should show correct checkbox state when shown', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(queryByRole('checkbox')).toBeChecked(); + }); + + it('should show correct checkbox state when hidden', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(queryByRole('checkbox')).not.toBeChecked(); + }); + + describe('enabled', () => { + it('should show checkbox as enabled', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(queryByRole('checkbox')).toBeEnabled(); + }); + + it('should be accessible', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(isInaccessible(queryByRole('checkbox'))).toBeFalsy(); + }); + + describe('shown', () => { + it('should call onChange when clicked', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + await userEvent.click(queryByRole('checkbox')); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + + it('should call onChange on space', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + queryByRole('checkbox').focus(); + await userEvent.keyboard('[Space]'); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + }); + + describe('hidden', () => { + it('should call onChange when clicked', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + await userEvent.click(queryByRole('checkbox')); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + + it('should call onChange on space', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + queryByRole('checkbox').focus(); + await userEvent.keyboard('[Space]'); + + expect(onChange).toHaveBeenCalledTimes(1); + }); + }); + }); + + describe('disabled', () => { + it('should show checkbox as disabled', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(queryByRole('checkbox')).toBeDisabled(); + }); + + it('should be accessible', () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + + expect(isInaccessible(queryByRole('checkbox'))).toBeFalsy(); + }); + + describe('shown', () => { + it('should not call onChange when clicked', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + await userEvent.click(queryByRole('checkbox')); + + expect(onChange).not.toHaveBeenCalled(); + }); + + it('should not call onChange on space', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + queryByRole('checkbox').focus(); + await userEvent.keyboard('[Space]'); + + expect(onChange).not.toHaveBeenCalled(); + }); + }); + + describe('hidden', () => { + it('should not call onChange when clicked', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + await userEvent.click(queryByRole('checkbox')); + + expect(onChange).not.toHaveBeenCalled(); + }); + + it('should not call onChange on space', async () => { + const onChange = jest.fn(); + const { queryByRole } = render( + , + ); + queryByRole('checkbox').focus(); + await userEvent.keyboard('[Space]'); + + expect(onChange).not.toHaveBeenCalled(); + }); + }); + }); +}); diff --git a/ui/components/ui/ui-components.scss b/ui/components/ui/ui-components.scss index 07d4fdb90..0a3b51552 100644 --- a/ui/components/ui/ui-components.scss +++ b/ui/components/ui/ui-components.scss @@ -44,6 +44,7 @@ @import 'radio-group/index'; @import 'readonly-input/index'; @import 'sender-to-recipient/index'; +@import 'show-hide-toggle/index.scss'; @import 'snackbar/index'; @import 'site-origin/index'; @import 'slider/index'; From 962679323301acb8fb46f60443aafc8df504e6be Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 17 Mar 2022 14:40:12 +0100 Subject: [PATCH 034/192] Dark Mode : AddNetwork (#13999) --- ui/components/app/add-network/index.scss | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/components/app/add-network/index.scss b/ui/components/app/add-network/index.scss index 9a087b259..9c0dfd169 100644 --- a/ui/components/app/add-network/index.scss +++ b/ui/components/app/add-network/index.scss @@ -1,6 +1,6 @@ .add-network { &__header { - border-bottom: 1px solid var(--ui-grey); + border-bottom: 1px solid var(--color-border-default); &__back-icon { margin-left: 24px; @@ -17,13 +17,13 @@ &__add-icon { height: 16px; width: 12px; - color: var(--ui-4); + color: var(--color-text-alternative); margin-left: auto; margin-right: 0; } &__footer { - border-top: 1px solid var(--ui-2); + border-top: 1px solid var(--color-border-muted); & .btn-link { display: initial; @@ -31,12 +31,12 @@ } &__link { - color: var(--primary-1); + color: var(--color-primary-default); } & .actionable-message--warning .actionable-message__message, .actionable-message--warning .actionable-message__action { - color: var(--ui-4); + color: var(--color-text-alternative); } } } From 8b9b9af13fabcef4882d4423e35acb4cd3aef4e9 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Thu, 17 Mar 2022 17:43:18 +0100 Subject: [PATCH 035/192] Add native browser notification support for Snaps (#13613) * Initial native notification implementation * Simplify implementation * Implementation based on RateLimitController * Update controllers package * Add notification to permission list * Wire up correctly * Remove snap_notify from the exclusion list --- app/_locales/en/messages.json | 4 ++++ app/scripts/metamask-controller.js | 32 ++++++++++++++++++++++++++++++ shared/constants/permissions.js | 3 ++- ui/helpers/utils/permission.js | 5 +++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index b0d6dd9b8..a3afaeebb 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2362,6 +2362,10 @@ "message": "Store and manage its data on your device.", "description": "The description for the `snap_manageState` permission" }, + "permission_notifications": { + "message": "Show notifications.", + "description": "The description for the `snap_notify` permission" + }, "permission_unknown": { "message": "Unknown permission: $1", "description": "$1 is the name of a requested permission that is not recognized." diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 1f4441c2e..bd5fbdb5e 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -40,6 +40,9 @@ import { CollectibleDetectionController, PermissionController, SubjectMetadataController, + ///: BEGIN:ONLY_INCLUDE_IN(flask) + RateLimitController, + ///: END:ONLY_INCLUDE_IN } from '@metamask/controllers'; import SmartTransactionsController from '@metamask/smart-transactions-controller'; ///: BEGIN:ONLY_INCLUDE_IN(flask) @@ -634,6 +637,27 @@ export default class MetamaskController extends EventEmitter { state: initState.SnapController, messenger: snapControllerMessenger, }); + + this.rateLimitController = new RateLimitController({ + messenger: this.controllerMessenger.getRestricted({ + name: 'RateLimitController', + }), + implementations: { + showNativeNotification: (origin, message) => { + const subjectMetadataState = this.controllerMessenger.call( + 'SubjectMetadataController:getState', + ); + + const originMetadata = subjectMetadataState.subjectMetadata[origin]; + + this.platform._showNotification( + originMetadata?.name ?? origin, + message, + ); + return null; + }, + }, + }); ///: END:ONLY_INCLUDE_IN this.detectTokensController = new DetectTokensController({ @@ -1036,6 +1060,14 @@ export default class MetamaskController extends EventEmitter { type: MESSAGE_TYPE.SNAP_CONFIRM, requestData: confirmationData, }), + showNotification: (origin, args) => + this.controllerMessenger.call( + 'RateLimitController:call', + origin, + 'showNativeNotification', + origin, + args.message, + ), updateSnapState: this.controllerMessenger.call.bind( this.controllerMessenger, 'SnapController:updateSnapState', diff --git a/shared/constants/permissions.js b/shared/constants/permissions.js index 982f20e7b..c1e4e69e7 100644 --- a/shared/constants/permissions.js +++ b/shared/constants/permissions.js @@ -6,6 +6,7 @@ export const RestrictedMethods = Object.freeze({ eth_accounts: 'eth_accounts', ///: BEGIN:ONLY_INCLUDE_IN(flask) snap_confirm: 'snap_confirm', + snap_notify: 'snap_notify', snap_manageState: 'snap_manageState', 'snap_getBip44Entropy_*': 'snap_getBip44Entropy_*', 'wallet_snap_*': 'wallet_snap_*', @@ -23,5 +24,5 @@ export const EndowmentPermissions = Object.freeze({ }); // Methods / permissions in external packages that we are temporarily excluding. -export const ExcludedSnapPermissions = new Set(['snap_notify']); +export const ExcludedSnapPermissions = new Set([]); ///: END:ONLY_INCLUDE_IN diff --git a/ui/helpers/utils/permission.js b/ui/helpers/utils/permission.js index baa21dc18..7625880ea 100644 --- a/ui/helpers/utils/permission.js +++ b/ui/helpers/utils/permission.js @@ -24,6 +24,11 @@ const PERMISSION_DESCRIPTIONS = deepFreeze({ leftIcon: 'fas fa-user-check', rightIcon: null, }, + [RestrictedMethods.snap_notify]: { + leftIcon: 'fas fa-bell', + label: (t) => t('permission_notifications'), + rightIcon: null, + }, [RestrictedMethods['snap_getBip44Entropy_*']]: { label: (t, permissionName) => { const coinType = permissionName.split('_').slice(-1); From b5c120c6a34ff8606860c0e8d21fcb2b90e4ea30 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Thu, 17 Mar 2022 13:03:47 -0500 Subject: [PATCH 036/192] Dark mode: Settings / Contacts colors (#13988) --- ui/pages/settings/contact-list-tab/index.scss | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ui/pages/settings/contact-list-tab/index.scss b/ui/pages/settings/contact-list-tab/index.scss index 6d2528fdb..7bfd99398 100644 --- a/ui/pages/settings/contact-list-tab/index.scss +++ b/ui/pages/settings/contact-list-tab/index.scss @@ -80,20 +80,20 @@ } &__link { - background-color: #fff; - color: #037dd6; + background-color: transparent; + color: var(--color-primary-default); } &__input { @include H4; - border: 1px solid var(--Grey-200); + border: 1px solid var(--color-border-muted); border-radius: 6px; - color: var(--Grey-800); + color: var(--color-text-muted); padding: 0.875rem 1rem; &:focus-within { - border-color: var(--Blue-500); + border-color: var(--color-primary-default); } margin-top: 0.25rem; @@ -129,7 +129,7 @@ &__label--capitalized { @include H7; - color: var(--Grey-500); + color: var(--color-text-alternative); margin-bottom: 0.25rem; } @@ -143,7 +143,7 @@ display: flex; flex-flow: row nowrap; - color: var(--Grey-800); + color: var(--color-text-muted); word-break: break-word; &--address { From 9373f51e975b37ff22f701651ed59ab3c9cddd3f Mon Sep 17 00:00:00 2001 From: David Walsh Date: Thu, 17 Mar 2022 13:04:01 -0500 Subject: [PATCH 037/192] Dark Mode: Swaps Colors (#13976) --- .../transaction-detail-item.component.js | 2 +- ui/pages/swaps/awaiting-swap/index.scss | 12 ++++---- ui/pages/swaps/build-quote/index.scss | 18 +++++------ ui/pages/swaps/dropdown-input-pair/index.scss | 4 +-- .../swaps/dropdown-search-list/index.scss | 28 ++++++++--------- .../swaps/exchange-rate-display/index.scss | 2 +- ui/pages/swaps/fee-card/index.scss | 22 +++++++------- ui/pages/swaps/import-token/index.scss | 2 +- ui/pages/swaps/index.scss | 12 ++++---- .../swaps/loading-swaps-quotes/index.scss | 8 ++--- ui/pages/swaps/main-quote-summary/index.scss | 8 ++--- .../swaps/searchable-item-list/index.scss | 30 +++++++++---------- .../swaps/select-quote-popover/index.scss | 22 +++++++------- .../quote-details/index.scss | 12 ++++---- ui/pages/swaps/slippage-buttons/index.scss | 24 +++++++-------- .../swaps/smart-transaction-status/index.scss | 8 ++--- ui/pages/swaps/swaps-footer/index.scss | 2 +- ui/pages/swaps/view-quote/index.scss | 6 ++-- 18 files changed, 111 insertions(+), 111 deletions(-) diff --git a/ui/components/app/transaction-detail-item/transaction-detail-item.component.js b/ui/components/app/transaction-detail-item/transaction-detail-item.component.js index 8601185a9..e82c78f1a 100644 --- a/ui/components/app/transaction-detail-item/transaction-detail-item.component.js +++ b/ui/components/app/transaction-detail-item/transaction-detail-item.component.js @@ -16,7 +16,7 @@ import { export default function TransactionDetailItem({ detailTitle = '', detailText = '', - detailTitleColor = COLORS.BLACK, + detailTitleColor = COLORS.TEXT_DEFAULT, detailTotal = '', subTitle = '', subText = '', diff --git a/ui/pages/swaps/awaiting-swap/index.scss b/ui/pages/swaps/awaiting-swap/index.scss index 9ed729b9c..bae40017d 100644 --- a/ui/pages/swaps/awaiting-swap/index.scss +++ b/ui/pages/swaps/awaiting-swap/index.scss @@ -21,7 +21,7 @@ } a { - color: var(--Blue-500); + color: var(--text-primary-color); } &__status-image { @@ -32,13 +32,13 @@ &__header { @include H3; - color: var(--Black-100); + color: var(--color-text-default); } &__main-description { @include H6; - color: var(--Grey-500); + color: var(--color-text-alternative); margin-top: 16px; width: 100%; } @@ -46,7 +46,7 @@ &__time-estimate { @include H7; - color: var(--Black-100); + color: var(--color-text-default); margin-top: 20px; font-style: italic; @@ -66,7 +66,7 @@ &__view-on-etherscan, &__support-link { - color: var(--Blue-500); + color: var(--text-primary-color); margin-top: 24px; cursor: pointer; } @@ -90,7 +90,7 @@ } &__amount-and-symbol { - color: var(--Black-100); + color: var(--color-text-default); font-weight: bold; } } diff --git a/ui/pages/swaps/build-quote/index.scss b/ui/pages/swaps/build-quote/index.scss index b53754263..725550113 100644 --- a/ui/pages/swaps/build-quote/index.scss +++ b/ui/pages/swaps/build-quote/index.scss @@ -42,7 +42,7 @@ @include H5; font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); margin-top: 3px; } @@ -67,7 +67,7 @@ &__max-button { @include H7; - color: var(--Blue-500); + color: var(--text-primary-color); cursor: pointer; } @@ -75,7 +75,7 @@ @include H7; width: 100%; - color: var(--Grey-500); + color: var(--color-text-muted); margin-top: 4px; display: flex; flex-flow: column; @@ -84,17 +84,17 @@ &--error { div:first-of-type { font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); } .build-quote__form-error:first-of-type { font-weight: bold; - color: var(--Red-500); + color: var(--color-error-default); } div:last-of-type { font-weight: normal; - color: var(--Grey-500); + color: var(--color-text-alternative); } } } @@ -142,7 +142,7 @@ @include H7; width: 100%; - color: var(--Grey-500); + color: var(--color-text-alternative); margin-top: 4px; .info-tooltip { @@ -151,7 +151,7 @@ } &__token-etherscan-link { - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; } @@ -190,7 +190,7 @@ } a { - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; } } diff --git a/ui/pages/swaps/dropdown-input-pair/index.scss b/ui/pages/swaps/dropdown-input-pair/index.scss index 7428130ba..234280dac 100644 --- a/ui/pages/swaps/dropdown-input-pair/index.scss +++ b/ui/pages/swaps/dropdown-input-pair/index.scss @@ -14,7 +14,7 @@ } div { - border: 1px solid var(--Grey-100); + border: 1px solid var(--color-background-alternative); border-top-left-radius: 0; border-bottom-left-radius: 0; border-left-color: transparent; @@ -47,7 +47,7 @@ height: 100%; display: flex; align-items: center; - color: var(--Grey-500); + color: var(--color-text-alternative); &--two-lines { right: inherit; diff --git a/ui/pages/swaps/dropdown-search-list/index.scss b/ui/pages/swaps/dropdown-search-list/index.scss index 2d4127c1e..711fd3f31 100644 --- a/ui/pages/swaps/dropdown-search-list/index.scss +++ b/ui/pages/swaps/dropdown-search-list/index.scss @@ -10,7 +10,7 @@ &__token-container { margin: 0; min-height: auto; - border: 1px solid #d6d9dc; + border: 1px solid var(--color-border-default); box-sizing: border-box; box-shadow: none; border-radius: 6px; @@ -18,8 +18,8 @@ } &--open { - box-shadow: 0 0 14px rgba(0, 0, 0, 0.18); - border: 1px solid var(--Grey-100); + box-shadow: 0 0 14px rgba(0, 0, 0, 0.18); /* TODO! */ + border: 1px solid var(--color-border-default); } &__close-area { @@ -40,18 +40,18 @@ transition: 200ms ease-in-out; border-radius: 6px; box-shadow: none; - border: 1px solid #d6d9dc; + border: 1px solid var(--color-border-default); height: 60px; &:hover { - background: var(--Grey-000); + background: var(--color-background-alternative); } } &__caret { position: absolute; right: 16px; - color: var(--Grey-200); + color: var(--color-icon-muted); } &__selector-closed { @@ -83,7 +83,7 @@ &__closed-primary-label { @include H4; - color: var(--Black-100); + color: var(--color-text-default); max-width: 100%; overflow: hidden; text-overflow: ellipsis; @@ -92,14 +92,14 @@ &__search-list--open { box-shadow: 0 0 14px rgba(0, 0, 0, 0.18); - border: 1px solid var(--Grey-100); + border: 1px solid var(--color-border-muted); } &__default-dropdown-icon { width: 34px; height: 34px; border-radius: 50%; - background: var(--Grey-200); + background: var(--color-background-alternative); flex: 0 1 auto; } @@ -118,18 +118,18 @@ } &__select-default { - color: var(--Grey-200); + color: var(--color-text-muted); } &__placeholder { @include H6; padding: 16px; - color: var(--Grey-500); + color: var(--color-text-alternative); min-height: 300px; position: relative; z-index: 1002; - background: white; + background: var(--color-background-default); border-radius: 6px; min-height: 194px; overflow: hidden; @@ -149,10 +149,10 @@ padding: 16px 12px; box-sizing: border-box; cursor: pointer; - border-top: 1px solid var(--Grey-100); + border-top: 1px solid var(--color-border-muted); position: relative; z-index: 1; - background: var(--white); + background: var(--color-background-default); } &__loading-item-text-container { diff --git a/ui/pages/swaps/exchange-rate-display/index.scss b/ui/pages/swaps/exchange-rate-display/index.scss index 64dfafb82..2d68dca24 100644 --- a/ui/pages/swaps/exchange-rate-display/index.scss +++ b/ui/pages/swaps/exchange-rate-display/index.scss @@ -4,7 +4,7 @@ display: flex; align-items: flex-end; justify-content: center; - color: var(--Black-100); + color: var(--color-text-default); width: 100%; flex-wrap: wrap; diff --git a/ui/pages/swaps/fee-card/index.scss b/ui/pages/swaps/fee-card/index.scss index 022fc25f9..4820f6a58 100644 --- a/ui/pages/swaps/fee-card/index.scss +++ b/ui/pages/swaps/fee-card/index.scss @@ -23,7 +23,7 @@ @include H6; font-weight: bold; - color: var(--Blue-500); + color: var(--color-primary-default); } &__quote-link-container { @@ -35,13 +35,13 @@ &__quote-link-text { @include H7; - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; padding-right: 4px; } &__caret-right { - color: var(--Blue-500); + color: var(--color-primary-default); width: 6px; height: 6px; display: flex; @@ -84,7 +84,7 @@ } &__row-header-text--bold { - color: var(--Black-100); + color: var(--color-text-default); } &__row-header-text { @@ -147,18 +147,18 @@ &__link, &__link:hover { - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; } &__edit-link { - color: var(--Blue-500); + ccolor: var(--color-primary-default); cursor: pointer; padding-left: 6px; } &__total-box { - border-top: 1px solid var(--Grey-100); + border-top: 1px solid var(--color-border-muted); padding: 12px 16px 16px 16px; } @@ -174,13 +174,13 @@ display: flex; justify-content: flex-end; font-weight: bold; - color: var(--Grey-500); + color: var(--color-text-alternative); margin-top: 4px; } &__row-header-secondary, &__row-header-secondary--bold { - color: var(--Grey-500); + color: var(--color-text-alternative); } &__row-header-secondary, @@ -189,11 +189,11 @@ } &__row-header-primary { - color: var(--Grey-500); + color: var(--color-text-alternative); } &__row-header-primary--bold { - color: var(--Black-100); + color: var(--color-text-default); } &__row-header-text--bold, diff --git a/ui/pages/swaps/import-token/index.scss b/ui/pages/swaps/import-token/index.scss index d7b12960a..578e3dfb6 100644 --- a/ui/pages/swaps/import-token/index.scss +++ b/ui/pages/swaps/import-token/index.scss @@ -10,7 +10,7 @@ } &__message { - color: var(--Black-100); + color: var(--color-text-default); text-align: left; } } diff --git a/ui/pages/swaps/index.scss b/ui/pages/swaps/index.scss index fb428a52d..ef601851c 100644 --- a/ui/pages/swaps/index.scss +++ b/ui/pages/swaps/index.scss @@ -46,8 +46,8 @@ @media screen and (min-width: $break-large) { width: 460px; - background: white; - border: 1px solid var(--Grey-100); + background: var(--color-background-default); + border: 1px solid var(--color-border-muted); box-shadow: 0 0 7px 0 rgba(0, 0, 0, 0.08); border-radius: 8px; height: 620px; @@ -77,7 +77,7 @@ @include H5; font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); margin-top: -5px; flex: 1; text-align: center; @@ -90,7 +90,7 @@ align-items: center; padding-top: 0; padding-bottom: 16px; - background: var(--Grey-000); + background: var(--color-background-alternative); width: 100%; position: relative; flex-direction: row; @@ -105,7 +105,7 @@ &__header-cancel { @include H7; - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; padding-right: 24px; flex: 1; @@ -115,7 +115,7 @@ &__header-edit { @include H7; - color: var(--Blue-500); + color: var(--color-primary-default); cursor: pointer; padding-left: 24px; flex: 1; diff --git a/ui/pages/swaps/loading-swaps-quotes/index.scss b/ui/pages/swaps/loading-swaps-quotes/index.scss index 60b0d46dd..1494ee8ed 100644 --- a/ui/pages/swaps/loading-swaps-quotes/index.scss +++ b/ui/pages/swaps/loading-swaps-quotes/index.scss @@ -17,7 +17,7 @@ &__quote-counter { @include H7; - color: var(--Grey-500); + color: var(--color-text-alternative); margin-top: 3px; display: flex; justify-content: center; @@ -29,7 +29,7 @@ @include H4; font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); display: flex; justify-content: center; width: 100%; @@ -123,14 +123,14 @@ &__loading-bar-container { width: 248px; height: 3px; - background: var(--Grey-100); + background: var(--color-background-alternative); display: flex; margin-top: 16px; } &__loading-bar { height: 3px; - background: var(--Blue-500); + background: var(--color-primary-default); -webkit-transition: width 0.5s linear; -moz-transition: width 0.5s linear; -o-transition: width 0.5s linear; diff --git a/ui/pages/swaps/main-quote-summary/index.scss b/ui/pages/swaps/main-quote-summary/index.scss index 87c714d8d..290c894c0 100644 --- a/ui/pages/swaps/main-quote-summary/index.scss +++ b/ui/pages/swaps/main-quote-summary/index.scss @@ -5,7 +5,7 @@ align-items: center; position: relative; width: 100%; - color: var(--Black-100); + color: var(--color-text-default); margin-top: 28px; margin-bottom: 56px; @@ -18,7 +18,7 @@ @include H6; - color: var(--Grey-500); + color: var(--color-text-alternative); } &__source-row { @@ -53,7 +53,7 @@ &__destination-row-symbol { margin-left: 5px; - color: var(--Black-100); + color: var(--color-text-default); } &__icon, @@ -117,6 +117,6 @@ } &__exchange-rate-display { - color: var(--Grey-500); + color: var(--color-text-alternative); } } diff --git a/ui/pages/swaps/searchable-item-list/index.scss b/ui/pages/swaps/searchable-item-list/index.scss index f656928c2..1c9a6ae3f 100644 --- a/ui/pages/swaps/searchable-item-list/index.scss +++ b/ui/pages/swaps/searchable-item-list/index.scss @@ -1,12 +1,12 @@ .searchable-item-list { - background: var(--white); + background: var(--color-background-default); width: 100%; position: relative; &__search { > div { border: none; - border-bottom: 1px solid var(--Grey-100); + border-bottom: 1px solid var(--color-border-muted); border-radius: 0; height: 55px; font-size: 12px; @@ -14,26 +14,26 @@ input { @include H6; - color: var(--Grey-500); + color: var(--color-text-default); line-height: 100%; &::-webkit-input-placeholder { - color: var(--Grey-500); + color: var(--color-text-muted); opacity: 1; } &:-moz-placeholder { - color: var(--Grey-500); + color: var(--color-text-muted); opacity: 1; } &::-moz-placeholder { - color: var(--Grey-500); + color: var(--color-text-muted); opacity: 1; } &::placeholder { - color: var(--Grey-500); + color: var(--color-text-muted); opacity: 1; } } @@ -54,7 +54,7 @@ padding: 8px 12px; box-sizing: border-box; cursor: pointer; - border-top: 1px solid var(--Grey-100); + border-top: 1px solid var(--color-border-muted); position: relative; min-height: 50px; @@ -68,11 +68,11 @@ &:hover, &:focus { - background: var(--Grey-000); + background: var(--color-background-alternative); } &--selected { - border: 1px solid var(--malibu-blue) !important; + border: 1px solid var(--color-primary-default) !important; } &--disabled { @@ -94,12 +94,12 @@ &__message { text-align: left; - color: var(--Black-100); + color: var(--color-text-default); } a { pointer-events: auto; - color: #037dd6; + color: var(--color-primary-default); cursor: pointer; } } @@ -170,7 +170,7 @@ @include H7; line-height: 100%; - color: var(--Grey-500); + color: var(--color-text-alternative); text-overflow: ellipsis; overflow: hidden; white-space: nowrap; @@ -185,7 +185,7 @@ @include H7; line-height: 100%; - color: var(--Grey-500); + color: var(--color-text-alternative); opacity: 0.5; text-overflow: ellipsis; overflow: hidden; @@ -194,7 +194,7 @@ &__list-container { z-index: 1002; - background: white; + background: var(--color-background-default); } &__search { diff --git a/ui/pages/swaps/select-quote-popover/index.scss b/ui/pages/swaps/select-quote-popover/index.scss index 07bc9c209..d40da99c2 100644 --- a/ui/pages/swaps/select-quote-popover/index.scss +++ b/ui/pages/swaps/select-quote-popover/index.scss @@ -28,7 +28,7 @@ &__popover-bg { height: 100%; width: 100%; - background: var(--Grey-100); + background: var(--color-background-alternative); opacity: 1; @media screen and (min-width: $break-large) { @@ -58,7 +58,7 @@ @include H8; font-weight: bold; - color: var(--Black-100); + color: var(--color-text-default); height: 43px; margin-bottom: 4px; } @@ -74,7 +74,7 @@ cursor: pointer; color: var(--black); height: 49px; - border-bottom: 1px solid var(--Grey-100); + border-bottom: 1px solid var(--color-background-alternative); margin-bottom: 8px; border-radius: 8px; background: var(--Grey-000); @@ -82,7 +82,7 @@ border: none; &:hover { - border: 1px solid var(--Blue-500); + border: 1px solid var(--color-primary-default); width: 101%; padding-right: 11px; padding-left: 19.5px; @@ -90,7 +90,7 @@ &--no-hover { &:hover { - border: 1px solid var(--Grey-100); + border: 1px solid var(--color-background-alternative); width: 100%; padding-right: 12px; padding-left: 20px; @@ -99,7 +99,7 @@ &--selected { color: var(--white); - background: linear-gradient(90deg, var(--Blue-500) 0%, var(--Blue-400) 101.32%); + background: linear-gradient(90deg, var(--color-primary-default) 0%, var(--primary-alternative) 101.32%); box-shadow: 0 10px 39px rgba(3, 125, 214, 0.15); border-radius: 8px; border-bottom: none; @@ -107,7 +107,7 @@ height: 64px; &:hover { - background: linear-gradient(90deg, var(--Blue-500) 0%, var(--Blue-400) 101.32%); + background: linear-gradient(90deg, var(--color-primary-default) 0%, var(--color-primary-alternative) 101.32%); width: 100%; padding-left: 20px; padding-right: 12px; @@ -118,7 +118,7 @@ color: var(--white); &:hover { - color: var(--Grey-500); + color: var(--color-text-alternative); } } @@ -146,7 +146,7 @@ } &__caret-right { - color: var(--Grey-500); + color: var(--color-text-alternative); width: 32px; height: 32px; display: flex; @@ -160,7 +160,7 @@ &:hover { border-radius: 8px; background: white; - border: 1px solid var(--Blue-500); + border: 1px solid var(--color-primary-default); } } @@ -211,7 +211,7 @@ &__receiving-symbol { - color: var(--Grey-500); + color: var(--color-text-alternative); > div { width: 12px; diff --git a/ui/pages/swaps/select-quote-popover/quote-details/index.scss b/ui/pages/swaps/select-quote-popover/quote-details/index.scss index 31039fa62..b020b55c1 100644 --- a/ui/pages/swaps/select-quote-popover/quote-details/index.scss +++ b/ui/pages/swaps/select-quote-popover/quote-details/index.scss @@ -15,7 +15,7 @@ &__detail-content { @include H6; - color: var(--Black-100); + color: var(--color-text-default); > div { justify-content: flex-start; @@ -23,17 +23,17 @@ } &__conversion-rate { - color: var(--Black-100); + color: var(--color-text-default); justify-content: flex-start; align-items: center; height: inherit; .view-quote__conversion-rate-eth-label { - color: var(--Black-100); + color: var(--color-text-default); } i { - color: var(--Blue-500); + color: var(--color-primary-default); } * { @@ -62,7 +62,7 @@ display: flex; flex-flow: column; justify-content: center; - border-top: 1px solid var(--Grey-100); + border-top: 1px solid var(--color-background-alternative); &--high { min-height: 60px; @@ -73,7 +73,7 @@ .view-quote__conversion-rate-token-label { @include H6; - color: var(--Black-100); + color: var(--color-text-default); font-weight: bold; margin-left: 2px; } diff --git a/ui/pages/swaps/slippage-buttons/index.scss b/ui/pages/swaps/slippage-buttons/index.scss index dfc34ab2c..644cb1610 100644 --- a/ui/pages/swaps/slippage-buttons/index.scss +++ b/ui/pages/swaps/slippage-buttons/index.scss @@ -7,7 +7,7 @@ &__header { display: flex; align-items: center; - color: var(--Blue-500); + color: var(--color-primary-default); margin-bottom: 0; margin-left: auto; margin-right: auto; @@ -22,7 +22,7 @@ @include H6; margin-right: 6px; - color: var(--Blue-500); + color: var(--color-primary-default); font-weight: 900; } @@ -45,14 +45,14 @@ @include H6; margin-right: 4px; - color: black; + color: var(--color-text-default); font-weight: 900; } &__error-text { @include H7; - color: var(--Red-500); + color: var(--color-error-default); margin-top: 8px; } @@ -76,34 +76,34 @@ border: none; width: 64px; text-align: center; - background: var(--Blue-500); - color: white; + background: var(--color-primary-default); + color: var(--color-primary-inverse); font-weight: inherit; &::-webkit-input-placeholder { /* WebKit, Blink, Edge */ - color: white; + color: var(--color-primary-inverse); } &:-moz-placeholder { /* Mozilla Firefox 4 to 18 */ - color: white; + color: var(--color-primary-inverse); opacity: 1; } &::-moz-placeholder { /* Mozilla Firefox 19+ */ - color: white; + color: var(--color-primary-inverse); opacity: 1; } &:-ms-input-placeholder { /* Internet Explorer 10-11 */ - color: white; + color: var(--color-primary-inverse); } &::-ms-input-placeholder { /* Microsoft Edge */ - color: white; + color: var(--color-primary-inverse); } &::placeholder { /* Most modern browsers support this now. */ - color: white; + color: var(--color-primary-inverse); } } diff --git a/ui/pages/swaps/smart-transaction-status/index.scss b/ui/pages/swaps/smart-transaction-status/index.scss index 07399de61..d077f0d24 100644 --- a/ui/pages/swaps/smart-transaction-status/index.scss +++ b/ui/pages/swaps/smart-transaction-status/index.scss @@ -13,7 +13,7 @@ &__loading-bar-container { height: 3px; - background: var(--Grey-100); + background: var(--color-background-alternative); display: flex; margin-top: 12px; margin-bottom: 28px; @@ -21,7 +21,7 @@ &__loading-bar { height: 3px; - background: var(--Blue-500); + background: var(--color-primary-default); transition: width 0.5s linear; } @@ -58,11 +58,11 @@ } a { - color: var(--Blue-500); + color: var(--color-primary-default); } &__support-link { - color: var(--Blue-500); + color: var(--color-primary-default); margin-top: 24px; cursor: pointer; } diff --git a/ui/pages/swaps/swaps-footer/index.scss b/ui/pages/swaps/swaps-footer/index.scss index a360a9ae7..4bd417389 100644 --- a/ui/pages/swaps/swaps-footer/index.scss +++ b/ui/pages/swaps/swaps-footer/index.scss @@ -38,7 +38,7 @@ &__bottom-text { @include H7; - color: var(--Blue-500); + color: var(--color-primary-default); margin-bottom: 16px; cursor: pointer; display: flex; diff --git a/ui/pages/swaps/view-quote/index.scss b/ui/pages/swaps/view-quote/index.scss index b50f0b9ef..2db5e250e 100644 --- a/ui/pages/swaps/view-quote/index.scss +++ b/ui/pages/swaps/view-quote/index.scss @@ -73,7 +73,7 @@ cursor: pointer; border-radius: 28px; padding: 5px 18px; - background: linear-gradient(90deg, var(--Blue-500) 0%, var(--Blue-400) 101.32%); + background: linear-gradient(90deg, var(--color-primary-default) 0%, var(--color-primary-alternative) 101.32%); @media screen and (min-width: $break-large) { @@ -122,7 +122,7 @@ &.low { .actionable-message { button { - background: var(--Blue-500); + background: var(--color-primary-default); color: #fff; } } @@ -217,7 +217,7 @@ &__metamask-rate-text { @include H7; - color: var(--Grey-500); + color: var(--color-text-alternative); } &__metamask-rate-info-icon { From 41974cec3b564813312f8493797aba22913ab39d Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Thu, 17 Mar 2022 19:23:56 +0100 Subject: [PATCH 038/192] Dark Mode : Connected account popover (#13932) --- ui/components/app/connected-accounts-permissions/index.scss | 2 +- ui/components/ui/popover/index.scss | 2 +- ui/components/ui/popover/popover.component.js | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/components/app/connected-accounts-permissions/index.scss b/ui/components/app/connected-accounts-permissions/index.scss index 89fdb39a2..06a2fcad6 100644 --- a/ui/components/app/connected-accounts-permissions/index.scss +++ b/ui/components/app/connected-accounts-permissions/index.scss @@ -21,7 +21,7 @@ justify-content: space-between; align-items: center; cursor: pointer; - color: #24292e; + color: var(--color-text-default); button { font-size: $font-size-paragraph; diff --git a/ui/components/ui/popover/index.scss b/ui/components/ui/popover/index.scss index 35b170a44..30eccfe29 100644 --- a/ui/components/ui/popover/index.scss +++ b/ui/components/ui/popover/index.scss @@ -67,7 +67,7 @@ &-bg { width: 100%; height: 100%; - background: black; + background: var(--color-text-default); opacity: 0.2; } diff --git a/ui/components/ui/popover/popover.component.js b/ui/components/ui/popover/popover.component.js index 2cdaee0d5..68c927b5e 100644 --- a/ui/components/ui/popover/popover.component.js +++ b/ui/components/ui/popover/popover.component.js @@ -6,6 +6,7 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import Box from '../box'; import { ALIGN_ITEMS, + COLORS, FLEX_DIRECTION, JUSTIFY_CONTENT, } from '../../../helpers/constants/design-system'; @@ -14,7 +15,7 @@ const defaultHeaderProps = { padding: [6, 4, 4], display: 'flex', flexDirection: FLEX_DIRECTION.COLUMN, - backgroundColor: 'white', + backgroundColor: COLORS.BACKGROUND_DEFAULT, borderRadius: 'xl', }; From e3ea4f2cd044d48c61b6a35ef206fa942f3b43d1 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Thu, 17 Mar 2022 13:35:40 -0500 Subject: [PATCH 039/192] Fix issue where we show contract address as recipient when calling safe transfer method on erc721 or erc1155 contracts (#13535) * fix issue where we show contract address as recipient when calling safe transfer method on erc721 or erc1155 contracts * updates function name getTransactionData -> parseStandardTokenTransactionData, and adds documentation --- app/_locales/en/messages.json | 3 ++ app/scripts/metamask-controller.js | 4 +- package.json | 1 + shared/constants/transaction.js | 1 + shared/modules/transaction.utils.js | 52 +++++++++++++++++-- shared/modules/transaction.utils.test.js | 19 +++++++ ...onfirm-page-container-summary.component.js | 4 +- .../confirm-transaction.duck.js | 8 ++- ui/helpers/constants/routes.js | 3 ++ ui/helpers/utils/token-util.js | 8 +-- ui/helpers/utils/transactions.util.js | 21 ++------ ui/helpers/utils/transactions.util.test.js | 20 ------- ui/hooks/useAssetDetails.js | 5 +- ui/hooks/useTokenData.js | 4 +- ui/hooks/useTokenDisplayValue.test.js | 9 ++-- .../confirm-approve/confirm-approve.util.js | 4 +- .../confirm-transaction-base.container.js | 7 ++- .../confirm-transaction-switch.component.js | 5 ++ .../confirm-token-transaction-switch.js | 24 +++++++++ ui/pages/swaps/view-quote/view-quote.js | 4 +- yarn.lock | 2 +- 21 files changed, 142 insertions(+), 66 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index a3afaeebb..1997ea777 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2594,6 +2594,9 @@ "rpcUrl": { "message": "New RPC URL" }, + "safeTransferFrom": { + "message": "Safe Transfer From" + }, "save": { "message": "Save" }, diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index bd5fbdb5e..2abae9066 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -85,8 +85,8 @@ import { import { hexToDecimal } from '../../ui/helpers/utils/conversions.util'; import { getTokenValueParam } from '../../ui/helpers/utils/token-util'; -import { getTransactionData } from '../../ui/helpers/utils/transactions.util'; import { isEqualCaseInsensitive } from '../../shared/modules/string-utils'; +import { parseStandardTokenTransactionData } from '../../shared/modules/transaction.utils'; import ComposableObservableStore from './lib/ComposableObservableStore'; import AccountTracker from './lib/account-tracker'; import createLoggerMiddleware from './lib/createLoggerMiddleware'; @@ -777,7 +777,7 @@ export default class MetamaskController extends EventEmitter { from: userAddress, } = txMeta.txParams; const { chainId } = txMeta; - const transactionData = getTransactionData(data); + const transactionData = parseStandardTokenTransactionData(data); const tokenAmountOrTokenId = getTokenValueParam(transactionData); const { allCollectibles } = this.collectiblesController.state; diff --git a/package.json b/package.json index 65fb850f6..5b17dcc77 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,7 @@ "@metamask/iframe-execution-environment-service": "^0.10.2", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^3.1.1", + "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/obs-store": "^5.0.0", "@metamask/post-message-stream": "^4.0.0", "@metamask/providers": "^8.1.1", diff --git a/shared/constants/transaction.js b/shared/constants/transaction.js index b1ea01c39..1e461f491 100644 --- a/shared/constants/transaction.js +++ b/shared/constants/transaction.js @@ -48,6 +48,7 @@ export const TRANSACTION_TYPES = { RETRY: 'retry', TOKEN_METHOD_TRANSFER: 'transfer', TOKEN_METHOD_TRANSFER_FROM: 'transferfrom', + TOKEN_METHOD_SAFE_TRANSFER_FROM: 'safetransferfrom', TOKEN_METHOD_APPROVE: 'approve', INCOMING: 'incoming', SIMPLE_SEND: 'simpleSend', diff --git a/shared/modules/transaction.utils.js b/shared/modules/transaction.utils.js index e79e569c3..08adb46e3 100644 --- a/shared/modules/transaction.utils.js +++ b/shared/modules/transaction.utils.js @@ -1,6 +1,6 @@ import { isHexString } from 'ethereumjs-util'; import { ethers } from 'ethers'; -import abi from 'human-standard-token-abi'; +import { abiERC721, abiERC20, abiERC1155 } from '@metamask/metamask-eth-abis'; import log from 'loglevel'; import { TOKEN_STANDARDS } from '../../ui/helpers/constants/common'; import { ASSET_TYPES, TRANSACTION_TYPES } from '../constants/transaction'; @@ -19,7 +19,22 @@ import { isEqualCaseInsensitive } from './string-utils'; * code */ -const hstInterface = new ethers.utils.Interface(abi); +/** + * @typedef EthersContractCall + * @type object + * @property {any[]} args - The args/params to the function call. + * An array-like object with numerical and string indices. + * @property {string} name - The name of the function. + * @property {string} signature - The function signature. + * @property {string} sighash - The function signature hash. + * @property {EthersBigNumber} value - The ETH value associated with the call. + * @property {FunctionFragment} functionFragment - The Ethers function fragment + * representation of the function. + */ + +const erc20Interface = new ethers.utils.Interface(abiERC20); +const erc721Interface = new ethers.utils.Interface(abiERC721); +const erc1155Interface = new ethers.utils.Interface(abiERC1155); export function transactionMatchesNetwork(transaction, chainId, networkId) { if (typeof transaction.chainId !== 'undefined') { @@ -83,6 +98,36 @@ export function txParamsAreDappSuggested(transaction) { ); } +/** + * Attempts to decode transaction data using ABIs for three different token standards: ERC20, ERC721, ERC1155. + * The data will decode correctly if the transaction is an interaction with a contract that matches one of these + * contract standards + * + * @param data - encoded transaction data + * @returns {EthersContractCall | undefined} + */ +export function parseStandardTokenTransactionData(data) { + try { + return erc20Interface.parseTransaction({ data }); + } catch { + // ignore and next try to parse with erc721 ABI + } + + try { + return erc721Interface.parseTransaction({ data }); + } catch { + // ignore and next try to parse with erc1155 ABI + } + + try { + return erc1155Interface.parseTransaction({ data }); + } catch { + // ignore and return undefined + } + + return undefined; +} + /** * Determines the type of the transaction by analyzing the txParams. * This method will return one of the types defined in shared/constants/transactions @@ -98,7 +143,7 @@ export async function determineTransactionType(txParams, query) { const { data, to } = txParams; let name; try { - name = data && hstInterface.parseTransaction({ data }).name; + ({ name } = data && parseStandardTokenTransactionData(data)); } catch (error) { log.debug('Failed to parse transaction data.', error, data); } @@ -107,6 +152,7 @@ export async function determineTransactionType(txParams, query) { TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM, ].find((methodName) => isEqualCaseInsensitive(methodName, name)); let result; diff --git a/shared/modules/transaction.utils.test.js b/shared/modules/transaction.utils.test.js index f6d816160..fba8c7827 100644 --- a/shared/modules/transaction.utils.test.js +++ b/shared/modules/transaction.utils.test.js @@ -5,9 +5,28 @@ import { determineTransactionType, isEIP1559Transaction, isLegacyTransaction, + parseStandardTokenTransactionData, } from './transaction.utils'; describe('Transaction.utils', function () { + describe('parseStandardTokenTransactionData', () => { + it('should return token data', () => { + const tokenData = parseStandardTokenTransactionData( + '0xa9059cbb00000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000004e20', + ); + expect(tokenData).toStrictEqual(expect.anything()); + const { name, args } = tokenData; + expect(name).toStrictEqual(TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER); + const to = args._to; + const value = args._value.toString(); + expect(to).toStrictEqual('0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706'); + expect(value).toStrictEqual('20000'); + }); + + it('should not throw errors when called without arguments', () => { + expect(() => parseStandardTokenTransactionData()).not.toThrow(); + }); + }); describe('isEIP1559Transaction', function () { it('should return true if both maxFeePerGas and maxPriorityFeePerGas are hex strings', () => { expect( diff --git a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js index 7da4ddeba..218fc99a7 100644 --- a/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js +++ b/ui/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js @@ -38,6 +38,7 @@ const ConfirmPageContainerSummary = (props) => { TRANSACTION_TYPES.CONTRACT_INTERACTION, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM, ]; const isContractTypeTransaction = contractInitiatedTransactionType.includes( transactionType, @@ -49,7 +50,8 @@ const ConfirmPageContainerSummary = (props) => { // type of contract interaction it is passed as toAddress contractAddress = transactionType === TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER || - transactionType === TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM + transactionType === TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM || + transactionType === TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM ? tokenAddress : toAddress; } diff --git a/ui/ducks/confirm-transaction/confirm-transaction.duck.js b/ui/ducks/confirm-transaction/confirm-transaction.duck.js index c05050f28..b16d60312 100644 --- a/ui/ducks/confirm-transaction/confirm-transaction.duck.js +++ b/ui/ducks/confirm-transaction/confirm-transaction.duck.js @@ -13,14 +13,12 @@ import { addEth, } from '../../helpers/utils/confirm-tx.util'; -import { - getTransactionData, - sumHexes, -} from '../../helpers/utils/transactions.util'; +import { sumHexes } from '../../helpers/utils/transactions.util'; import { conversionUtil } from '../../../shared/modules/conversion.utils'; import { getAveragePriceEstimateInHexWEI } from '../../selectors/custom-gas'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; +import { parseStandardTokenTransactionData } from '../../../shared/modules/transaction.utils'; // Actions const createActionType = (action) => `metamask/confirm-transaction/${action}`; @@ -285,7 +283,7 @@ export function setTransactionToConfirm(transactionId) { if (txParams.data) { const { to: tokenAddress, data } = txParams; - const tokenData = getTransactionData(data); + const tokenData = parseStandardTokenTransactionData(data); const tokens = getTokens(state); const currentToken = tokens?.find(({ address }) => isEqualCaseInsensitive(tokenAddress, address), diff --git a/ui/helpers/constants/routes.js b/ui/helpers/constants/routes.js index 83d659dbf..519e0a098 100644 --- a/ui/helpers/constants/routes.js +++ b/ui/helpers/constants/routes.js @@ -88,6 +88,7 @@ const CONFIRM_SEND_TOKEN_PATH = '/send-token'; const CONFIRM_DEPLOY_CONTRACT_PATH = '/deploy-contract'; const CONFIRM_APPROVE_PATH = '/approve'; const CONFIRM_TRANSFER_FROM_PATH = '/transfer-from'; +const CONFIRM_SAFE_TRANSFER_FROM_PATH = '/safe-transfer-from'; const CONFIRM_TOKEN_METHOD_PATH = '/token-method'; const SIGNATURE_REQUEST_PATH = '/signature-request'; const DECRYPT_MESSAGE_REQUEST_PATH = '/decrypt-message-request'; @@ -140,6 +141,7 @@ const PATH_NAME_MAP = { [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_DEPLOY_CONTRACT_PATH}`]: 'Confirm Deploy Contract Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_APPROVE_PATH}`]: 'Confirm Approve Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_TRANSFER_FROM_PATH}`]: 'Confirm Transfer From Transaction Page', + [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_SAFE_TRANSFER_FROM_PATH}`]: 'Confirm Safe Transfer From Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${SIGNATURE_REQUEST_PATH}`]: 'Signature Request Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${DECRYPT_MESSAGE_REQUEST_PATH}`]: 'Decrypt Message Request Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${ENCRYPTION_PUBLIC_KEY_REQUEST_PATH}`]: 'Encryption Public Key Request Page', @@ -200,6 +202,7 @@ export { CONFIRM_DEPLOY_CONTRACT_PATH, CONFIRM_APPROVE_PATH, CONFIRM_TRANSFER_FROM_PATH, + CONFIRM_SAFE_TRANSFER_FROM_PATH, CONFIRM_TOKEN_METHOD_PATH, SIGNATURE_REQUEST_PATH, DECRYPT_MESSAGE_REQUEST_PATH, diff --git a/ui/helpers/utils/token-util.js b/ui/helpers/utils/token-util.js index a75db6da6..b934ed176 100644 --- a/ui/helpers/utils/token-util.js +++ b/ui/helpers/utils/token-util.js @@ -7,15 +7,14 @@ import { import { getTokenStandardAndDetails } from '../../store/actions'; import { ERC1155, ERC721 } from '../constants/common'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; +import { parseStandardTokenTransactionData } from '../../../shared/modules/transaction.utils'; import * as util from './util'; import { formatCurrency } from './confirm-tx.util'; -import { getTransactionData } from './transactions.util'; const DEFAULT_SYMBOL = ''; async function getSymbolFromContract(tokenAddress) { const token = util.getContractAtAddress(tokenAddress); - try { const result = await token.symbol(); return result[0]; @@ -136,7 +135,8 @@ export function calcTokenValue(value, decimals) { * @returns {string | undefined} A lowercase address string. */ export function getTokenAddressParam(tokenData = {}) { - const value = tokenData?.args?._to || tokenData?.args?.[0]; + const value = + tokenData?.args?._to || tokenData?.args?.to || tokenData?.args?.[0]; return value?.toString().toLowerCase(); } @@ -223,7 +223,7 @@ export async function getAssetDetails( transactionData, existingCollectibles, ) { - const tokenData = getTransactionData(transactionData); + const tokenData = parseStandardTokenTransactionData(transactionData); if (!tokenData) { throw new Error('Unable to detect valid token data'); } diff --git a/ui/helpers/utils/transactions.util.js b/ui/helpers/utils/transactions.util.js index 6bdf6f548..25a38593f 100644 --- a/ui/helpers/utils/transactions.util.js +++ b/ui/helpers/utils/transactions.util.js @@ -1,6 +1,4 @@ import { MethodRegistry } from 'eth-method-registry'; -import abi from 'human-standard-token-abi'; -import { ethers } from 'ethers'; import log from 'loglevel'; import { addHexPrefix } from '../../../app/scripts/lib/util'; @@ -14,8 +12,6 @@ import { addCurrencies } from '../../../shared/modules/conversion.utils'; import { readAddressAsContract } from '../../../shared/modules/contract-utils'; import fetchWithCache from './fetch-with-cache'; -const hstInterface = new ethers.utils.Interface(abi); - /** * @typedef EthersContractCall * @type object @@ -29,19 +25,6 @@ const hstInterface = new ethers.utils.Interface(abi); * representation of the function. */ -/** - * @param data - * @returns {EthersContractCall | undefined} - */ -export function getTransactionData(data) { - try { - return hstInterface.parseTransaction({ data }); - } catch (error) { - log.debug('Failed to parse transaction data.', error, data); - return undefined; - } -} - async function getMethodFrom4Byte(fourBytePrefix) { const fourByteResponse = await fetchWithCache( `https://www.4byte.directory/api/v1/signatures/?hex_signature=${fourBytePrefix}`, @@ -122,6 +105,7 @@ export function isTokenMethodAction(type) { TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER, TRANSACTION_TYPES.TOKEN_METHOD_APPROVE, TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM, + TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM, ].includes(type); } @@ -215,6 +199,9 @@ export function getTransactionTypeTitle(t, type, nativeCurrency = 'ETH') { case TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER_FROM: { return t('transferFrom'); } + case TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM: { + return t('safeTransferFrom'); + } case TRANSACTION_TYPES.TOKEN_METHOD_APPROVE: { return t('approve'); } diff --git a/ui/helpers/utils/transactions.util.test.js b/ui/helpers/utils/transactions.util.test.js index ce5225076..591e46d07 100644 --- a/ui/helpers/utils/transactions.util.test.js +++ b/ui/helpers/utils/transactions.util.test.js @@ -1,5 +1,4 @@ import { - TRANSACTION_TYPES, TRANSACTION_GROUP_STATUSES, TRANSACTION_STATUSES, TRANSACTION_ENVELOPE_TYPES, @@ -7,25 +6,6 @@ import { import * as utils from './transactions.util'; describe('Transactions utils', () => { - describe('getTransactionData', () => { - it('should return token data', () => { - const tokenData = utils.getTransactionData( - '0xa9059cbb00000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000004e20', - ); - expect(tokenData).toStrictEqual(expect.anything()); - const { name, args } = tokenData; - expect(name).toStrictEqual(TRANSACTION_TYPES.TOKEN_METHOD_TRANSFER); - const to = args._to; - const value = args._value.toString(); - expect(to).toStrictEqual('0x50A9D56C2B8BA9A5c7f2C08C3d26E0499F23a706'); - expect(value).toStrictEqual('20000'); - }); - - it('should not throw errors when called without arguments', () => { - expect(() => utils.getTransactionData()).not.toThrow(); - }); - }); - describe('getStatusKey', () => { it('should return the correct status', () => { const tests = [ diff --git a/ui/hooks/useAssetDetails.js b/ui/hooks/useAssetDetails.js index ac12ed494..ce9ef30ba 100644 --- a/ui/hooks/useAssetDetails.js +++ b/ui/hooks/useAssetDetails.js @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; +import { parseStandardTokenTransactionData } from '../../shared/modules/transaction.utils'; import { getCollectibles, getTokens } from '../ducks/metamask/metamask'; import { ERC1155, ERC721, ERC20 } from '../helpers/constants/common'; import { @@ -8,14 +9,12 @@ import { getTokenAddressParam, getTokenValueParam, } from '../helpers/utils/token-util'; -import { getTransactionData } from '../helpers/utils/transactions.util'; import { getTokenList } from '../selectors'; import { hideLoadingIndication, showLoadingIndication } from '../store/actions'; import { usePrevious } from './usePrevious'; export function useAssetDetails(tokenAddress, userAddress, transactionData) { const dispatch = useDispatch(); - // state selectors const tokens = useSelector(getTokens); const collectibles = useSelector(getCollectibles); @@ -84,7 +83,7 @@ export function useAssetDetails(tokenAddress, userAddress, transactionData) { balance, decimals: currentAssetDecimals, } = currentAsset; - const tokenData = getTransactionData(transactionData); + const tokenData = parseStandardTokenTransactionData(transactionData); assetStandard = standard; assetAddress = tokenAddress; tokenSymbol = symbol; diff --git a/ui/hooks/useTokenData.js b/ui/hooks/useTokenData.js index d1d7e1ffe..654bb50ff 100644 --- a/ui/hooks/useTokenData.js +++ b/ui/hooks/useTokenData.js @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { getTransactionData } from '../helpers/utils/transactions.util'; +import { parseStandardTokenTransactionData } from '../../shared/modules/transaction.utils'; /** * useTokenData @@ -19,6 +19,6 @@ export function useTokenData(transactionData, isTokenTransaction = true) { if (!isTokenTransaction || !transactionData) { return null; } - return getTransactionData(transactionData); + return parseStandardTokenTransactionData(transactionData); }, [isTokenTransaction, transactionData]); } diff --git a/ui/hooks/useTokenDisplayValue.test.js b/ui/hooks/useTokenDisplayValue.test.js index 9be126f81..26e2a4374 100644 --- a/ui/hooks/useTokenDisplayValue.test.js +++ b/ui/hooks/useTokenDisplayValue.test.js @@ -1,7 +1,7 @@ import { renderHook } from '@testing-library/react-hooks'; import sinon from 'sinon'; import * as tokenUtil from '../helpers/utils/token-util'; -import * as txUtil from '../helpers/utils/transactions.util'; +import * as txUtil from '../../shared/modules/transaction.utils'; import { useTokenDisplayValue } from './useTokenDisplayValue'; const tests = [ @@ -122,9 +122,12 @@ describe('useTokenDisplayValue', () => { describe(`when input is decimals: ${token.decimals} and value: ${tokenValue}`, () => { it(`should return ${displayValue} as displayValue`, () => { const getTokenValueStub = sinon.stub(tokenUtil, 'getTokenValueParam'); - const getTokenDataStub = sinon.stub(txUtil, 'getTransactionData'); + const parseStandardTokenTransactionDataStub = sinon.stub( + txUtil, + 'parseStandardTokenTransactionData', + ); - getTokenDataStub.callsFake(() => tokenData); + parseStandardTokenTransactionDataStub.callsFake(() => tokenData); getTokenValueStub.callsFake(() => tokenValue); const { result } = renderHook(() => diff --git a/ui/pages/confirm-approve/confirm-approve.util.js b/ui/pages/confirm-approve/confirm-approve.util.js index 7bc3ea550..022dc108a 100644 --- a/ui/pages/confirm-approve/confirm-approve.util.js +++ b/ui/pages/confirm-approve/confirm-approve.util.js @@ -1,16 +1,16 @@ import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; +import { parseStandardTokenTransactionData } from '../../../shared/modules/transaction.utils'; import { decimalToHex } from '../../helpers/utils/conversions.util'; import { calcTokenValue, getTokenAddressParam, } from '../../helpers/utils/token-util'; -import { getTransactionData } from '../../helpers/utils/transactions.util'; export function getCustomTxParamsData( data, { customPermissionAmount, decimals }, ) { - const tokenData = getTransactionData(data); + const tokenData = parseStandardTokenTransactionData(data); if (!tokenData) { throw new Error('Invalid data'); diff --git a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js index e5c325242..e375a3c96 100644 --- a/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -43,6 +43,7 @@ import { } from '../../ducks/metamask/metamask'; import { + parseStandardTokenTransactionData, transactionMatchesNetwork, txParamsAreDappSuggested, } from '../../../shared/modules/transaction.utils'; @@ -52,6 +53,7 @@ import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app'; import { isLegacyTransaction } from '../../helpers/utils/transactions.util'; import { CUSTOM_GAS_ESTIMATE } from '../../../shared/constants/gas'; import { isEqualCaseInsensitive } from '../../../shared/modules/string-utils'; +import { getTokenAddressParam } from '../../helpers/utils/token-util'; import ConfirmTransactionBase from './confirm-transaction-base.component'; let customNonceValue = ''; @@ -104,9 +106,12 @@ const mapStateToProps = (state, ownProps) => { } = (transaction && transaction.txParams) || txParams; const accounts = getMetaMaskAccounts(state); + const transactionData = parseStandardTokenTransactionData(data); + const tokenToAddress = getTokenAddressParam(transactionData); + const { balance } = accounts[fromAddress]; const { name: fromName } = identities[fromAddress]; - const toAddress = propsToAddress || txParamsToAddress; + const toAddress = propsToAddress || tokenToAddress || txParamsToAddress; const tokenList = getTokenList(state); const useTokenDetection = getUseTokenDetection(state); diff --git a/ui/pages/confirm-transaction-switch/confirm-transaction-switch.component.js b/ui/pages/confirm-transaction-switch/confirm-transaction-switch.component.js index 7e9882d65..db58cc640 100644 --- a/ui/pages/confirm-transaction-switch/confirm-transaction-switch.component.js +++ b/ui/pages/confirm-transaction-switch/confirm-transaction-switch.component.js @@ -13,6 +13,7 @@ import { SIGNATURE_REQUEST_PATH, DECRYPT_MESSAGE_REQUEST_PATH, ENCRYPTION_PUBLIC_KEY_REQUEST_PATH, + CONFIRM_SAFE_TRANSFER_FROM_PATH, } from '../../helpers/constants/routes'; import { MESSAGE_TYPE } from '../../../shared/constants/app'; import { TRANSACTION_TYPES } from '../../../shared/constants/transaction'; @@ -50,6 +51,10 @@ export default class ConfirmTransactionSwitch extends Component { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TRANSFER_FROM_PATH}`; return ; } + case TRANSACTION_TYPES.TOKEN_METHOD_SAFE_TRANSFER_FROM: { + const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_SAFE_TRANSFER_FROM_PATH}`; + return ; + } default: { const pathname = `${CONFIRM_TRANSACTION_ROUTE}/${id}${CONFIRM_TOKEN_METHOD_PATH}`; return ; diff --git a/ui/pages/confirm-transaction/confirm-token-transaction-switch.js b/ui/pages/confirm-transaction/confirm-token-transaction-switch.js index ea06c0d0b..036f2b149 100644 --- a/ui/pages/confirm-transaction/confirm-token-transaction-switch.js +++ b/ui/pages/confirm-transaction/confirm-token-transaction-switch.js @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'; import { Switch, Route } from 'react-router-dom'; import { CONFIRM_APPROVE_PATH, + CONFIRM_SAFE_TRANSFER_FROM_PATH, CONFIRM_SEND_TOKEN_PATH, CONFIRM_TRANSACTION_ROUTE, CONFIRM_TRANSFER_FROM_PATH, @@ -88,6 +89,29 @@ export default function ConfirmTokenTransactionSwitch({ transaction }) { /> )} /> + ( + + )} + /> Date: Fri, 18 Mar 2022 10:16:11 -0500 Subject: [PATCH 040/192] ToggleButton: Use label so users can click text (#13876) --- test/e2e/tests/send-eth.spec.js | 4 ++-- ui/components/ui/toggle-button/index.scss | 2 ++ ui/components/ui/toggle-button/toggle-button.component.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/e2e/tests/send-eth.spec.js b/test/e2e/tests/send-eth.spec.js index f17f116d9..fab46be79 100644 --- a/test/e2e/tests/send-eth.spec.js +++ b/test/e2e/tests/send-eth.spec.js @@ -190,7 +190,7 @@ describe('Send ETH from dapp using advanced gas controls', function () { await driver.clickElement({ text: 'Settings', tag: 'div' }); await driver.clickElement({ text: 'Advanced', tag: 'div' }); await driver.clickElement( - '[data-testid="advanced-setting-show-testnet-conversion"] .settings-page__content-item-col > div > div', + '[data-testid="advanced-setting-show-testnet-conversion"] .settings-page__content-item-col > label > div', ); const advancedGasTitle = await driver.findElement({ text: 'Advanced gas controls', @@ -198,7 +198,7 @@ describe('Send ETH from dapp using advanced gas controls', function () { }); await driver.scrollToElement(advancedGasTitle); await driver.clickElement( - '[data-testid="advanced-setting-advanced-gas-inline"] .settings-page__content-item-col > div > div', + '[data-testid="advanced-setting-advanced-gas-inline"] .settings-page__content-item-col > label > div', ); windowHandles = await driver.getAllWindowHandles(); extension = windowHandles[0]; diff --git a/ui/components/ui/toggle-button/index.scss b/ui/components/ui/toggle-button/index.scss index 57bbd4505..503a7f1d0 100644 --- a/ui/components/ui/toggle-button/index.scss +++ b/ui/components/ui/toggle-button/index.scss @@ -1,5 +1,7 @@ .toggle-button { display: flex; + cursor: pointer; + $self: &; &__status { diff --git a/ui/components/ui/toggle-button/toggle-button.component.js b/ui/components/ui/toggle-button/toggle-button.component.js index 271707cbe..10a2bb538 100644 --- a/ui/components/ui/toggle-button/toggle-button.component.js +++ b/ui/components/ui/toggle-button/toggle-button.component.js @@ -52,7 +52,7 @@ const ToggleButton = (props) => { const modifier = value ? 'on' : 'off'; return ( -
{ if (e.key === 'Enter') { @@ -82,7 +82,7 @@ const ToggleButton = (props) => { {offLabel} {onLabel}
-
+ ); }; From 6fd037f1e6f5e582d6e4d3e8b763d91a28075700 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 18 Mar 2022 11:06:35 -0500 Subject: [PATCH 041/192] fix missing insufficient funds error for token sends (#14026) --- .../confirm-page-container-content.component.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 16f89f91e..b9e4ee86e 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 @@ -146,8 +146,7 @@ export default class ConfirmPageContainerContent extends Component { supportsEIP1559V2 && !hasSimulationError && (errorKey || errorMessage) && - errorKey === INSUFFICIENT_FUNDS_ERROR_KEY && - currentTransaction.type === TRANSACTION_TYPES.SIMPLE_SEND; + errorKey === INSUFFICIENT_FUNDS_ERROR_KEY; return (
Date: Fri, 18 Mar 2022 18:07:12 +0100 Subject: [PATCH 042/192] snaps-skunkworks@0.10.3 (#14041) --- package.json | 6 +++--- yarn.lock | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index 5b17dcc77..63c4daaeb 100644 --- a/package.json +++ b/package.json @@ -114,17 +114,17 @@ "@metamask/eth-ledger-bridge-keyring": "^0.10.0", "@metamask/eth-token-tracker": "^4.0.0", "@metamask/etherscan-link": "^2.1.0", - "@metamask/iframe-execution-environment-service": "^0.10.2", + "@metamask/iframe-execution-environment-service": "^0.10.3", "@metamask/jazzicon": "^2.0.0", "@metamask/logo": "^3.1.1", "@metamask/metamask-eth-abis": "^3.0.0", "@metamask/obs-store": "^5.0.0", "@metamask/post-message-stream": "^4.0.0", "@metamask/providers": "^8.1.1", - "@metamask/rpc-methods": "^0.10.0", + "@metamask/rpc-methods": "^0.10.3", "@metamask/slip44": "^2.0.0", "@metamask/smart-transactions-controller": "^1.9.1", - "@metamask/snap-controllers": "^0.10.2", + "@metamask/snap-controllers": "^0.10.3", "@ngraveio/bc-ur": "^1.1.6", "@popperjs/core": "^2.4.0", "@reduxjs/toolkit": "^1.6.2", diff --git a/yarn.lock b/yarn.lock index 6a31b63cc..d8c23e18b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2851,15 +2851,15 @@ resolved "https://registry.yarnpkg.com/@metamask/etherscan-link/-/etherscan-link-2.1.0.tgz#c0be8e68445b7b83cf85bcc03a56cdf8e256c973" integrity sha512-ADuWlTUkFfN2vXlz81Bg/0BA+XRor+CdK1055p6k7H6BLIPoDKn9SBOFld9haQFuR9cKh/JYHcnlSIv5R4fUEw== -"@metamask/execution-environments@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@metamask/execution-environments/-/execution-environments-0.10.2.tgz#dfa4750a0eee4f51d9bc7e3c75a0e80a18798093" - integrity sha512-4bqDTk0oPRiju21M8KNaoxT8eiGaygyC2pldIrCDByfDqiIVkIpv8neol6EEH7ebMQkNiC4sr8IhfNFL7cJIdA== +"@metamask/execution-environments@^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@metamask/execution-environments/-/execution-environments-0.10.3.tgz#3a080523a399614b4b993d87e6bb933ccc3bcf24" + integrity sha512-03zOThe9QhopfMHB8wlpOCLtxhKyPiyxr0RM97xBeKSXHgItsqRL8BBi9LW+ww8JEp9MAD2Bnbt1LEzSN5QjqA== dependencies: "@metamask/object-multiplex" "^1.2.0" "@metamask/post-message-stream" "^4.0.0" "@metamask/providers" "^8.1.1" - "@metamask/snap-types" "^0.10.1" + "@metamask/snap-types" "^0.10.3" cross-fetch "^3.1.5" eth-rpc-errors "^4.0.3" pump "^3.0.0" @@ -2871,17 +2871,17 @@ resolved "https://registry.yarnpkg.com/@metamask/forwarder/-/forwarder-1.1.0.tgz#13829d8244bbf19ea658c0b20d21a77b67de0bdd" integrity sha512-Hggj4y0QIjDzKGTXzarhEPIQyFSB2bi2y6YLJNwaT4JmP30UB5Cj6gqoY0M4pj3QT57fzp0BUuGp7F/AUe28tw== -"@metamask/iframe-execution-environment-service@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@metamask/iframe-execution-environment-service/-/iframe-execution-environment-service-0.10.2.tgz#85e38616af2a46b170c4940e2d7c5cd8eeaa4c48" - integrity sha512-99hAcMyeqacmhh4dsD4my55Y6g5v2L6ftXmTu7cfl+EKy39t5miWSKTGbL4dDocsAiKI/7nI9LMyyWFgcDCx8Q== +"@metamask/iframe-execution-environment-service@^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@metamask/iframe-execution-environment-service/-/iframe-execution-environment-service-0.10.3.tgz#47059dcdac4ca0b6009a5c8c9e3488f3467effa0" + integrity sha512-4fJnsNC7drDXo3Eg8UfCNm9uwDKOo8W/AU4izFXXFjzkd5dVSfo2tWSdGMDJj1sxdgU6O1vr12yc9HxbnQXt9Q== dependencies: "@metamask/controllers" "^26.0.0" - "@metamask/execution-environments" "^0.10.2" + "@metamask/execution-environments" "^0.10.3" "@metamask/object-multiplex" "^1.2.0" "@metamask/post-message-stream" "^4.0.0" - "@metamask/snap-controllers" "^0.10.2" - "@metamask/snap-types" "^0.10.1" + "@metamask/snap-controllers" "^0.10.3" + "@metamask/snap-types" "^0.10.3" eth-rpc-errors "^4.0.3" json-rpc-engine "^6.1.0" json-rpc-middleware-stream "^3.0.0" @@ -2975,14 +2975,14 @@ pump "^3.0.0" webextension-polyfill-ts "^0.25.0" -"@metamask/rpc-methods@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@metamask/rpc-methods/-/rpc-methods-0.10.0.tgz#8d7ea5e378a9144b4171f4f846d06d10657ed02e" - integrity sha512-nHFO8Dg4L422cKMgLXnfkX0F3z7j3N/7KyLPgxCoOhHvFz35uwC1jxz9WWF2+yv7j1Y8hVkRg4umyg76/IXZLg== +"@metamask/rpc-methods@^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@metamask/rpc-methods/-/rpc-methods-0.10.3.tgz#75816fd9fd14313d634a55e3877189ce8f102626" + integrity sha512-gEllV6CVpzjhjwGBFz2YgOov0vYXsYnpu5eg+0g8FMTGqhsgLuwLVEvPuAWKf9h+yR+Oflx+DRnKNrxtV/P/eg== dependencies: "@metamask/controllers" "^26.0.0" "@metamask/key-tree" "^3.0.1" - "@metamask/snap-controllers" "^0.10.0" + "@metamask/snap-controllers" "^0.10.3" "@metamask/types" "^1.1.0" eth-rpc-errors "^4.0.2" @@ -3009,13 +3009,13 @@ isomorphic-fetch "^3.0.0" lodash "^4.17.21" -"@metamask/snap-controllers@^0.10.0", "@metamask/snap-controllers@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@metamask/snap-controllers/-/snap-controllers-0.10.2.tgz#0261ff82dd384f8a9398116967cfa2f7eb44b063" - integrity sha512-KFM7U6hCmUjevLK2hYUMcqRKtxK3/J2cI8uUbE1rx4zwBfDuN58RfI1s+69rZtblucqpnuqKs+Mc56lxb6+6oQ== +"@metamask/snap-controllers@^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@metamask/snap-controllers/-/snap-controllers-0.10.3.tgz#5cd0cf22ddccf83bc7b52ef86f5cc7d44868d877" + integrity sha512-l8haEQ6B1bhiWN0WDXST3eHFn/hgE9bG+PvcjMRkd7ENOQptTjCKqiC4CojpEuY+VoHZ519CK7qZv+Zg4yQqOw== dependencies: "@metamask/controllers" "^26.0.0" - "@metamask/execution-environments" "^0.10.2" + "@metamask/execution-environments" "^0.10.3" "@metamask/object-multiplex" "^1.1.0" "@metamask/obs-store" "^7.0.0" "@metamask/post-message-stream" "4.0.0" @@ -3038,10 +3038,10 @@ semver "^7.3.5" tar-stream "^2.2.0" -"@metamask/snap-types@^0.10.1": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@metamask/snap-types/-/snap-types-0.10.1.tgz#dd170813d38091473f9ae1fd1e9d64c46666ba0c" - integrity sha512-DsTAMSNmVWH/wXL4OWvnI4Wxh247d7PPD0jjxlMC3hEKB6hSdbCW3umwxqBCxgrU18gJOGwNJMygTolxO0SUrA== +"@metamask/snap-types@^0.10.3": + version "0.10.3" + resolved "https://registry.yarnpkg.com/@metamask/snap-types/-/snap-types-0.10.3.tgz#733cbba058489eb084590788e9d9ad1eeff2a35a" + integrity sha512-Rdus61liExENanzBtu9QYRScyqzOQGvXuaaZJAVJN5TnsIt2hsOq9D6wktKvT3IHeKCF9ydFq4YWam2RcNccoQ== dependencies: "@metamask/controllers" "^26.0.0" From 3bdfd7f6a0d6818f9e4a7c7c7efecb949405a920 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 18 Mar 2022 12:35:43 -0500 Subject: [PATCH 043/192] Dark Mode: Settings Search Bar (#13997) --- ui/pages/settings/settings-search/settings-search.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ui/pages/settings/settings-search/settings-search.js b/ui/pages/settings/settings-search/settings-search.js index 57b206684..a28561afd 100644 --- a/ui/pages/settings/settings-search/settings-search.js +++ b/ui/pages/settings/settings-search/settings-search.js @@ -15,7 +15,9 @@ export default function SettingsSearch({ const t = useContext(I18nContext); const [searchQuery, setSearchQuery] = useState(''); - const [searchIconColor, setSearchIconColor] = useState('#9b9b9b'); + const [searchIconColor, setSearchIconColor] = useState( + 'var(--color-icon-muted)', + ); const settingsRoutesListArray = Object.values(settingsRoutesList); const settingsSearchFuse = new Fuse(settingsRoutesListArray, { @@ -32,9 +34,9 @@ export default function SettingsSearch({ const handleSearch = (searchQuery) => { setSearchQuery(searchQuery); if (searchQuery === '') { - setSearchIconColor('#9b9b9b'); + setSearchIconColor('var(--color-icon-muted)'); } else { - setSearchIconColor('#24292E'); + setSearchIconColor('var(--color-icon-default)'); } const fuseSearchResult = settingsSearchFuse.search(searchQuery); const addressSearchResult = settingsRoutesListArray.filter((routes) => { @@ -91,7 +93,6 @@ export default function SettingsSearch({ fullWidth autoFocus autoComplete="off" - style={{ backgroundColor: '#fff' }} startAdornment={renderStartAdornment()} endAdornment={renderEndAdornment()} /> From 0c8c2725217e4d8f4c055d02ce5fe875e7edadbe Mon Sep 17 00:00:00 2001 From: ryanml Date: Fri, 18 Mar 2022 10:40:44 -0700 Subject: [PATCH 044/192] Removing iconClassName prop from NetworkDisplay (#14035) --- ui/components/app/network-display/network-display.js | 11 +---------- .../app/network-display/network-display.stories.js | 6 ------ 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/ui/components/app/network-display/network-display.js b/ui/components/app/network-display/network-display.js index 5fd28809c..29e90ff3d 100644 --- a/ui/components/app/network-display/network-display.js +++ b/ui/components/app/network-display/network-display.js @@ -22,7 +22,6 @@ import { isNetworkLoading } from '../../../selectors'; export default function NetworkDisplay({ colored, outline, - iconClassName, indicatorSize, disabled, labelProps, @@ -61,14 +60,7 @@ export default function NetworkDisplay({ /> } - rightIcon={ - iconClassName && ( - - ) - } + rightIcon={} label={ networkType === NETWORK_TYPE_RPC ? networkNickname ?? t('privateNetwork') @@ -100,7 +92,6 @@ NetworkDisplay.propTypes = { }), outline: PropTypes.bool, disabled: PropTypes.bool, - iconClassName: PropTypes.string, onClick: PropTypes.func, }; diff --git a/ui/components/app/network-display/network-display.stories.js b/ui/components/app/network-display/network-display.stories.js index 42019d5d4..7799589bb 100644 --- a/ui/components/app/network-display/network-display.stories.js +++ b/ui/components/app/network-display/network-display.stories.js @@ -23,16 +23,10 @@ export default { disabled: { control: 'boolean', }, - iconClassName: { - control: 'text', - }, onClick: { action: 'onClick', }, }, - args: { - iconClassName: 'caret', - }, }; export const DefaultStory = (args) => ; From 22306826ffe39de82eb7ecd8d3ebbd0e16647959 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 18 Mar 2022 18:45:23 +0100 Subject: [PATCH 045/192] Set Chrome logger to level 3: Log_Fatal (#14044) --- test/e2e/webdriver/chrome.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/webdriver/chrome.js b/test/e2e/webdriver/chrome.js index 05ce2b65d..13ff00f62 100644 --- a/test/e2e/webdriver/chrome.js +++ b/test/e2e/webdriver/chrome.js @@ -18,6 +18,7 @@ class ChromeDriver { if (responsive) { args.push('--auto-open-devtools-for-tabs'); } + args.push('--log-level=3'); const options = new chrome.Options().addArguments(args); options.setProxy(proxy.manual({ https: HTTPS_PROXY_HOST })); options.setAcceptInsecureCerts(true); From 093c69cf769876ff590bb8fb7bfa44fd01a95a69 Mon Sep 17 00:00:00 2001 From: seaona <54408225+seaona@users.noreply.github.com> Date: Fri, 18 Mar 2022 18:47:28 +0100 Subject: [PATCH 046/192] Fix flaky test: add account (#14045) --- test/e2e/tests/add-account.spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/e2e/tests/add-account.spec.js b/test/e2e/tests/add-account.spec.js index f9318cc7f..9c8603138 100644 --- a/test/e2e/tests/add-account.spec.js +++ b/test/e2e/tests/add-account.spec.js @@ -78,6 +78,7 @@ describe('Add account', function () { const detailsModal = await driver.findVisibleElement('span .modal'); // get the public address for the "second account" + await driver.waitForSelector('.qr-code__address'); const secondAccountAddress = await driver.findElement( '.qr-code__address', ); @@ -103,6 +104,7 @@ describe('Add account', function () { const secondDetailsModal = await driver.findVisibleElement( 'span .modal', ); + await driver.waitForSelector('.qr-code__address'); const thirdAccountAddress = await driver.findElement( '.qr-code__address', ); @@ -158,6 +160,7 @@ describe('Add account', function () { 'span .modal', ); // get the public address for the "second account" + await driver.waitForSelector('.qr-code__address'); const recreatedSecondAccountAddress = await driver.findElement( '.qr-code__address', ); @@ -184,6 +187,7 @@ describe('Add account', function () { ); // get the public address for the "third account" + await driver.waitForSelector('.qr-code__address'); const recreatedThirdAccountAddress = await driver.findElement( '.qr-code__address', ); From 8df8f81df785f2a2b08143bcb4a0f706a2404825 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 18 Mar 2022 14:07:05 -0500 Subject: [PATCH 047/192] Deprecate extensionizer for webextension-polyfill (#13960) * deprecate extensionizer for webextension-polyfill * fix tests * remove extensionizer * fix browser windows api calls * fix broken on firefox * fix getAcceptLanguages call * update more browser apis that are now promisified * remove unnecessary console error ignoring in e2e tests --- app/scripts/background.js | 17 +++---- app/scripts/contentscript.js | 8 +-- app/scripts/lib/createOnboardingMiddleware.js | 4 +- app/scripts/lib/ens-ipfs/setup.js | 11 ++-- .../lib/get-first-preferred-lang-code.js | 9 +--- app/scripts/lib/local-store.js | 12 ++--- app/scripts/lib/util.js | 5 +- app/scripts/metamask-controller.js | 4 +- app/scripts/metamask-controller.test.js | 4 +- app/scripts/phishing-detect.js | 4 +- app/scripts/platforms/extension.js | 51 ++++++++++--------- app/scripts/platforms/extension.test.js | 20 ++++---- app/scripts/ui.js | 6 +-- lavamoat/browserify/beta/policy.json | 15 +++--- lavamoat/browserify/flask/policy.json | 15 +++--- lavamoat/browserify/main/policy.json | 15 +++--- package.json | 2 +- test/helpers/setup-helper.js | 2 + ui/__mocks__/webextension-polyfill.js | 3 ++ ui/components/app/menu-bar/menu-bar.js | 4 +- .../onboarding-initiator-util.js | 16 +++--- yarn.lock | 10 ++-- 22 files changed, 124 insertions(+), 113 deletions(-) create mode 100644 ui/__mocks__/webextension-polyfill.js diff --git a/app/scripts/background.js b/app/scripts/background.js index 4e6176436..ae85d781b 100644 --- a/app/scripts/background.js +++ b/app/scripts/background.js @@ -6,7 +6,7 @@ import endOfStream from 'end-of-stream'; import pump from 'pump'; import debounce from 'debounce-stream'; import log from 'loglevel'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import { storeAsStream, storeTransformStream } from '@metamask/obs-store'; import PortStream from 'extension-port-stream'; import { captureException } from '@sentry/browser'; @@ -224,7 +224,7 @@ function setupController(initState, initLangCode) { // platform specific api platform, notificationManager, - extension, + browser, getRequestAccountTabIds: () => { return requestAccountTabIds; }, @@ -294,8 +294,8 @@ function setupController(initState, initLangCode) { // // connect to other contexts // - extension.runtime.onConnect.addListener(connectRemote); - extension.runtime.onConnectExternal.addListener(connectExternal); + browser.runtime.onConnect.addListener(connectRemote); + browser.runtime.onConnectExternal.addListener(connectExternal); const metamaskInternalProcessHash = { [ENVIRONMENT_TYPE_POPUP]: true, @@ -359,8 +359,7 @@ function setupController(initState, initLangCode) { isMetaMaskInternalProcess = metamaskInternalProcessHash[processName]; } else { isMetaMaskInternalProcess = - remotePort.sender.origin === - `chrome-extension://${extension.runtime.id}`; + remotePort.sender.origin === `chrome-extension://${browser.runtime.id}`; } if (isMetaMaskInternalProcess) { @@ -481,8 +480,8 @@ function setupController(initState, initLangCode) { if (count) { label = String(count); } - extension.browserAction.setBadgeText({ text: label }); - extension.browserAction.setBadgeBackgroundColor({ color: '#037DD6' }); + browser.browserAction.setBadgeText({ text: label }); + browser.browserAction.setBadgeBackgroundColor({ color: '#037DD6' }); } function getUnapprovedTransactionCount() { @@ -627,7 +626,7 @@ async function openPopup() { } // On first install, open a new tab with MetaMask -extension.runtime.onInstalled.addListener(({ reason }) => { +browser.runtime.onInstalled.addListener(({ reason }) => { if ( reason === 'install' && !(process.env.METAMASK_DEBUG || process.env.IN_TEST) diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js index 236952f61..037f3de14 100644 --- a/app/scripts/contentscript.js +++ b/app/scripts/contentscript.js @@ -2,7 +2,7 @@ import querystring from 'querystring'; import pump from 'pump'; import { WindowPostMessageStream } from '@metamask/post-message-stream'; import ObjectMultiplex from 'obj-multiplex'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import PortStream from 'extension-port-stream'; import { obj as createThoughStream } from 'through2'; @@ -14,7 +14,7 @@ const inpageContent = fs.readFileSync( path.join(__dirname, '..', '..', 'dist', 'chrome', 'inpage.js'), 'utf8', ); -const inpageSuffix = `//# sourceURL=${extension.runtime.getURL('inpage.js')}\n`; +const inpageSuffix = `//# sourceURL=${browser.runtime.getURL('inpage.js')}\n`; const inpageBundle = inpageContent + inpageSuffix; const CONTENT_SCRIPT = 'metamask-contentscript'; @@ -61,7 +61,7 @@ async function setupStreams() { name: CONTENT_SCRIPT, target: INPAGE, }); - const extensionPort = extension.runtime.connect({ name: CONTENT_SCRIPT }); + const extensionPort = browser.runtime.connect({ name: CONTENT_SCRIPT }); const extensionStream = new PortStream(extensionPort); // create and connect channel muxers @@ -301,7 +301,7 @@ function blockedDomainCheck() { */ function redirectToPhishingWarning() { console.debug('MetaMask: Routing to Phishing Warning component.'); - const extensionURL = extension.runtime.getURL('phishing.html'); + const extensionURL = browser.runtime.getURL('phishing.html'); window.location.href = `${extensionURL}#${querystring.stringify({ hostname: window.location.hostname, href: window.location.href, diff --git a/app/scripts/lib/createOnboardingMiddleware.js b/app/scripts/lib/createOnboardingMiddleware.js index 5fa244c07..fd41655f3 100644 --- a/app/scripts/lib/createOnboardingMiddleware.js +++ b/app/scripts/lib/createOnboardingMiddleware.js @@ -1,5 +1,5 @@ import log from 'loglevel'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; /** * Returns a middleware that intercepts `wallet_registerOnboarding` messages @@ -17,7 +17,7 @@ export default function createOnboardingMiddleware({ next(); return; } - if (req.tabId && req.tabId !== extension.tabs.TAB_ID_NONE) { + if (req.tabId && req.tabId !== browser.tabs.TAB_ID_NONE) { await registerOnboarding(location, req.tabId); } else { log.debug( diff --git a/app/scripts/lib/ens-ipfs/setup.js b/app/scripts/lib/ens-ipfs/setup.js index a4c199b42..2d19811c3 100644 --- a/app/scripts/lib/ens-ipfs/setup.js +++ b/app/scripts/lib/ens-ipfs/setup.js @@ -1,6 +1,7 @@ import base32Encode from 'base32-encode'; import base64 from 'base64-js'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; + import { SECOND } from '../../../../shared/constants/time'; import getFetchWithTimeout from '../../../../shared/modules/fetch-with-timeout'; import resolveEnsToIpfsContentId from './resolver'; @@ -16,7 +17,7 @@ export default function setupEnsIpfsResolver({ }) { // install listener const urlPatterns = supportedTopLevelDomains.map((tld) => `*://*.${tld}/*`); - extension.webRequest.onErrorOccurred.addListener(webRequestDidFail, { + browser.webRequest.onErrorOccurred.addListener(webRequestDidFail, { urls: urlPatterns, types: ['main_frame'], }); @@ -25,7 +26,7 @@ export default function setupEnsIpfsResolver({ return { // uninstall listener remove() { - extension.webRequest.onErrorOccurred.removeListener(webRequestDidFail); + browser.webRequest.onErrorOccurred.removeListener(webRequestDidFail); }, }; @@ -51,7 +52,7 @@ export default function setupEnsIpfsResolver({ async function attemptResolve({ tabId, name, pathname, search, fragment }) { const ipfsGateway = getIpfsGateway(); - extension.tabs.update(tabId, { url: `loading.html` }); + browser.tabs.update(tabId, { url: `loading.html` }); let url = `https://app.ens.domains/name/${name}`; try { const { type, hash } = await resolveEnsToIpfsContentId({ @@ -101,7 +102,7 @@ export default function setupEnsIpfsResolver({ } catch (err) { console.warn(err); } finally { - extension.tabs.update(tabId, { url }); + browser.tabs.update(tabId, { url }); } } } diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js index 76faaafcc..a47cdc2ac 100644 --- a/app/scripts/lib/get-first-preferred-lang-code.js +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -1,11 +1,6 @@ -import extension from 'extensionizer'; -import promisify from 'pify'; +import browser from 'webextension-polyfill'; import allLocales from '../../_locales/index.json'; -const getPreferredLocales = extension.i18n - ? promisify(extension.i18n.getAcceptLanguages, { errorFirst: false }) - : async () => []; - // mapping some browsers return hyphen instead underscore in locale codes (e.g. zh_TW -> zh-tw) const existingLocaleCodes = {}; allLocales.forEach((locale) => { @@ -25,7 +20,7 @@ export default async function getFirstPreferredLangCode() { let userPreferredLocaleCodes; try { - userPreferredLocaleCodes = await getPreferredLocales(); + userPreferredLocaleCodes = await browser.i18n.getAcceptLanguages(); } catch (e) { // Brave currently throws when calling getAcceptLanguages, so this handles that. userPreferredLocaleCodes = []; diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js index 8ef36479a..889e36d55 100644 --- a/app/scripts/lib/local-store.js +++ b/app/scripts/lib/local-store.js @@ -1,4 +1,4 @@ -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import log from 'loglevel'; import { checkForError } from './util'; @@ -7,7 +7,7 @@ import { checkForError } from './util'; */ export default class ExtensionStore { constructor() { - this.isSupported = Boolean(extension.storage.local); + this.isSupported = Boolean(browser.storage.local); if (!this.isSupported) { log.error('Storage local API not available.'); } @@ -48,9 +48,9 @@ export default class ExtensionStore { * @returns {Object} the key-value map from local storage */ _get() { - const { local } = extension.storage; + const { local } = browser.storage; return new Promise((resolve, reject) => { - local.get(null, (/** @type {any} */ result) => { + local.get(null).then((/** @type {any} */ result) => { const err = checkForError(); if (err) { reject(err); @@ -69,9 +69,9 @@ export default class ExtensionStore { * @private */ _set(obj) { - const { local } = extension.storage; + const { local } = browser.storage; return new Promise((resolve, reject) => { - local.set(obj, () => { + local.set(obj).then(() => { const err = checkForError(); if (err) { reject(err); diff --git a/app/scripts/lib/util.js b/app/scripts/lib/util.js index 922447c3e..9800666af 100644 --- a/app/scripts/lib/util.js +++ b/app/scripts/lib/util.js @@ -1,4 +1,5 @@ -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; + import { stripHexPrefix } from 'ethereumjs-util'; import BN from 'bn.js'; import { memoize } from 'lodash'; @@ -102,7 +103,7 @@ function BnMultiplyByFraction(targetBN, numerator, denominator) { * @returns {Error|undefined} */ function checkForError() { - const { lastError } = extension.runtime; + const { lastError } = browser.runtime; if (!lastError) { return undefined; } diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index 2abae9066..616f0991b 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -164,7 +164,7 @@ export default class MetamaskController extends EventEmitter { MILLISECOND * 200, ); this.opts = opts; - this.extension = opts.extension; + this.extension = opts.browser; this.platform = opts.platform; this.notificationManager = opts.notificationManager; const initState = opts.initState || {}; @@ -1001,7 +1001,7 @@ export default class MetamaskController extends EventEmitter { } // Lazily update the store with the current extension environment - this.extension.runtime.getPlatformInfo(({ os }) => { + this.extension.runtime.getPlatformInfo().then(({ os }) => { this.appStateController.setBrowserEnvironment( os, // This method is presently only supported by Firefox diff --git a/app/scripts/metamask-controller.test.js b/app/scripts/metamask-controller.test.js index 2739c7dcf..f1771c173 100644 --- a/app/scripts/metamask-controller.test.js +++ b/app/scripts/metamask-controller.test.js @@ -65,7 +65,7 @@ class ThreeBoxControllerMock { } } -const ExtensionizerMock = { +const browserPolyfillMock = { runtime: { id: 'fake-extension-id', onInstalled: { @@ -148,7 +148,7 @@ describe('MetaMaskController', function () { showTransactionNotification: () => undefined, getVersion: () => 'foo', }, - extension: ExtensionizerMock, + browser: browserPolyfillMock, infuraProjectId: 'foo', }); diff --git a/app/scripts/phishing-detect.js b/app/scripts/phishing-detect.js index bb6bf5b2e..68c30d501 100644 --- a/app/scripts/phishing-detect.js +++ b/app/scripts/phishing-detect.js @@ -1,6 +1,6 @@ import querystring from 'querystring'; import PortStream from 'extension-port-stream'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import createRandomId from '../../shared/modules/random-id'; import { setupMultiplex } from './lib/stream-utils'; import { getEnvironmentType } from './lib/util'; @@ -21,7 +21,7 @@ function start() { global.platform = new ExtensionPlatform(); - const extensionPort = extension.runtime.connect({ + const extensionPort = browser.runtime.connect({ name: getEnvironmentType(), }); const connectionStream = new PortStream(extensionPort); diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index 0626f1545..7741a5f78 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -1,4 +1,5 @@ -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; + import { getBlockExplorerLink } from '@metamask/etherscan-link'; import { getEnvironmentType, checkForError } from '../lib/util'; import { ENVIRONMENT_TYPE_BACKGROUND } from '../../../shared/constants/app'; @@ -9,12 +10,12 @@ export default class ExtensionPlatform { // Public // reload() { - extension.runtime.reload(); + browser.runtime.reload(); } openTab(options) { return new Promise((resolve, reject) => { - extension.tabs.create(options, (newTab) => { + browser.tabs.create(options).then((newTab) => { const error = checkForError(); if (error) { return reject(error); @@ -26,7 +27,7 @@ export default class ExtensionPlatform { openWindow(options) { return new Promise((resolve, reject) => { - extension.windows.create(options, (newWindow) => { + browser.windows.create(options).then((newWindow) => { const error = checkForError(); if (error) { return reject(error); @@ -38,7 +39,7 @@ export default class ExtensionPlatform { focusWindow(windowId) { return new Promise((resolve, reject) => { - extension.windows.update(windowId, { focused: true }, () => { + browser.windows.update(windowId, { focused: true }).then(() => { const error = checkForError(); if (error) { return reject(error); @@ -50,7 +51,7 @@ export default class ExtensionPlatform { updateWindowPosition(windowId, left, top) { return new Promise((resolve, reject) => { - extension.windows.update(windowId, { left, top }, () => { + browser.windows.update(windowId, { left, top }).then(() => { const error = checkForError(); if (error) { return reject(error); @@ -62,7 +63,7 @@ export default class ExtensionPlatform { getLastFocusedWindow() { return new Promise((resolve, reject) => { - extension.windows.getLastFocused((windowObject) => { + browser.windows.getLastFocused().then((windowObject) => { const error = checkForError(); if (error) { return reject(error); @@ -73,8 +74,8 @@ export default class ExtensionPlatform { } closeCurrentWindow() { - return extension.windows.getCurrent((windowDetails) => { - return extension.windows.remove(windowDetails.id); + return browser.windows.getCurrent().then((windowDetails) => { + return browser.windows.remove(windowDetails.id); }); } @@ -82,7 +83,7 @@ export default class ExtensionPlatform { const { version, version_name: versionName, - } = extension.runtime.getManifest(); + } = browser.runtime.getManifest(); const versionParts = version.split('.'); if (versionName) { @@ -115,7 +116,7 @@ export default class ExtensionPlatform { queryString = null, keepWindowOpen = false, ) { - let extensionURL = extension.runtime.getURL('home.html'); + let extensionURL = browser.runtime.getURL('home.html'); if (route) { extensionURL += `#${route}`; @@ -136,9 +137,9 @@ export default class ExtensionPlatform { getPlatformInfo(cb) { try { - extension.runtime.getPlatformInfo((platform) => { - cb(null, platform); - }); + const platformInfo = browser.runtime.getPlatformInfo(); + cb(platformInfo); + return; } catch (e) { cb(e); // eslint-disable-next-line no-useless-return @@ -163,12 +164,12 @@ export default class ExtensionPlatform { } addOnRemovedListener(listener) { - extension.windows.onRemoved.addListener(listener); + browser.windows.onRemoved.addListener(listener); } getAllWindows() { return new Promise((resolve, reject) => { - extension.windows.getAll((windows) => { + browser.windows.getAll().then((windows) => { const error = checkForError(); if (error) { return reject(error); @@ -180,7 +181,7 @@ export default class ExtensionPlatform { getActiveTabs() { return new Promise((resolve, reject) => { - extension.tabs.query({ active: true }, (tabs) => { + browser.tabs.query({ active: true }).then((tabs) => { const error = checkForError(); if (error) { return reject(error); @@ -192,7 +193,7 @@ export default class ExtensionPlatform { currentTab() { return new Promise((resolve, reject) => { - extension.tabs.getCurrent((tab) => { + browser.tabs.getCurrent().then((tab) => { const err = checkForError(); if (err) { reject(err); @@ -205,7 +206,7 @@ export default class ExtensionPlatform { switchToTab(tabId) { return new Promise((resolve, reject) => { - extension.tabs.update(tabId, { highlighted: true }, (tab) => { + browser.tabs.update(tabId, { highlighted: true }).then((tab) => { const err = checkForError(); if (err) { reject(err); @@ -218,7 +219,7 @@ export default class ExtensionPlatform { closeTab(tabId) { return new Promise((resolve, reject) => { - extension.tabs.remove(tabId, () => { + browser.tabs.remove(tabId).then(() => { const err = checkForError(); if (err) { reject(err); @@ -252,23 +253,23 @@ export default class ExtensionPlatform { } _showNotification(title, message, url) { - extension.notifications.create(url, { + browser.notifications.create(url, { type: 'basic', title, - iconUrl: extension.extension.getURL('../../images/icon-64.png'), + iconUrl: browser.extension.getURL('../../images/icon-64.png'), message, }); } _subscribeToNotificationClicked() { - if (!extension.notifications.onClicked.hasListener(this._viewOnEtherscan)) { - extension.notifications.onClicked.addListener(this._viewOnEtherscan); + if (!browser.notifications.onClicked.hasListener(this._viewOnEtherscan)) { + browser.notifications.onClicked.addListener(this._viewOnEtherscan); } } _viewOnEtherscan(url) { if (url.startsWith('https://')) { - extension.tabs.create({ url }); + browser.tabs.create({ url }); } } } diff --git a/app/scripts/platforms/extension.test.js b/app/scripts/platforms/extension.test.js index af7852b8b..de8b05cdd 100644 --- a/app/scripts/platforms/extension.test.js +++ b/app/scripts/platforms/extension.test.js @@ -1,7 +1,7 @@ -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import ExtensionPlatform from './extension'; -jest.mock('extensionizer', () => { +jest.mock('webextension-polyfill', () => { return { runtime: { getManifest: jest.fn(), @@ -17,7 +17,7 @@ describe('extension platform', () => { describe('getVersion', () => { it('should return non-prerelease version', () => { - extension.runtime.getManifest.mockReturnValue({ version: '1.2.3' }); + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3' }); const extensionPlatform = new ExtensionPlatform(); const version = extensionPlatform.getVersion(); @@ -26,7 +26,7 @@ describe('extension platform', () => { }); it('should return SemVer-formatted version for Chrome style manifest of prerelease', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3.0', version_name: '1.2.3-beta.0', }); @@ -38,7 +38,7 @@ describe('extension platform', () => { }); it('should return SemVer-formatted version for Firefox style manifest of prerelease', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3beta0', }); const extensionPlatform = new ExtensionPlatform(); @@ -49,7 +49,7 @@ describe('extension platform', () => { }); it('should throw error if build version is missing from Chrome style prerelease manifest', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3', version_name: '1.2.3-beta.0', }); @@ -61,7 +61,7 @@ describe('extension platform', () => { }); it('should throw error if version name is missing from Chrome style prerelease manifest', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3.0', }); const extensionPlatform = new ExtensionPlatform(); @@ -70,7 +70,7 @@ describe('extension platform', () => { }); it('should throw error if version includes four parts in a Firefox style manifest', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3.4', }); const extensionPlatform = new ExtensionPlatform(); @@ -79,7 +79,7 @@ describe('extension platform', () => { }); it('should throw error if build version is missing from Firefox style prerelease manifest', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.3beta', }); const extensionPlatform = new ExtensionPlatform(); @@ -90,7 +90,7 @@ describe('extension platform', () => { }); it('should throw error if patch is missing from Firefox style prerelease manifest', () => { - extension.runtime.getManifest.mockReturnValue({ + browser.runtime.getManifest.mockReturnValue({ version: '1.2.beta0', }); const extensionPlatform = new ExtensionPlatform(); diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 362567aa8..1c4a3fc1c 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -5,7 +5,7 @@ import '@formatjs/intl-relativetimeformat/polyfill'; import 'react-devtools'; import PortStream from 'extension-port-stream'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import Eth from 'ethjs'; import EthQuery from 'eth-query'; @@ -31,7 +31,7 @@ async function start() { const windowType = getEnvironmentType(); // setup stream to background - const extensionPort = extension.runtime.connect({ name: windowType }); + const extensionPort = browser.runtime.connect({ name: windowType }); const connectionStream = new PortStream(extensionPort); const activeTab = await queryCurrentActiveTab(windowType); @@ -72,7 +72,7 @@ async function queryCurrentActiveTab(windowType) { return; } - extension.tabs.query({ active: true, currentWindow: true }, (tabs) => { + browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => { const [activeTab] = tabs; const { id, title, url } = activeTab; const { origin, protocol } = url ? new URL(url) : {}; diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index eaa8a7633..f37d918b0 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -2240,12 +2240,6 @@ "stream-browserify": true } }, - "extensionizer": { - "globals": { - "browser": true, - "chrome": true - } - }, "faker": { "globals": { "console.error": true, @@ -5189,6 +5183,15 @@ "utf8": true } }, + "webextension-polyfill": { + "globals": { + "browser": true, + "chrome": true, + "console.error": true, + "console.warn": true, + "define": true + } + }, "webrtcsupport": { "globals": { "AudioContext": true, diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index 28f79890d..1db9f2da3 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -2259,12 +2259,6 @@ "stream-browserify": true } }, - "extensionizer": { - "globals": { - "browser": true, - "chrome": true - } - }, "faker": { "globals": { "console.error": true, @@ -5208,6 +5202,15 @@ "utf8": true } }, + "webextension-polyfill": { + "globals": { + "browser": true, + "chrome": true, + "console.error": true, + "console.warn": true, + "define": true + } + }, "webrtcsupport": { "globals": { "AudioContext": true, diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index eaa8a7633..f37d918b0 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -2240,12 +2240,6 @@ "stream-browserify": true } }, - "extensionizer": { - "globals": { - "browser": true, - "chrome": true - } - }, "faker": { "globals": { "console.error": true, @@ -5189,6 +5183,15 @@ "utf8": true } }, + "webextension-polyfill": { + "globals": { + "browser": true, + "chrome": true, + "console.error": true, + "console.warn": true, + "define": true + } + }, "webrtcsupport": { "globals": { "AudioContext": true, diff --git a/package.json b/package.json index 63c4daaeb..780c62a74 100644 --- a/package.json +++ b/package.json @@ -168,7 +168,6 @@ "ethjs-ens": "^2.0.0", "ethjs-query": "^0.3.4", "extension-port-stream": "^2.0.0", - "extensionizer": "^1.0.1", "fast-json-patch": "^2.2.1", "fast-safe-stringify": "^2.0.7", "fuse.js": "^3.2.0", @@ -363,6 +362,7 @@ "vinyl-source-stream": "^2.0.0", "vinyl-sourcemaps-apply": "^0.2.1", "watchify": "^4.0.0", + "webextension-polyfill": "^0.8.0", "webpack": "^4.41.6", "yargs": "^17.0.1", "yarn-deduplicate": "^3.1.0" diff --git a/test/helpers/setup-helper.js b/test/helpers/setup-helper.js index 9d4b7d892..75dfb8ea7 100644 --- a/test/helpers/setup-helper.js +++ b/test/helpers/setup-helper.js @@ -6,6 +6,8 @@ import { JSDOM } from 'jsdom'; process.env.IN_TEST = true; +global.chrome = { runtime: { id: 'testid' } }; + nock.disableNetConnect(); nock.enableNetConnect('localhost'); diff --git a/ui/__mocks__/webextension-polyfill.js b/ui/__mocks__/webextension-polyfill.js new file mode 100644 index 000000000..54e90aa25 --- /dev/null +++ b/ui/__mocks__/webextension-polyfill.js @@ -0,0 +1,3 @@ +module.exports = { + runtime: {}, +}; diff --git a/ui/components/app/menu-bar/menu-bar.js b/ui/components/app/menu-bar/menu-bar.js index bc3af6362..9d8af1066 100644 --- a/ui/components/app/menu-bar/menu-bar.js +++ b/ui/components/app/menu-bar/menu-bar.js @@ -1,5 +1,5 @@ import React, { useState, useContext } from 'react'; -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import { useHistory } from 'react-router-dom'; import { useSelector } from 'react-redux'; import SelectedAccount from '../selected-account'; @@ -26,7 +26,7 @@ export default function MenuBar() { const showStatus = getEnvironmentType() === ENVIRONMENT_TYPE_POPUP && origin && - origin !== extension.runtime.id; + origin !== browser.runtime.id; return (
diff --git a/ui/pages/first-time-flow/onboarding-initiator-util.js b/ui/pages/first-time-flow/onboarding-initiator-util.js index abfa424d7..98dc98f89 100644 --- a/ui/pages/first-time-flow/onboarding-initiator-util.js +++ b/ui/pages/first-time-flow/onboarding-initiator-util.js @@ -1,9 +1,9 @@ -import extension from 'extensionizer'; +import browser from 'webextension-polyfill'; import log from 'loglevel'; const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { const tab = await new Promise((resolve) => { - extension.tabs.update( + browser.tabs.update( onboardingInitiator.tabId, { active: true }, // eslint-disable-next-line no-shadow @@ -12,8 +12,8 @@ const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { resolve(tab); } else { // silence console message about unchecked error - if (extension.runtime.lastError) { - log.debug(extension.runtime.lastError); + if (browser.runtime.lastError) { + log.debug(browser.runtime.lastError); } resolve(); } @@ -24,7 +24,7 @@ const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { if (tab) { window.close(); } else { - // this case can happen if the tab was closed since being checked with `extension.tabs.get` + // this case can happen if the tab was closed since being checked with `browser.tabs.get` log.warn( `Setting current tab to onboarding initiator has failed; falling back to redirect`, ); @@ -35,13 +35,13 @@ const returnToOnboardingInitiatorTab = async (onboardingInitiator) => { export const returnToOnboardingInitiator = async (onboardingInitiator) => { const tab = await new Promise((resolve) => { // eslint-disable-next-line no-shadow - extension.tabs.get(onboardingInitiator.tabId, (tab) => { + browser.tabs.get(onboardingInitiator.tabId, (tab) => { if (tab) { resolve(tab); } else { // silence console message about unchecked error - if (extension.runtime.lastError) { - log.debug(extension.runtime.lastError); + if (browser.runtime.lastError) { + log.debug(browser.runtime.lastError); } resolve(); } diff --git a/yarn.lock b/yarn.lock index d8c23e18b..5b7bd96e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12040,11 +12040,6 @@ extension-port-stream@^2.0.0, extension-port-stream@^2.0.1: dependencies: webextension-polyfill-ts "^0.22.0" -extensionizer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/extensionizer/-/extensionizer-1.0.1.tgz#504544239a7610ba8404b15c1832091a37768d09" - integrity sha512-UES5CSOYqshNsWFrpORcQR47+ph6UvQK25mguD44IyeMemt40CG+LTZrH1PgpGUHX3w7ACtNQnmM0J+qEe8G0Q== - external-editor@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" @@ -27761,6 +27756,11 @@ webextension-polyfill@^0.7.0: resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.7.0.tgz#0df1120ff0266056319ce1a622b09ad8d4a56505" integrity sha512-su48BkMLxqzTTvPSE1eWxKToPS2Tv5DLGxKexLEVpwFd6Po6N8hhSLIvG6acPAg7qERoEaDL+Y5HQJeJeml5Aw== +webextension-polyfill@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.8.0.tgz#f80e9f4b7f81820c420abd6ffbebfa838c60e041" + integrity sha512-a19+DzlT6Kp9/UI+mF9XQopeZ+n2ussjhxHJ4/pmIGge9ijCDz7Gn93mNnjpZAk95T4Tae8iHZ6sSf869txqiQ== + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" From 79d00f72e13ddfe0c45e4c2e34d04bf60808750e Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 18 Mar 2022 15:07:07 -0500 Subject: [PATCH 048/192] Dark Mode: Update swaps link colors (#14033) --- ui/pages/swaps/awaiting-swap/index.scss | 4 ++-- ui/pages/swaps/build-quote/index.scss | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/pages/swaps/awaiting-swap/index.scss b/ui/pages/swaps/awaiting-swap/index.scss index bae40017d..0750ace6f 100644 --- a/ui/pages/swaps/awaiting-swap/index.scss +++ b/ui/pages/swaps/awaiting-swap/index.scss @@ -21,7 +21,7 @@ } a { - color: var(--text-primary-color); + color: var(--color-primary-default); } &__status-image { @@ -66,7 +66,7 @@ &__view-on-etherscan, &__support-link { - color: var(--text-primary-color); + color: var(--color-primary-default); margin-top: 24px; cursor: pointer; } diff --git a/ui/pages/swaps/build-quote/index.scss b/ui/pages/swaps/build-quote/index.scss index 725550113..1655ea59f 100644 --- a/ui/pages/swaps/build-quote/index.scss +++ b/ui/pages/swaps/build-quote/index.scss @@ -67,7 +67,7 @@ &__max-button { @include H7; - color: var(--text-primary-color); + color: var(--color-primary-default); cursor: pointer; } From c0e930ea534bb0c8af7e9e622f9d25b5a7a5c42f Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 18 Mar 2022 15:15:41 -0500 Subject: [PATCH 049/192] Dark Mode: Standardize error colors (#14029) --- .../app/modals/export-private-key-modal/index.scss | 6 +++--- ui/components/app/signature-request-original/index.scss | 2 +- ui/css/utilities/colors.scss | 1 - ui/pages/settings/settings-tab/index.scss | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/ui/components/app/modals/export-private-key-modal/index.scss b/ui/components/app/modals/export-private-key-modal/index.scss index d4debed95..862e305d3 100644 --- a/ui/components/app/modals/export-private-key-modal/index.scss +++ b/ui/components/app/modals/export-private-key-modal/index.scss @@ -33,7 +33,7 @@ } &__password--error { - color: var(--crimson); + color: var(--color-error-default); margin-bottom: 0; } @@ -55,7 +55,7 @@ border-radius: 8px; background-color: #fff6f6; font-weight: 500; - color: var(--crimson); + color: var(--color-error-default); width: 292px; padding: 9px 15px; margin-top: 18px; @@ -71,7 +71,7 @@ &__password-display-textarea { @include Paragraph; - color: var(--crimson); + color: var(--color-error-default); border: none; height: 75px; width: 100%; diff --git a/ui/components/app/signature-request-original/index.scss b/ui/components/app/signature-request-original/index.scss index ce40fd424..246dc5fba 100644 --- a/ui/components/app/signature-request-original/index.scss +++ b/ui/components/app/signature-request-original/index.scss @@ -186,7 +186,7 @@ } &__warning { - color: var(--crimson); + color: var(--color-error-default); } &__rows { diff --git a/ui/css/utilities/colors.scss b/ui/css/utilities/colors.scss index 3409dc8a9..6e4e5cf91 100644 --- a/ui/css/utilities/colors.scss +++ b/ui/css/utilities/colors.scss @@ -131,7 +131,6 @@ --silver: #cdcdcd; --caribbean-green: #02c9b1; --monzo: #d0021b; - --crimson: #e91550; --blue-lagoon: #038789; --purple: #690496; --tulip-tree: #ebb33f; diff --git a/ui/pages/settings/settings-tab/index.scss b/ui/pages/settings/settings-tab/index.scss index f4e6d4c79..ec6bd42d7 100644 --- a/ui/pages/settings/settings-tab/index.scss +++ b/ui/pages/settings/settings-tab/index.scss @@ -2,7 +2,7 @@ &__error { padding-bottom: 20px; text-align: center; - color: var(--crimson); + color: var(--color-error-default); } &__rpc-save-button { From 2454bd81243a666971e1019968fef08b54a7fd69 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Fri, 18 Mar 2022 22:10:20 +0100 Subject: [PATCH 050/192] confirmation screen dark mode (#14024) --- .../confirmation-footer.scss | 4 ++-- ui/pages/confirmation/confirmation.scss | 18 +++++++++--------- .../templates/flask/snap-confirm/index.scss | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ui/pages/confirmation/components/confirmation-footer/confirmation-footer.scss b/ui/pages/confirmation/components/confirmation-footer/confirmation-footer.scss index 290d5cce8..d386e5a8f 100644 --- a/ui/pages/confirmation/components/confirmation-footer/confirmation-footer.scss +++ b/ui/pages/confirmation/components/confirmation-footer/confirmation-footer.scss @@ -3,8 +3,8 @@ &__actions { display: flex; - border-top: 1px solid var(--ui-2); - background-color: white; + border-top: 1px solid var(--color-border-muted); + background-color: var(--color-background-default); padding: 16px; & .button:first-child { diff --git a/ui/pages/confirmation/confirmation.scss b/ui/pages/confirmation/confirmation.scss index 482f1c210..6c930ec4c 100644 --- a/ui/pages/confirmation/confirmation.scss +++ b/ui/pages/confirmation/confirmation.scss @@ -5,7 +5,7 @@ width: 100%; height: 100%; position: relative; - background: white; + background: var(--color-background-default); display: grid; flex-direction: column; grid-template-columns: 1fr; @@ -16,7 +16,7 @@ 'footer'; a { - color: var(--primary-1); + color: var(--color-primary-default); } &__content { @@ -32,19 +32,19 @@ @include H7; grid-area: navigation; - background-color: var(--Grey-000); - border-bottom: 1px solid var(--geyser); + background-color: var(--color-background-alternative); + border-bottom: 1px solid var(--color-border-muted); padding: 6px 16px 5px 16px; - color: var(--Grey-500); + color: var(--color-text-alternative); display: grid; grid-template-columns: 1fr minmax(0, auto) minmax(0, auto); align-items: center; } &__navigation-button { - background-color: white; + background-color: var(--color-background-default); border-radius: 100px; - color: var(--Grey-500); + color: var(--color-text-alternative); font-size: $font-size-h6; height: 20px; width: 20px; @@ -52,8 +52,8 @@ &:disabled { cursor: not-allowed; - background-color: var(--Grey-100); - color: var(--Grey-300); + background-color: var(--color-background-alternative); + color: var(--color-text-muted); } } diff --git a/ui/pages/confirmation/templates/flask/snap-confirm/index.scss b/ui/pages/confirmation/templates/flask/snap-confirm/index.scss index 7fed11cd3..fdac1698a 100644 --- a/ui/pages/confirmation/templates/flask/snap-confirm/index.scss +++ b/ui/pages/confirmation/templates/flask/snap-confirm/index.scss @@ -1,7 +1,7 @@ .snap-confirm { padding: 16px 32px; - border-top: 1px solid var(--Grey-100); - border-bottom: 1px solid var(--Grey-100); + border-top: 1px solid var(--color-border-muted); + border-bottom: 1px solid var(--color-border-muted); margin: 24px 0 16px 0; .text { From b43d565af7a0ab6bd3cd8f8e93493c4b503f80b1 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 18 Mar 2022 17:55:33 -0500 Subject: [PATCH 051/192] Dark Mode: Reveal Seed colors (#14028) --- ui/components/ui/export-text-container/index.scss | 12 ++++++------ ui/css/base-styles.scss | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ui/components/ui/export-text-container/index.scss b/ui/components/ui/export-text-container/index.scss index c1ac0adec..8d01f0113 100644 --- a/ui/components/ui/export-text-container/index.scss +++ b/ui/components/ui/export-text-container/index.scss @@ -3,7 +3,7 @@ justify-content: center; flex-direction: column; align-items: center; - border: 1px solid var(--alto); + border: 1px solid var(--color-border-default); border-radius: 4px; font-weight: 400; @@ -13,7 +13,7 @@ justify-content: center; padding: 20px; border-radius: 4px; - background: var(--alabaster); + background: var(--color-background-default); } &__text { @@ -21,14 +21,14 @@ resize: none; border: none; - background: var(--alabaster); + background: var(--color-background-default); text-align: center; } &__buttons-container { display: flex; flex-direction: row; - border-top: 1px solid var(--alto); + border-top: 1px solid var(--color-border-default); width: 100%; } @@ -41,10 +41,10 @@ justify-content: center; align-items: center; cursor: pointer; - color: var(--primary-blue); + color: var(--color-primary-default); &--copy { - border-right: 1px solid var(--alto); + border-right: 1px solid var(--color-border-default); } } diff --git a/ui/css/base-styles.scss b/ui/css/base-styles.scss index 7e06d33ba..8ca68590d 100644 --- a/ui/css/base-styles.scss +++ b/ui/css/base-styles.scss @@ -90,6 +90,7 @@ input.form-control { font-size: 14px; height: 40px; border: 1px solid var(--color-border-muted); + background: transparent; border-radius: 3px; width: 100%; From 524e0aaf078065f9737a0f67378d699c31bba220 Mon Sep 17 00:00:00 2001 From: Alex Donesky Date: Fri, 18 Mar 2022 19:04:59 -0500 Subject: [PATCH 052/192] unbreak storybook (#14059) --- .storybook/__mocks__/webextension-polyfill.js | 4 ++++ .storybook/main.js | 1 + 2 files changed, 5 insertions(+) create mode 100644 .storybook/__mocks__/webextension-polyfill.js diff --git a/.storybook/__mocks__/webextension-polyfill.js b/.storybook/__mocks__/webextension-polyfill.js new file mode 100644 index 000000000..c8e3dea17 --- /dev/null +++ b/.storybook/__mocks__/webextension-polyfill.js @@ -0,0 +1,4 @@ +module.exports = { + runtime: {}, + }; + \ No newline at end of file diff --git a/.storybook/main.js b/.storybook/main.js index 5ce2f32d7..e7b859b84 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -23,6 +23,7 @@ module.exports = { config.node = { __filename: true, }; + config.resolve.alias['webextension-polyfill'] = require.resolve('./__mocks__/webextension-polyfill.js') config.module.strictExportPresence = true; config.module.rules.push({ test: /\.scss$/, From 91a30bc4648f7943b228da5835aff01a017ee425 Mon Sep 17 00:00:00 2001 From: David Walsh Date: Fri, 18 Mar 2022 19:20:40 -0500 Subject: [PATCH 053/192] Dark Mode: Loading Heartbeat (#14015) --- ui/components/ui/loading-heartbeat/index.js | 2 +- ui/components/ui/loading-heartbeat/index.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/components/ui/loading-heartbeat/index.js b/ui/components/ui/loading-heartbeat/index.js index ab69a465a..9cc3dc243 100644 --- a/ui/components/ui/loading-heartbeat/index.js +++ b/ui/components/ui/loading-heartbeat/index.js @@ -12,7 +12,7 @@ const LOADING_CLASS = `${BASE_CLASS}--active`; export default function LoadingHeartBeat({ estimateUsed, - backgroundColor = '#fff', + backgroundColor = 'var(--color-background-default)', }) { useShouldAnimateGasEstimations(); const active = useSelector(getGasLoadingAnimationIsShowing); diff --git a/ui/components/ui/loading-heartbeat/index.scss b/ui/components/ui/loading-heartbeat/index.scss index c6f213453..a9e565ec5 100644 --- a/ui/components/ui/loading-heartbeat/index.scss +++ b/ui/components/ui/loading-heartbeat/index.scss @@ -5,7 +5,7 @@ left: 0; right: 0; opacity: 0; - background: #fff; + background: var(--color-background-default); display: none; pointer-events: none; From c3901e4ba862ee31667f5351d651fbe717351592 Mon Sep 17 00:00:00 2001 From: Guillaume Roux Date: Sat, 19 Mar 2022 01:43:10 +0100 Subject: [PATCH 054/192] Dark Mode : Gas fee (#14005) --- app/images/curve-high.svg | 2 +- app/images/curve-low.svg | 2 +- app/images/curve-medium.svg | 2 +- .../app/edit-gas-display-education/index.scss | 2 +- ui/components/app/edit-gas-display/index.scss | 8 ++-- .../app/edit-gas-fee-button/index.scss | 8 ++-- .../edit-gas-item/index.scss | 4 +- .../edit-gas-tooltip/index.scss | 2 +- .../app/edit-gas-fee-popover/index.scss | 8 ++-- .../network-statistics/index.scss | 6 +-- .../advanced-gas-inputs/index.scss | 24 +++++------ .../advanced-tab-content/index.scss | 18 ++++----- .../basic-tab-content/index.scss | 6 +-- .../gas-modal-page-container/index.scss | 16 ++++---- .../gas-price-button-group/index.scss | 40 +++++++++---------- .../gas-customization/gas-slider/index.scss | 8 ++-- .../gas-details-item-title/index.scss | 2 +- ui/components/app/gas-details-item/index.scss | 2 +- ui/components/app/gas-timing/index.scss | 14 +++---- ui/components/ui/info-tooltip/index.scss | 16 ++++---- ui/components/ui/radio-group/index.scss | 12 +++--- .../ui/radio-group/radio-group.component.js | 2 +- ui/components/ui/tooltip/index.scss | 12 +++--- 23 files changed, 108 insertions(+), 108 deletions(-) diff --git a/app/images/curve-high.svg b/app/images/curve-high.svg index f8d0f0c00..643f6fb46 100644 --- a/app/images/curve-high.svg +++ b/app/images/curve-high.svg @@ -1 +1 @@ - + diff --git a/app/images/curve-low.svg b/app/images/curve-low.svg index 385f89f86..7f1d41395 100644 --- a/app/images/curve-low.svg +++ b/app/images/curve-low.svg @@ -1 +1 @@ - + diff --git a/app/images/curve-medium.svg b/app/images/curve-medium.svg index e8a8f6a3f..3410b9604 100644 --- a/app/images/curve-medium.svg +++ b/app/images/curve-medium.svg @@ -1 +1 @@ - + diff --git a/ui/components/app/edit-gas-display-education/index.scss b/ui/components/app/edit-gas-display-education/index.scss index f2d8bf308..c37683182 100644 --- a/ui/components/app/edit-gas-display-education/index.scss +++ b/ui/components/app/edit-gas-display-education/index.scss @@ -1,5 +1,5 @@ .edit-gas-display-education { a { - color: var(--primary-1); + color: var(--color-primary-default); } } diff --git a/ui/components/app/edit-gas-display/index.scss b/ui/components/app/edit-gas-display/index.scss index 70e35c6a4..3af1e402c 100644 --- a/ui/components/app/edit-gas-display/index.scss +++ b/ui/components/app/edit-gas-display/index.scss @@ -28,8 +28,8 @@ button.edit-gas-display__dapp-acknowledgement-button { margin: 40px auto 0 auto; display: block; - color: var(--secondary-1); - border: 1px solid var(--secondary-1); + color: var(--color-secondary-default); + border: 1px solid var(--color-secondary-default); text-transform: unset; width: auto; background: transparent; @@ -43,7 +43,7 @@ display: block; margin: 0 auto; background: transparent; - color: var(--primary-1); + color: var(--color-primary-default); font-weight: bold; } @@ -58,7 +58,7 @@ display: block; margin: 0 auto; background: transparent; - color: var(--primary-1); + color: var(--color-primary-default); } } diff --git a/ui/components/app/edit-gas-fee-button/index.scss b/ui/components/app/edit-gas-fee-button/index.scss index ada2348fc..52c7cbaf4 100644 --- a/ui/components/app/edit-gas-fee-button/index.scss +++ b/ui/components/app/edit-gas-fee-button/index.scss @@ -8,7 +8,7 @@ display: flex; align-items: baseline; - color: var(--primary-1); + color: var(--color-primary-default); background: transparent; border: 0; padding-inline-end: 0; @@ -16,7 +16,7 @@ } i { - color: var(--primary-1); + color: var(--color-primary-default); margin-right: 2px; } @@ -37,11 +37,11 @@ &__tooltip { p { - color: var(--Grey-500); + color: var(--color-text-alternative); } b { - color: var(--neutral-black); + color: var(--color-text-default); display: inline-block; min-width: 60%; } diff --git a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss index 409de3744..87a13ccec 100644 --- a/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss +++ b/ui/components/app/edit-gas-fee-popover/edit-gas-item/index.scss @@ -12,7 +12,7 @@ width: 100%; &:hover:not([disabled]) { - background-color: var(--primary-2); + background-color: var(--color-primary-muted); } &--selected { @@ -83,6 +83,6 @@ &__time-estimate-medium, &__time-estimate-high { - color: var(--success-3); + color: var(--color-success-muted); } } diff --git a/ui/components/app/edit-gas-fee-popover/edit-gas-tooltip/index.scss b/ui/components/app/edit-gas-fee-popover/edit-gas-tooltip/index.scss index 05b8d4963..63c1b7e98 100644 --- a/ui/components/app/edit-gas-fee-popover/edit-gas-tooltip/index.scss +++ b/ui/components/app/edit-gas-fee-popover/edit-gas-tooltip/index.scss @@ -17,7 +17,7 @@ } &__dialog { - background-color: var(--Orange-500); + background-color: var(--color-secondary-default); border-radius: 30px; margin: 4px 0; text-align: center; diff --git a/ui/components/app/edit-gas-fee-popover/index.scss b/ui/components/app/edit-gas-fee-popover/index.scss index 5319938a3..9d72b840f 100644 --- a/ui/components/app/edit-gas-fee-popover/index.scss +++ b/ui/components/app/edit-gas-fee-popover/index.scss @@ -2,7 +2,7 @@ height: 500px; &__wrapper { - border-top: 1px solid var(--ui-grey); + border-top: 1px solid var(--color-border-default); height: 100%; } @@ -19,7 +19,7 @@ } &__header { - color: var(--ui-4); + color: var(--color-text-alternative); font-size: 10px; font-weight: 700; margin: 0 12px; @@ -41,7 +41,7 @@ } &__separator { - border-top: 1px solid var(--ui-grey); + border-top: 1px solid var(--color-border-default); margin: 8px 12px; } } @@ -51,6 +51,6 @@ } &__know-more a { - color: var(--primary-1); + color: var(--color-primary-default); } } diff --git a/ui/components/app/edit-gas-fee-popover/network-statistics/index.scss b/ui/components/app/edit-gas-fee-popover/network-statistics/index.scss index 3204fbf14..a0a01e411 100644 --- a/ui/components/app/edit-gas-fee-popover/network-statistics/index.scss +++ b/ui/components/app/edit-gas-fee-popover/network-statistics/index.scss @@ -2,8 +2,8 @@ margin: 24px 12px 12px; &__info { - border-top: 1px solid var(--ui-2); - border-bottom: 1px solid var(--ui-2); + border-top: 1px solid var(--color-border-muted); + border-bottom: 1px solid var(--color-border-muted); height: 56px; display: flex; align-items: center; @@ -18,7 +18,7 @@ flex: 1; &:not(:last-child) { - border-right: 1px solid var(--ui-2); + border-right: 1px solid var(--color-border-muted); } } diff --git a/ui/components/app/gas-customization/advanced-gas-inputs/index.scss b/ui/components/app/gas-customization/advanced-gas-inputs/index.scss index 270b7c29f..778117137 100644 --- a/ui/components/app/gas-customization/advanced-gas-inputs/index.scss +++ b/ui/components/app/gas-customization/advanced-gas-inputs/index.scss @@ -23,12 +23,12 @@ } .fa-info-circle { - color: var(--silver); + color: var(--color-icon-default); cursor: pointer; } .fa-info-circle:hover { - color: var(--mid-gray); + color: var(--color-icon-muted); } } @@ -53,9 +53,9 @@ @include Paragraph; direction: ltr; - border: 1px solid var(--dusty-gray); + border: 1px solid var(--color-border-muted); border-radius: 4px; - color: var(--mid-gray); + color: var(--color-text-alternative); height: 24px; width: 100%; padding-left: 8px; @@ -64,11 +64,11 @@ } &__input--error { - border: 1px solid var(--red); + border: 1px solid var(--color-error-default); } &__input--warning { - border: 1px solid var(--orange); + border: 1px solid var(--color-warning-default); } &__input-arrows { @@ -98,12 +98,12 @@ } &__i-wrap:hover { - background: #4eade7; - color: var(--white); + background: var(--color-primary-default); + color: var(--color-primary-inverse); } i:hover { - background: #4eade7; + background: var(--color-primary-muted); } i { @@ -116,11 +116,11 @@ } &__input-arrows--error { - border: 1px solid var(--red); + border: 1px solid var(--color-error-default); } &__input-arrows--warning { - border: 1px solid var(--orange); + border: 1px solid var(--color-warning-default); } input[type="number"] { @@ -145,7 +145,7 @@ position: absolute; top: 8px; right: 10px; - color: var(--dusty-gray); + color: var(--color-text-muted); } &__custom-text { diff --git a/ui/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index d35feac31..920e831c2 100644 --- a/ui/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -10,7 +10,7 @@ &__transaction-data-summary { display: flex; flex-flow: column; - color: var(--mid-gray); + color: var(--color-text-alternative); margin-top: 12px; padding-left: 18px; padding-right: 18px; @@ -22,7 +22,7 @@ display: flex; flex-flow: row; justify-content: space-between; - color: #888ea3; + color: var(--color-text-muted); } &__container { @@ -34,7 +34,7 @@ &__fee { @include Paragraph; - color: #313a5e; + color: var(--color-text-alternative); } &__time-remaining { @@ -42,7 +42,7 @@ /*rtl:ignore*/ direction: ltr; - color: #313a5e; + color: var(--color-text-alternative); .minutes-num, .seconds-num { @@ -65,15 +65,15 @@ &__fee-chart { margin-top: 8px; height: 265px; - background: #f8f9fb; - border-bottom: 1px solid #d2d8dd; - border-top: 1px solid #d2d8dd; + background: var(--color-background-alternative); + border-bottom: 1px solid var(--color-border-muted); + border-top: 1px solid var(--color-border-muted); position: relative; &__title { @include H7; - color: #313a5e; + color: var(--color-text-alternative); margin-left: 22px; } @@ -87,7 +87,7 @@ padding-left: 20px; padding-right: 19px; width: 100%; - color: #888ea3; + color: var(--color-text-alternative); } .loading-overlay { diff --git a/ui/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.scss index ce4b48e31..235e52b95 100644 --- a/ui/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.scss +++ b/ui/components/app/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -11,14 +11,14 @@ @include Paragraph; margin-top: 19px; - color: var(--black); + color: var(--color-text-default); } &__blurb { @include H7; width: 95%; - color: var(--black); + color: var(--color-text-default); margin-top: 5px; margin-bottom: 15px; } @@ -27,7 +27,7 @@ @include H7; width: 95%; - color: #979797; + color: var(--color-text-alternative); margin-top: 15px; } } diff --git a/ui/components/app/gas-customization/gas-modal-page-container/index.scss b/ui/components/app/gas-customization/gas-modal-page-container/index.scss index 85b8a981c..70d759d21 100644 --- a/ui/components/app/gas-customization/gas-modal-page-container/index.scss +++ b/ui/components/app/gas-customization/gas-modal-page-container/index.scss @@ -33,7 +33,7 @@ &__header-close-text { @include H6; - color: #4eade7; + color: var(--color-primary-default); position: absolute; font-size: 0.75rem; top: 8px; @@ -46,7 +46,7 @@ &__title { @include H5; - color: var(--black); + color: var(--color-text-default); font-weight: 500; display: flex; justify-content: center; @@ -80,7 +80,7 @@ } &.tab--active button { - color: var(--primary-blue); + color: var(--color-primary-default); } } } @@ -101,11 +101,11 @@ @include H7; width: 100%; - background: var(--polar); + background: var(--color-background-alternative); padding: 15px 21px; display: flex; flex-flow: column; - color: var(--scorpion); + color: var(--color-text-alternative); &__send-info, &__transaction-info, @@ -153,8 +153,8 @@ } &__info-row--fade { - background: white; - color: var(--dusty-gray); - border-top: 1px solid var(--mischka); + background: var(--color-background-default); + color: var(--color-text-muted); + border-top: 1px solid var(--color-border-muted); } } diff --git a/ui/components/app/gas-customization/gas-price-button-group/index.scss b/ui/components/app/gas-customization/gas-price-button-group/index.scss index 0619b545e..5573d923d 100644 --- a/ui/components/app/gas-customization/gas-price-button-group/index.scss +++ b/ui/components/app/gas-customization/gas-price-button-group/index.scss @@ -15,7 +15,7 @@ &__time-estimate { margin-top: 5.5px; - color: var(--silver-chalice); + color: var(--color-text-alternative); height: 15.4px; } @@ -34,9 +34,9 @@ display: flex; padding-top: 17px; border-radius: 4px; - border-color: var(--spindle); - background: var(--white); - color: var(--scorpion); + border-color: var(--color-primary-muted); + background: var(--color-background-default); + color: var(--color-text-alternative); div { display: flex; @@ -52,13 +52,13 @@ } .button-group__button--active { - border-color: var(--primary-blue); - color: var(--scorpion); + border-color: var(--color-primary-default); + color: var(--color-text-alternative); i { &:last-child { display: flex; - color: var(--primary-blue); + color: var(--color-primary-default); margin-top: 8px; } } @@ -114,8 +114,8 @@ .button-group__button, .button-group__button--active { - background: white; - color: var(--scorpion); + background: var(--color-background-default); + color: var(--color-text-alternative); padding: 4px; div { @@ -133,13 +133,13 @@ } .button-group__button--active { - color: var(--white); - background: var(--dodger-blue); + color: var(--color-background-default); + background: var(--color-primary-muted); i { &:last-child { display: flex; - color: var(--primary-blue); + color: var(--color-primary-default); margin-top: 10px; } } @@ -185,14 +185,14 @@ font-weight: 500; margin-top: 4px; - color: var(--black); + color: var(--color-text-default); } .button-group__button, .button-group__button--active { height: 78px; - background: white; - color: #2a4055; + background: var(--color-background-default); + color: var(--color-text-default); width: 108px; height: 97px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.151579); @@ -221,11 +221,11 @@ } .button-group__button--active { - background: #f7fcff; - border-color: #2c8bdc; + background: var(--color-background-alternative); + border-color: var(--color-primary-default); &:first-child { - border-color: #2c8bdc; + border-color: var(--color-primary-default); } .button-check-wrapper { @@ -235,7 +235,7 @@ position: absolute; top: -11px; right: -10px; - background: #d5ecfa; + background: var(--color-background-alternative); display: flex; flex-flow: row; justify-content: center; @@ -244,7 +244,7 @@ i { display: flex; - color: var(--primary-blue); + color: var(--color-primary-default); font-weight: 900; } } diff --git a/ui/components/app/gas-customization/gas-slider/index.scss b/ui/components/app/gas-customization/gas-slider/index.scss index d7d1dc055..876c5664b 100644 --- a/ui/components/app/gas-customization/gas-slider/index.scss +++ b/ui/components/app/gas-customization/gas-slider/index.scss @@ -16,7 +16,7 @@ -webkit-appearance: none !important; height: 34px; width: 34px; - background-color: var(--primary-blue); + background-color: var(--color-primary-default); box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.08); border-radius: 50%; position: relative; @@ -26,7 +26,7 @@ &__bar { height: 6px; width: 322px; - background: var(--alto); + background: var(--color-background-alternative); display: flex; justify-content: space-between; position: absolute; @@ -41,7 +41,7 @@ margin-left: 102px; width: 322px; z-index: 1; - background-color: var(--blizzard-blue); + background-color: var(--color-primary-muted); } &__labels { @@ -50,6 +50,6 @@ display: flex; justify-content: space-between; margin-top: -6px; - color: var(--mid-gray); + color: var(--color-text-alternative); } } diff --git a/ui/components/app/gas-details-item/gas-details-item-title/index.scss b/ui/components/app/gas-details-item/gas-details-item-title/index.scss index eab165081..341732627 100644 --- a/ui/components/app/gas-details-item/gas-details-item-title/index.scss +++ b/ui/components/app/gas-details-item/gas-details-item-title/index.scss @@ -3,7 +3,7 @@ font-weight: 400; font-style: italic; font-size: 12px; - color: var(--Grey-500); + color: var(--color-text-alternative); line-height: inherit; } } diff --git a/ui/components/app/gas-details-item/index.scss b/ui/components/app/gas-details-item/index.scss index 64c6fcfe3..43b2da44b 100644 --- a/ui/components/app/gas-details-item/index.scss +++ b/ui/components/app/gas-details-item/index.scss @@ -1,6 +1,6 @@ .gas-details-item { &__gas-fee-warning { - color: var(--secondary-1); + color: var(--color-secondary-default); //@TODO: revisit when warning color tokens are revisited } &__currency-container, diff --git a/ui/components/app/gas-timing/index.scss b/ui/components/app/gas-timing/index.scss index bd4e03c3e..ca8d1e989 100644 --- a/ui/components/app/gas-timing/index.scss +++ b/ui/components/app/gas-timing/index.scss @@ -1,26 +1,26 @@ .typography.gas-timing { - color: var(--ui-4); + color: var(--color-text-alternative); &--positive { - color: var(--success-3); + color: var(--color-success-default); } &--positive-V2 { - color: var(--success-3); + color: var(--color-success-default); font-weight: bold; } &--warning { - color: var(--alert-3); + color: var(--color-warning-default); } &--negative { - color: var(--error-1); + color: var(--color-error-default); font-weight: bold; } &--negative-V2 { - color: var(--secondary-1); + color: var(--color-secondary-default); font-weight: bold; } @@ -29,7 +29,7 @@ margin-inline-start: 4px; path { - fill: var(--error-1); + fill: var(--color-error-default); } } } diff --git a/ui/components/ui/info-tooltip/index.scss b/ui/components/ui/info-tooltip/index.scss index 03bc51dde..28beeebfc 100644 --- a/ui/components/ui/info-tooltip/index.scss +++ b/ui/components/ui/info-tooltip/index.scss @@ -13,29 +13,29 @@ .tippy-popper[x-placement^=top] .tippy-tooltip-info-theme [x-arrow], .tippy-popper[x-placement^=top] .tippy-tooltip-wideInfo-theme [x-arrow] { - border-top-color: var(--white); + border-top-color: var(--color-background-default); } .tippy-popper[x-placement^=right] .tippy-tooltip-info-theme [x-arrow], .tippy-popper[x-placement^=right] .tippy-tooltip-wideInfo-theme [x-arrow] { - border-right-color: var(--white); + border-right-color: var(--color-background-default); } .tippy-popper[x-placement^=left] .tippy-tooltip-info-theme [x-arrow], .tippy-popper[x-placement^=left] .tippy-tooltip-wideInfo-theme [x-arrow] { - border-left-color: var(--white); + border-left-color: var(--color-background-default); } .tippy-popper[x-placement^=bottom] .tippy-tooltip-info-theme [x-arrow], .tippy-popper[x-placement^=bottom] .tippy-tooltip-wideInfo-theme [x-arrow] { - border-bottom-color: var(--white); + border-bottom-color: var(--color-background-default); } .tippy-tooltip { &#{&}-info-theme, &#{&}-wideInfo-theme { - background: white; - color: black; + background: var(--color-background-default); + color: var(--color-text-default); box-shadow: 0 0 14px rgba(0, 0, 0, 0.18); border-radius: 8px; max-width: 203px; @@ -46,10 +46,10 @@ @include H7; text-align: left; - color: var(--Grey-500); + color: var(--color-text-alternative); a { - color: var(--primary-1); + color: var(--color-primary-default); } p { diff --git a/ui/components/ui/radio-group/index.scss b/ui/components/ui/radio-group/index.scss index 06d0ed554..43585036a 100644 --- a/ui/components/ui/radio-group/index.scss +++ b/ui/components/ui/radio-group/index.scss @@ -36,28 +36,28 @@ &__column-start-connector { width: calc(50% + 0.5px); height: 6px; - border-left: 1px solid var(--ui-2); - border-bottom: 1px solid var(--ui-2); + border-left: 1px solid var(--color-border-muted); + border-bottom: 1px solid var(--color-border-muted); align-self: flex-end; } &__column-end-connector { width: calc(50% + 0.5px); height: 6px; - border-right: 1px solid var(--ui-2); - border-bottom: 1px solid var(--ui-2); + border-right: 1px solid var(--color-border-muted); + border-bottom: 1px solid var(--color-border-muted); align-self: flex-start; } &__column-vertical-line { width: 1px; height: 5px; - border-left: 1px solid var(--ui-2); + border-left: 1px solid var(--color-border-muted); } &__column-horizontal-line { height: 1px; - border-bottom: 1px solid var(--ui-2); + border-bottom: 1px solid var(--color-border-muted); width: 100%; } diff --git a/ui/components/ui/radio-group/radio-group.component.js b/ui/components/ui/radio-group/radio-group.component.js index 0704de2a2..dce4e09b9 100644 --- a/ui/components/ui/radio-group/radio-group.component.js +++ b/ui/components/ui/radio-group/radio-group.component.js @@ -69,7 +69,7 @@ export default function RadioGroup({ options, name, selectedValue, onChange }) { isLast={index === options.length - 1} /> Date: Sat, 19 Mar 2022 01:43:33 +0100 Subject: [PATCH 055/192] Dark Mode : Onboarding flow (#14020) --- .../create-new-vault/create-new-vault.scss | 2 +- ui/components/app/srp-input/srp-input.js | 3 +- .../app/step-progress-bar/index.scss | 34 +++++++++---------- ui/components/ui/check-box/index.scss | 10 +++--- .../first-time-flow/end-of-flow/index.scss | 2 +- ui/pages/first-time-flow/index.scss | 18 +++++----- .../metametrics-opt-in/index.scss | 12 +++---- .../confirm-seed-phrase/index.scss | 6 ++-- .../first-time-flow/seed-phrase/index.scss | 2 +- .../seed-phrase/reveal-seed-phrase/index.scss | 6 ++-- .../first-time-flow/select-action/index.scss | 10 +++--- ui/pages/first-time-flow/welcome/index.scss | 4 +-- .../create-password/index.scss | 10 +++--- .../onboarding-flow/import-srp/index.scss | 12 +++---- ui/pages/onboarding-flow/index.scss | 4 +-- .../onboarding-app-header/index.scss | 2 +- .../onboarding-flow/pin-extension/index.scss | 4 +-- .../recovery-phrase/index.scss | 10 +++--- .../secure-your-wallet/index.scss | 2 +- ui/pages/onboarding-flow/welcome/index.scss | 9 ++--- 20 files changed, 82 insertions(+), 80 deletions(-) diff --git a/ui/components/app/create-new-vault/create-new-vault.scss b/ui/components/app/create-new-vault/create-new-vault.scss index 305861f39..e24ac7337 100644 --- a/ui/components/app/create-new-vault/create-new-vault.scss +++ b/ui/components/app/create-new-vault/create-new-vault.scss @@ -20,7 +20,7 @@ } &__terms-link { - color: var(--primary-1); + color: var(--color-primary-default); } &__submit-button#{&}__submit-button { diff --git a/ui/components/app/srp-input/srp-input.js b/ui/components/app/srp-input/srp-input.js index 0192ba1b8..9ef216f7f 100644 --- a/ui/components/app/srp-input/srp-input.js +++ b/ui/components/app/srp-input/srp-input.js @@ -7,6 +7,7 @@ import { clearClipboard } from '../../../helpers/utils/util'; import CheckBox from '../../ui/check-box'; import Typography from '../../ui/typography'; import { COLORS } from '../../../helpers/constants/design-system'; +import Textarea from '../../ui/textarea'; import { parseSecretRecoveryPhrase } from './parse-secret-recovery-phrase'; const { isValidMnemonic } = ethers.utils; @@ -50,7 +51,7 @@ export default function SrpInput({ onChange }) { {t('secretRecoveryPhrase')} {showSrp ? ( -