diff --git a/.circleci/config.yml b/.circleci/config.yml index 908ef7722..4955fe38f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -135,16 +135,20 @@ jobs: steps: - checkout - restore_cache: - key: dependency-cache-{{ checksum "yarn.lock" }} + key: dependency-cache-v1-{{ checksum "yarn.lock" }} - run: name: Install deps command: | .circleci/scripts/deps-install.sh - save_cache: - key: dependency-cache-{{ checksum "yarn.lock" }} + key: dependency-cache-v1-{{ checksum "yarn.lock" }} paths: - node_modules/ - build-artifacts/yarn-install-har/ + - run: + name: Postinstall + command: | + yarn setup:postinstall - persist_to_workspace: root: . paths: diff --git a/.circleci/scripts/deps-install.sh b/.circleci/scripts/deps-install.sh index eaab9f2de..7ea3da9cb 100755 --- a/.circleci/scripts/deps-install.sh +++ b/.circleci/scripts/deps-install.sh @@ -5,7 +5,7 @@ set -x # Exit immediately if a command exits with a non-zero status. set -e -yarn setup-ci +yarn install --frozen-lockfile --har # Move HAR file into directory with consistent name so that we can cache it mkdir -p build-artifacts/yarn-install-har diff --git a/CHANGELOG.md b/CHANGELOG.md index b585b20d7..637c22b6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Current Develop Branch +## 9.2.1 Thu Mar 25 2021 +- [#10692](https://github.com/MetaMask/metamask-extension/pull/10692): Prevent UI crash when a 'wallet_requestPermissions" confirmation is queued behind a "wallet_addEthereumChain" confirmation +- [#10712](https://github.com/MetaMask/metamask-extension/pull/10712): Fix infinite spinner when request for token symbol fails while attempting an approve transaction + ## 9.2.0 Tue Mar 09 2021 - [#10546](https://github.com/MetaMask/metamask-extension/pull/10546): Add a warning when sending a token to its own contract address - [#10563](https://github.com/MetaMask/metamask-extension/pull/10563): Update references to MetaMask support diff --git a/app/manifest/_base.json b/app/manifest/_base.json index d32f75c3f..0b7caade1 100644 --- a/app/manifest/_base.json +++ b/app/manifest/_base.json @@ -78,6 +78,6 @@ "notifications" ], "short_name": "__MSG_appName__", - "version": "9.2.0", + "version": "9.2.1", "web_accessible_resources": ["inpage.js", "phishing.html"] } diff --git a/app/scripts/lib/account-tracker.js b/app/scripts/lib/account-tracker.js index 53c6a5c8d..cb4ec51de 100644 --- a/app/scripts/lib/account-tracker.js +++ b/app/scripts/lib/account-tracker.js @@ -286,7 +286,7 @@ export default class AccountTracker { return; } addresses.forEach((address, index) => { - const balance = bnToHex(result[index]); + const balance = result[index] ? bnToHex(result[index]) : '0x0'; accounts[address] = { address, balance }; }); this.store.updateState({ accounts }); diff --git a/package.json b/package.json index a3cb1f318..23f92a21e 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "private": true, "scripts": { - "setup": "yarn install && yarn patch-package && yarn allow-scripts", - "setup-ci": "yarn install --frozen-lockfile --har && yarn patch-package && yarn allow-scripts", + "setup": "yarn install && yarn setup:postinstall", + "setup:postinstall": "yarn patch-package && yarn allow-scripts", "start": "node development/build/index.js dev", "start:lavamoat": "yarn build dev", "dist": "yarn build prod", diff --git a/ui/app/helpers/constants/routes.js b/ui/app/helpers/constants/routes.js index 2079dcf40..61b21b50c 100644 --- a/ui/app/helpers/constants/routes.js +++ b/ui/app/helpers/constants/routes.js @@ -104,6 +104,8 @@ const PATH_NAME_MAP = { [CONNECTED_ACCOUNTS_ROUTE]: 'Accounts Connected To This Site Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id`]: 'Confirmation Root Page', [CONFIRM_TRANSACTION_ROUTE]: 'Confirmation Root Page', + // TODO: rename when this is the only confirmation page + [CONFIRMATION_V_NEXT_ROUTE]: 'New Confirmation Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_TOKEN_METHOD_PATH}`]: 'Confirm Token Method Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_SEND_ETHER_PATH}`]: 'Confirm Send Ether Transaction Page', [`${CONFIRM_TRANSACTION_ROUTE}/:id${CONFIRM_SEND_TOKEN_PATH}`]: 'Confirm Send Token Transaction Page', diff --git a/ui/app/pages/confirm-approve/confirm-approve.js b/ui/app/pages/confirm-approve/confirm-approve.js index cedd987af..c27b1160a 100644 --- a/ui/app/pages/confirm-approve/confirm-approve.js +++ b/ui/app/pages/confirm-approve/confirm-approve.js @@ -88,7 +88,9 @@ export default function ConfirmApprove() { ? getCustomTxParamsData(data, { customPermissionAmount, decimals }) : null; - return tokenSymbol ? ( + return tokenSymbol === undefined ? ( + + ) : ( - ) : ( - ); } diff --git a/ui/app/pages/confirmation/confirmation.js b/ui/app/pages/confirmation/confirmation.js index 47ce4f191..16c09b629 100644 --- a/ui/app/pages/confirmation/confirmation.js +++ b/ui/app/pages/confirmation/confirmation.js @@ -17,7 +17,7 @@ import { DEFAULT_ROUTE } from '../../helpers/constants/routes'; import { stripHttpsScheme } from '../../helpers/utils/util'; import { useI18nContext } from '../../hooks/useI18nContext'; import { useOriginMetadata } from '../../hooks/useOriginMetadata'; -import { getUnapprovedConfirmations } from '../../selectors'; +import { getUnapprovedTemplatedConfirmations } from '../../selectors'; import NetworkDisplay from '../../components/app/network-display/network-display'; import { COLORS, SIZES } from '../../helpers/constants/design-system'; import Callout from '../../components/ui/callout'; @@ -115,7 +115,10 @@ export default function ConfirmationPage() { const t = useI18nContext(); const dispatch = useDispatch(); const history = useHistory(); - const pendingConfirmations = useSelector(getUnapprovedConfirmations, isEqual); + const pendingConfirmations = useSelector( + getUnapprovedTemplatedConfirmations, + isEqual, + ); const [currentPendingConfirmation, setCurrentPendingConfirmation] = useState( 0, ); diff --git a/ui/app/pages/confirmation/templates/index.js b/ui/app/pages/confirmation/templates/index.js index b00c1552b..3c90a68fd 100644 --- a/ui/app/pages/confirmation/templates/index.js +++ b/ui/app/pages/confirmation/templates/index.js @@ -12,6 +12,10 @@ const APPROVAL_TEMPLATES = { [MESSAGE_TYPE.SWITCH_ETHEREUM_CHAIN]: switchEthereumChain, }; +export const TEMPLATED_CONFIRMATION_MESSAGE_TYPES = Object.keys( + APPROVAL_TEMPLATES, +); + const ALLOWED_TEMPLATE_KEYS = [ 'content', 'approvalText', diff --git a/ui/app/pages/home/home.component.js b/ui/app/pages/home/home.component.js index 3f9c14caa..84ecd217f 100644 --- a/ui/app/pages/home/home.component.js +++ b/ui/app/pages/home/home.component.js @@ -73,7 +73,7 @@ export default class Home extends PureComponent { setWeb3ShimUsageAlertDismissed: PropTypes.func.isRequired, originOfCurrentTab: PropTypes.string, disableWeb3ShimUsageAlert: PropTypes.func.isRequired, - pendingApprovals: PropTypes.arrayOf(PropTypes.object).isRequired, + pendingConfirmations: PropTypes.arrayOf(PropTypes.object).isRequired, }; state = { @@ -91,7 +91,7 @@ export default class Home extends PureComponent { haveSwapsQuotes, showAwaitingSwapScreen, swapsFetchParams, - pendingApprovals, + pendingConfirmations, } = this.props; this.setState({ mounted: true }); @@ -109,7 +109,7 @@ export default class Home extends PureComponent { history.push(CONFIRM_TRANSACTION_ROUTE); } else if (Object.keys(suggestedTokens).length > 0) { history.push(CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE); - } else if (pendingApprovals.length > 0) { + } else if (pendingConfirmations.length > 0) { history.push(CONFIRMATION_V_NEXT_ROUTE); } } diff --git a/ui/app/pages/home/home.container.js b/ui/app/pages/home/home.container.js index 3a9422486..929833e14 100644 --- a/ui/app/pages/home/home.container.js +++ b/ui/app/pages/home/home.container.js @@ -8,6 +8,7 @@ import { getIsMainnet, getOriginOfCurrentTab, getTotalUnapprovedCount, + getUnapprovedTemplatedConfirmations, getWeb3ShimUsageStateForOrigin, unconfirmedTransactionsCountSelector, } from '../../selectors'; @@ -52,12 +53,12 @@ const mapStateToProps = (state) => { connectedStatusPopoverHasBeenShown, defaultHomeActiveTabName, swapsState, - pendingApprovals = {}, } = metamask; const accountBalance = getCurrentEthBalance(state); const { forgottenPassword, threeBoxLastUpdated } = appState; const totalUnapprovedCount = getTotalUnapprovedCount(state); const swapsEnabled = getSwapsFeatureLiveness(state); + const pendingConfirmations = getUnapprovedTemplatedConfirmations(state); const envType = getEnvironmentType(); const isPopup = envType === ENVIRONMENT_TYPE_POPUP; @@ -102,7 +103,7 @@ const mapStateToProps = (state) => { isMainnet: getIsMainnet(state), originOfCurrentTab, shouldShowWeb3ShimUsageNotification, - pendingApprovals: Object.values(pendingApprovals), + pendingConfirmations, }; }; diff --git a/ui/app/selectors/selectors.js b/ui/app/selectors/selectors.js index 5b6f90c68..6f401220a 100644 --- a/ui/app/selectors/selectors.js +++ b/ui/app/selectors/selectors.js @@ -16,6 +16,19 @@ import { hexToDecimal, } from '../helpers/utils/conversions.util'; import { ETH_SWAPS_TOKEN_OBJECT } from '../helpers/constants/swaps'; +import { TEMPLATED_CONFIRMATION_MESSAGE_TYPES } from '../pages/confirmation/templates'; + +/** + * One of the only remaining valid uses of selecting the network subkey of the + * metamask state tree is to determine if the network is currently 'loading'. + * + * This will be used for all cases where this state key is accessed only for that + * purpose. + * @param {Object} state - redux state object + */ +export function isNetworkLoading(state) { + return state.metamask.network === 'loading'; +} export function getNetworkIdentifier(state) { const { @@ -301,6 +314,13 @@ export function getUnapprovedConfirmations(state) { return Object.values(pendingApprovals); } +export function getUnapprovedTemplatedConfirmations(state) { + const unapprovedConfirmations = getUnapprovedConfirmations(state); + return unapprovedConfirmations.filter((approval) => + TEMPLATED_CONFIRMATION_MESSAGE_TYPES.includes(approval.type), + ); +} + function getSuggestedTokenCount(state) { const { suggestedTokens = {} } = state.metamask; return Object.keys(suggestedTokens).length;