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:
commit
effc761e0e
1
.iyarc
1
.iyarc
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 () {
|
||||||
|
@ -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",
|
||||||
|
@ -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');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -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',
|
||||||
|
@ -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}`);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user