1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Merge pull request #15002 from MetaMask/Version-v10.15.1

Version v10.15.1 RC
This commit is contained in:
Dan J Miller 2022-06-22 15:32:24 -02:30 committed by GitHub
commit effc761e0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 97 additions and 52 deletions

1
.iyarc
View File

@ -2,3 +2,4 @@
GHSA-93q8-gq69-wqmw GHSA-93q8-gq69-wqmw
GHSA-257v-vj4p-3w2h GHSA-257v-vj4p-3w2h
GHSA-wm7h-9275-46v2 GHSA-wm7h-9275-46v2
GHSA-pfrx-2q88-qq97

View File

@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [10.15.1]
### Fixed
- Fix Ledger connection failures that can occur after remove all hardware wallet accounts and reconnecting ([#14993](https://github.com/MetaMask/metamask-extension/pull/14993))
- Fix bug that could cause MetaMask to crash in some cases when interacting with tokens or NFTs ([#14962](https://github.com/MetaMask/metamask-extension/pull/14962))
## [10.15.0] ## [10.15.0]
### Added ### Added
- Add warning when multiple instances of MetaMask are running ([#13836](https://github.com/MetaMask/metamask-extension/pull/13836)) - Add warning when multiple instances of MetaMask are running ([#13836](https://github.com/MetaMask/metamask-extension/pull/13836))
@ -2964,7 +2969,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Uncategorized ### Uncategorized
- Added the ability to restore accounts from seed words. - Added the ability to restore accounts from seed words.
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.15.0...HEAD [Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.15.1...HEAD
[10.15.1]: https://github.com/MetaMask/metamask-extension/compare/v10.15.0...v10.15.1
[10.15.0]: https://github.com/MetaMask/metamask-extension/compare/v10.14.7...v10.15.0 [10.15.0]: https://github.com/MetaMask/metamask-extension/compare/v10.14.7...v10.15.0
[10.14.7]: https://github.com/MetaMask/metamask-extension/compare/v10.14.6...v10.14.7 [10.14.7]: https://github.com/MetaMask/metamask-extension/compare/v10.14.6...v10.14.7
[10.14.6]: https://github.com/MetaMask/metamask-extension/compare/v10.14.5...v10.14.6 [10.14.6]: https://github.com/MetaMask/metamask-extension/compare/v10.14.5...v10.14.6

View File

@ -620,11 +620,9 @@ export default class MetaMetricsController {
* @returns {[]} * @returns {[]}
*/ */
_getAllNFTsFlattened = memoize((allCollectibles = {}) => { _getAllNFTsFlattened = memoize((allCollectibles = {}) => {
return Object.values(allCollectibles) return Object.values(allCollectibles).reduce((result, chainNFTs) => {
.reduce((result, chainNFTs) => { return result.concat(...Object.values(chainNFTs));
return result.concat(Object.values(chainNFTs)); }, []);
}, [])
.flat();
}); });
/** /**

View File

@ -77,14 +77,27 @@ async function addEthereumChainHandler(
); );
} }
const isLocalhost = (strUrl) => {
try {
const url = new URL(strUrl);
return url.hostname === 'localhost' || url.hostname === '127.0.0.1';
} catch (error) {
return false;
}
};
const firstValidRPCUrl = Array.isArray(rpcUrls) const firstValidRPCUrl = Array.isArray(rpcUrls)
? rpcUrls.find((rpcUrl) => validUrl.isHttpsUri(rpcUrl)) ? rpcUrls.find(
(rpcUrl) => isLocalhost(rpcUrl) || validUrl.isHttpsUri(rpcUrl),
)
: null; : null;
const firstValidBlockExplorerUrl = const firstValidBlockExplorerUrl =
blockExplorerUrls !== null && Array.isArray(blockExplorerUrls) blockExplorerUrls !== null && Array.isArray(blockExplorerUrls)
? blockExplorerUrls.find((blockExplorerUrl) => ? blockExplorerUrls.find(
validUrl.isHttpsUri(blockExplorerUrl), (blockExplorerUrl) =>
isLocalhost(blockExplorerUrl) ||
validUrl.isHttpsUri(blockExplorerUrl),
) )
: null; : null;

View File

@ -2587,8 +2587,14 @@ export default class MetamaskController extends EventEmitter {
// Remove account from the account tracker controller // Remove account from the account tracker controller
this.accountTracker.removeAccount([address]); this.accountTracker.removeAccount([address]);
const keyring = await this.keyringController.getKeyringForAccount(address);
// Remove account from the keyring // Remove account from the keyring
await this.keyringController.removeAccount(address); await this.keyringController.removeAccount(address);
const updatedKeyringAccounts = keyring ? await keyring.getAccounts() : {};
if (updatedKeyringAccounts?.length === 0) {
keyring.destroy?.();
}
return address; return address;
} }

View File

@ -769,12 +769,20 @@ describe('MetaMaskController', function () {
describe('#removeAccount', function () { describe('#removeAccount', function () {
let ret; let ret;
const addressToRemove = '0x1'; const addressToRemove = '0x1';
let mockKeyring;
beforeEach(async function () { beforeEach(async function () {
mockKeyring = {
getAccounts: sinon.stub().returns(Promise.resolve([])),
destroy: sinon.stub(),
};
sinon.stub(metamaskController.preferencesController, 'removeAddress'); sinon.stub(metamaskController.preferencesController, 'removeAddress');
sinon.stub(metamaskController.accountTracker, 'removeAccount'); sinon.stub(metamaskController.accountTracker, 'removeAccount');
sinon.stub(metamaskController.keyringController, 'removeAccount'); sinon.stub(metamaskController.keyringController, 'removeAccount');
sinon.stub(metamaskController, 'removeAllAccountPermissions'); sinon.stub(metamaskController, 'removeAllAccountPermissions');
sinon
.stub(metamaskController.keyringController, 'getKeyringForAccount')
.returns(Promise.resolve(mockKeyring));
ret = await metamaskController.removeAccount(addressToRemove); ret = await metamaskController.removeAccount(addressToRemove);
}); });
@ -784,6 +792,9 @@ describe('MetaMaskController', function () {
metamaskController.accountTracker.removeAccount.restore(); metamaskController.accountTracker.removeAccount.restore();
metamaskController.preferencesController.removeAddress.restore(); metamaskController.preferencesController.removeAddress.restore();
metamaskController.removeAllAccountPermissions.restore(); metamaskController.removeAllAccountPermissions.restore();
mockKeyring.getAccounts.resetHistory();
mockKeyring.destroy.resetHistory();
}); });
it('should call preferencesController.removeAddress', async function () { it('should call preferencesController.removeAddress', async function () {
@ -817,6 +828,16 @@ describe('MetaMaskController', function () {
it('should return address', async function () { it('should return address', async function () {
assert.equal(ret, '0x1'); assert.equal(ret, '0x1');
}); });
it('should call keyringController.getKeyringForAccount', async function () {
assert(
metamaskController.keyringController.getKeyringForAccount.calledWith(
addressToRemove,
),
);
});
it('should call keyring.destroy', async function () {
assert(mockKeyring.destroy.calledOnce);
});
}); });
describe('#newUnsignedMessage', function () { describe('#newUnsignedMessage', function () {

View File

@ -1,6 +1,6 @@
{ {
"name": "metamask-crx", "name": "metamask-crx",
"version": "10.15.0", "version": "10.15.1",
"private": true, "private": true,
"repository": { "repository": {
"type": "git", "type": "git",
@ -252,7 +252,7 @@
"@metamask/eslint-config-typescript": "^9.0.1", "@metamask/eslint-config-typescript": "^9.0.1",
"@metamask/forwarder": "^1.1.0", "@metamask/forwarder": "^1.1.0",
"@metamask/phishing-warning": "^1.1.0", "@metamask/phishing-warning": "^1.1.0",
"@metamask/test-dapp": "^5.0.0", "@metamask/test-dapp": "^5.1.1",
"@sentry/cli": "^1.58.0", "@sentry/cli": "^1.58.0",
"@storybook/addon-a11y": "^6.3.12", "@storybook/addon-a11y": "^6.3.12",
"@storybook/addon-actions": "^6.3.12", "@storybook/addon-actions": "^6.3.12",

View File

@ -29,8 +29,8 @@ describe('Test Snap Confirm', function () {
await driver.press('#password', driver.Key.ENTER); await driver.press('#password', driver.Key.ENTER);
// navigate to test snaps page and connect // navigate to test snaps page and connect
await driver.driver.get('https://metamask.github.io/test-snaps/'); await driver.driver.get('https://metamask.github.io/test-snaps/0.1.3');
await driver.fill('.snapId', 'npm:@metamask/test-snap-confirm'); await driver.fill('.snapId1', 'npm:@metamask/test-snap-confirm');
await driver.clickElement({ await driver.clickElement({
text: 'Connect To Confirm Snap', text: 'Connect To Confirm Snap',
tag: 'button', tag: 'button',
@ -90,7 +90,7 @@ describe('Test Snap Confirm', function () {
await driver.waitUntilXWindowHandles(1, 5000, 10000); await driver.waitUntilXWindowHandles(1, 5000, 10000);
windowHandles = await driver.getAllWindowHandles(); windowHandles = await driver.getAllWindowHandles();
await driver.switchToWindowWithTitle('Test Snaps', windowHandles); await driver.switchToWindowWithTitle('Test Snaps', windowHandles);
const confirmResult = await driver.findElement('.sendResults'); const confirmResult = await driver.findElement('.confirmResult');
assert.equal(await confirmResult.getText(), 'true'); assert.equal(await confirmResult.getText(), 'true');
}, },
); );

View File

@ -28,7 +28,7 @@ describe('Test Snap Error', function () {
await driver.press('#password', driver.Key.ENTER); await driver.press('#password', driver.Key.ENTER);
// navigate to test snaps page and connect // navigate to test snaps page and connect
await driver.driver.get('https://metamask.github.io/test-snaps/'); await driver.driver.get('https://metamask.github.io/test-snaps/0.1.3');
await driver.fill('.snapId2', 'npm:@metamask/test-snap-error'); await driver.fill('.snapId2', 'npm:@metamask/test-snap-error');
await driver.clickElement({ await driver.clickElement({
text: 'Connect Error Snap', text: 'Connect Error Snap',

View File

@ -2,16 +2,19 @@ const { strict: assert } = require('assert');
const { convertToHexValue, withFixtures } = require('../helpers'); const { convertToHexValue, withFixtures } = require('../helpers');
describe('Chain Interactions', function () { describe('Chain Interactions', function () {
it('should add the XDAI chain and not switch the network', async function () { const port = 8546;
const ganacheOptions = { const chainId = 1338;
accounts: [ const ganacheOptions = {
{ accounts: [
secretKey: {
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC', secretKey:
balance: convertToHexValue(25000000000000000000), '0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
}, balance: convertToHexValue(25000000000000000000),
], },
}; ],
concurrent: { port, chainId },
};
it('should add the Ganache test chain and not switch the network', async function () {
await withFixtures( await withFixtures(
{ {
dapp: true, dapp: true,
@ -36,12 +39,14 @@ describe('Chain Interactions', function () {
); );
// verify chain details // verify chain details
const [networkName, networkUrl, chainId] = await driver.findElements( const [
'.definition-list dd', networkName,
); networkUrl,
assert.equal(await networkName.getText(), 'xDAI Chain'); chainIdElement,
assert.equal(await networkUrl.getText(), 'https://dai.poa.network'); ] = await driver.findElements('.definition-list dd');
assert.equal(await chainId.getText(), '100'); assert.equal(await networkName.getText(), `Localhost ${port}`);
assert.equal(await networkUrl.getText(), `http://127.0.0.1:${port}`);
assert.equal(await chainIdElement.getText(), chainId.toString());
// approve add chain, cancel switch chain // approve add chain, cancel switch chain
await driver.clickElement({ text: 'Approve', tag: 'button' }); await driver.clickElement({ text: 'Approve', tag: 'button' });
@ -55,25 +60,16 @@ describe('Chain Interactions', function () {
const networkDisplay = await driver.findElement('.network-display'); const networkDisplay = await driver.findElement('.network-display');
await networkDisplay.click(); await networkDisplay.click();
assert.equal(await networkDisplay.getText(), 'Localhost 8545'); assert.equal(await networkDisplay.getText(), 'Localhost 8545');
const xDaiChain = await driver.findElements({ const ganacheChain = await driver.findElements({
text: 'xDAI Chain', text: `Localhost ${port}`,
tag: 'span', tag: 'span',
}); });
assert.ok(xDaiChain.length, 1); assert.ok(ganacheChain.length, 1);
}, },
); );
}); });
it('should add the XDAI chain and switch the network', async function () { it('should add the Ganache chain and switch the network', async function () {
const ganacheOptions = {
accounts: [
{
secretKey:
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
balance: convertToHexValue(25000000000000000000),
},
],
};
await withFixtures( await withFixtures(
{ {
dapp: true, dapp: true,
@ -107,7 +103,7 @@ describe('Chain Interactions', function () {
// verify current network // verify current network
const networkDisplay = await driver.findElement('.network-display'); const networkDisplay = await driver.findElement('.network-display');
assert.equal(await networkDisplay.getText(), 'xDAI Chain'); assert.equal(await networkDisplay.getText(), `Localhost ${port}`);
}, },
); );
}); });

View File

@ -23,7 +23,10 @@ describe('Dapp interactions', function () {
{ {
dapp: true, dapp: true,
fixtures: 'imported-account', fixtures: 'imported-account',
ganacheOptions, ganacheOptions: {
...ganacheOptions,
concurrent: { port: 8546, chainId: 1338 },
},
title: this.test.title, title: this.test.title,
}, },
async ({ driver }) => { async ({ driver }) => {
@ -44,6 +47,7 @@ describe('Dapp interactions', function () {
// Trigger Notification // Trigger Notification
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
await driver.clickElement('#addEthereumChain'); await driver.clickElement('#addEthereumChain');
await driver.waitUntilXWindowHandles(3);
await driver.switchToWindowWithTitle( await driver.switchToWindowWithTitle(
'MetaMask Notification', 'MetaMask Notification',
windowHandles, windowHandles,

View File

@ -47,7 +47,7 @@ describe('MetaMask', function () {
await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles); await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
const switchedNetworkDiv = await driver.waitForSelector({ const switchedNetworkDiv = await driver.waitForSelector({
css: '#network', css: '#network',
text: '1', text: '0x1',
}); });
const switchedChainIdDiv = await driver.waitForSelector({ const switchedChainIdDiv = await driver.waitForSelector({
css: '#chainId', css: '#chainId',
@ -55,7 +55,7 @@ describe('MetaMask', function () {
}); });
const accountsDiv = await driver.findElement('#accounts'); const accountsDiv = await driver.findElement('#accounts');
assert.equal(await switchedNetworkDiv.getText(), '1'); assert.equal(await switchedNetworkDiv.getText(), '0x1');
assert.equal(await switchedChainIdDiv.getText(), '0x1'); assert.equal(await switchedChainIdDiv.getText(), '0x1');
assert.equal( assert.equal(
await accountsDiv.getText(), await accountsDiv.getText(),

View File

@ -3080,10 +3080,10 @@
dependencies: dependencies:
"@metamask/controllers" "^28.0.0" "@metamask/controllers" "^28.0.0"
"@metamask/test-dapp@^5.0.0": "@metamask/test-dapp@^5.1.1":
version "5.0.0" version "5.1.1"
resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-5.0.0.tgz#ecea832b57ff97782bfdd57a4af3408c7c64c02d" resolved "https://registry.yarnpkg.com/@metamask/test-dapp/-/test-dapp-5.1.1.tgz#aadebf28542809650c57aa8f5a3489c748e1414f"
integrity sha512-eR9JQ0jPOeP/hdQj9hUkqbvinfjVLYTtdHV+mDCN1tsNxiTdninZbltg9bx6Gqp91v9/9YPhlhXCmMQPq/AMxQ== integrity sha512-Vast76cYR9vOvSH9Ut8y8LXZbDledUE2BkiLX+PGP5AOTp8Pn8V6jiYg1D/slBh7M8/Q/1AmdW9D0B+fw7esBQ==
"@metamask/types@^1.1.0": "@metamask/types@^1.1.0":
version "1.1.0" version "1.1.0"