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;