mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 18:00:18 +01:00
Merge pull request #19159 from MetaMask/Version-v10.30.3
Version v10.30.3 RC
This commit is contained in:
commit
42197a35d9
@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [10.30.3]
|
||||||
|
### Fixed
|
||||||
|
- Restore support for chains that return hex or number responses to `net_version` ([#19156](https://github.com/MetaMask/metamask-extension/pull/19156))
|
||||||
|
|
||||||
## [10.30.2]
|
## [10.30.2]
|
||||||
### Changed
|
### Changed
|
||||||
- Improve `eth_signTypedData_v4` validation ([#19110](https://github.com/MetaMask/metamask-extension/pull/19110))
|
- Improve `eth_signTypedData_v4` validation ([#19110](https://github.com/MetaMask/metamask-extension/pull/19110))
|
||||||
@ -3718,7 +3722,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.30.2...HEAD
|
[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v10.30.3...HEAD
|
||||||
|
[10.30.3]: https://github.com/MetaMask/metamask-extension/compare/v10.30.2...v10.30.3
|
||||||
[10.30.2]: https://github.com/MetaMask/metamask-extension/compare/v10.30.1...v10.30.2
|
[10.30.2]: https://github.com/MetaMask/metamask-extension/compare/v10.30.1...v10.30.2
|
||||||
[10.30.1]: https://github.com/MetaMask/metamask-extension/compare/v10.30.0...v10.30.1
|
[10.30.1]: https://github.com/MetaMask/metamask-extension/compare/v10.30.0...v10.30.1
|
||||||
[10.30.0]: https://github.com/MetaMask/metamask-extension/compare/v10.29.0...v10.30.0
|
[10.30.0]: https://github.com/MetaMask/metamask-extension/compare/v10.29.0...v10.30.0
|
||||||
|
@ -3,6 +3,7 @@ import assert from 'assert';
|
|||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import nock from 'nock';
|
import nock from 'nock';
|
||||||
|
import { toHex } from '@metamask/controller-utils';
|
||||||
import { ControllerMessenger } from '@metamask/base-controller';
|
import { ControllerMessenger } from '@metamask/base-controller';
|
||||||
import { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider';
|
import { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider';
|
||||||
import { when, resetAllWhenMocks } from 'jest-when';
|
import { when, resetAllWhenMocks } from 'jest-when';
|
||||||
@ -2558,6 +2559,9 @@ describe('NetworkController', () => {
|
|||||||
|
|
||||||
describe('when the type in the provider configuration is "rpc"', () => {
|
describe('when the type in the provider configuration is "rpc"', () => {
|
||||||
describe('if both net_version and eth_getBlockByNumber respond successfully', () => {
|
describe('if both net_version and eth_getBlockByNumber respond successfully', () => {
|
||||||
|
const validNetworkIds = [12345, '12345', toHex(12345)];
|
||||||
|
for (const networkId of validNetworkIds) {
|
||||||
|
describe(`with a network id of '${networkId}'`, () => {
|
||||||
it('stores the fact the network is available', async () => {
|
it('stores the fact the network is available', async () => {
|
||||||
await withController(
|
await withController(
|
||||||
{
|
{
|
||||||
@ -2575,7 +2579,9 @@ describe('NetworkController', () => {
|
|||||||
request: {
|
request: {
|
||||||
method: 'net_version',
|
method: 'net_version',
|
||||||
},
|
},
|
||||||
response: SUCCESSFUL_NET_VERSION_RESPONSE,
|
response: {
|
||||||
|
result: networkId,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
request: {
|
request: {
|
||||||
@ -2592,7 +2598,9 @@ describe('NetworkController', () => {
|
|||||||
await controller.initializeProvider();
|
await controller.initializeProvider();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
expect(controller.store.getState().networkStatus).toBe('unknown');
|
expect(controller.store.getState().networkStatus).toBe(
|
||||||
|
'unknown',
|
||||||
|
);
|
||||||
|
|
||||||
await waitForStateChanges({
|
await waitForStateChanges({
|
||||||
controller,
|
controller,
|
||||||
@ -2627,7 +2635,7 @@ describe('NetworkController', () => {
|
|||||||
method: 'net_version',
|
method: 'net_version',
|
||||||
},
|
},
|
||||||
response: {
|
response: {
|
||||||
result: '42',
|
result: networkId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2657,10 +2665,12 @@ describe('NetworkController', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(controller.store.getState().networkId).toBe('42');
|
expect(controller.store.getState().networkId).toBe('12345');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it('stores the fact that the network supports EIP-1559 when baseFeePerGas is in the block header', async () => {
|
it('stores the fact that the network supports EIP-1559 when baseFeePerGas is in the block header', async () => {
|
||||||
await withController(
|
await withController(
|
||||||
@ -3203,6 +3213,332 @@ describe('NetworkController', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('if the request for eth_getBlockByNumber responds successfully, but the request for net_version returns an invalid network ID', () => {
|
||||||
|
it('stores the network status as unknown', async () => {
|
||||||
|
await withController(
|
||||||
|
{
|
||||||
|
state: {
|
||||||
|
provider: {
|
||||||
|
type: 'rpc',
|
||||||
|
rpcUrl: 'https://mock-rpc-url',
|
||||||
|
chainId: '0x1337',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async ({ controller }) => {
|
||||||
|
const fakeProvider = buildFakeProvider([
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_NET_VERSION_RESPONSE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: 'invalid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const fakeNetworkClient = buildFakeClient(fakeProvider);
|
||||||
|
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkStatus'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.initializeProvider();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(controller.store.getState().networkStatus).toBe(
|
||||||
|
'available',
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkStatus'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.lookupNetwork();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(controller.store.getState().networkStatus).toBe('unknown');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clears the ID of the network from state', async () => {
|
||||||
|
await withController(
|
||||||
|
{
|
||||||
|
state: {
|
||||||
|
provider: {
|
||||||
|
type: 'rpc',
|
||||||
|
rpcUrl: 'https://mock-rpc-url',
|
||||||
|
chainId: '0x1337',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async ({ controller }) => {
|
||||||
|
const fakeProvider = buildFakeProvider([
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: '42',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: 'invalid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const fakeNetworkClient = buildFakeClient(fakeProvider);
|
||||||
|
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkStatus'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.initializeProvider();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(controller.store.getState().networkId).toBe('42');
|
||||||
|
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkId'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.lookupNetwork();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(controller.store.getState().networkId).toBeNull();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('clears whether the network supports EIP-1559 from state along with any other network details', async () => {
|
||||||
|
await withController(
|
||||||
|
{
|
||||||
|
state: {
|
||||||
|
provider: {
|
||||||
|
type: 'rpc',
|
||||||
|
rpcUrl: 'https://mock-rpc-url',
|
||||||
|
chainId: '0x1337',
|
||||||
|
},
|
||||||
|
networkDetails: {
|
||||||
|
EIPS: {
|
||||||
|
1559: true,
|
||||||
|
},
|
||||||
|
other: 'details',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async ({ controller }) => {
|
||||||
|
const fakeProvider = buildFakeProvider([
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_NET_VERSION_RESPONSE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: PRE_1559_BLOCK,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: 'invalid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: POST_1559_BLOCK,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const fakeNetworkClient = buildFakeClient(fakeProvider);
|
||||||
|
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkStatus'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.initializeProvider();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(controller.store.getState().networkDetails).toStrictEqual({
|
||||||
|
EIPS: {
|
||||||
|
1559: false,
|
||||||
|
},
|
||||||
|
other: 'details',
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitForStateChanges({
|
||||||
|
controller,
|
||||||
|
propertyPath: ['networkDetails'],
|
||||||
|
operation: async () => {
|
||||||
|
await controller.lookupNetwork();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(controller.store.getState().networkDetails).toStrictEqual({
|
||||||
|
EIPS: {
|
||||||
|
1559: undefined,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not emit infuraIsBlocked', async () => {
|
||||||
|
const { unrestrictedMessenger, restrictedMessenger } =
|
||||||
|
buildMessengerGroup();
|
||||||
|
|
||||||
|
await withController(
|
||||||
|
{
|
||||||
|
messenger: restrictedMessenger,
|
||||||
|
state: {
|
||||||
|
provider: {
|
||||||
|
type: 'rpc',
|
||||||
|
rpcUrl: 'https://mock-rpc-url',
|
||||||
|
chainId: '0x1337',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async ({ controller }) => {
|
||||||
|
const fakeProvider = buildFakeProvider([
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: 'invalid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const fakeNetworkClient = buildFakeClient(fakeProvider);
|
||||||
|
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);
|
||||||
|
await withoutCallingLookupNetwork({
|
||||||
|
controller,
|
||||||
|
operation: async () => {
|
||||||
|
await controller.initializeProvider();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const promiseForNoInfuraIsBlockedEvents = waitForPublishedEvents({
|
||||||
|
messenger: unrestrictedMessenger,
|
||||||
|
eventType: NetworkControllerEventType.InfuraIsBlocked,
|
||||||
|
count: 0,
|
||||||
|
operation: async () => {
|
||||||
|
await controller.lookupNetwork();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await promiseForNoInfuraIsBlockedEvents).toBeTruthy();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('emits infuraIsUnblocked', async () => {
|
||||||
|
const { unrestrictedMessenger, restrictedMessenger } =
|
||||||
|
buildMessengerGroup();
|
||||||
|
|
||||||
|
await withController(
|
||||||
|
{
|
||||||
|
messenger: restrictedMessenger,
|
||||||
|
state: {
|
||||||
|
provider: {
|
||||||
|
type: 'rpc',
|
||||||
|
rpcUrl: 'https://mock-rpc-url',
|
||||||
|
chainId: '0x1337',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async ({ controller }) => {
|
||||||
|
const fakeProvider = buildFakeProvider([
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'net_version',
|
||||||
|
},
|
||||||
|
response: {
|
||||||
|
result: 'invalid',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: {
|
||||||
|
method: 'eth_getBlockByNumber',
|
||||||
|
},
|
||||||
|
response: SUCCESSFUL_ETH_GET_BLOCK_BY_NUMBER_RESPONSE,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
const fakeNetworkClient = buildFakeClient(fakeProvider);
|
||||||
|
mockCreateNetworkClient().mockReturnValue(fakeNetworkClient);
|
||||||
|
await withoutCallingLookupNetwork({
|
||||||
|
controller,
|
||||||
|
operation: async () => {
|
||||||
|
await controller.initializeProvider();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const infuraIsUnblocked = await waitForPublishedEvents({
|
||||||
|
messenger: unrestrictedMessenger,
|
||||||
|
eventType: NetworkControllerEventType.InfuraIsUnblocked,
|
||||||
|
operation: async () => {
|
||||||
|
await controller.lookupNetwork();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(infuraIsUnblocked).toBeTruthy();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('if the request for net_version responds successfully, but the request for eth_getBlockByNumber responds with a generic error', () => {
|
describe('if the request for net_version responds successfully, but the request for eth_getBlockByNumber responds with a generic error', () => {
|
||||||
it('stores the fact that the network is unavailable', async () => {
|
it('stores the fact that the network is unavailable', async () => {
|
||||||
await withController(
|
await withController(
|
||||||
|
@ -10,10 +10,11 @@ import {
|
|||||||
import EthQuery from 'eth-query';
|
import EthQuery from 'eth-query';
|
||||||
import { RestrictedControllerMessenger } from '@metamask/base-controller';
|
import { RestrictedControllerMessenger } from '@metamask/base-controller';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { Hex, isPlainObject } from '@metamask/utils';
|
import { Hex, isPlainObject, isStrictHexString } from '@metamask/utils';
|
||||||
import { errorCodes } from 'eth-rpc-errors';
|
import { errorCodes } from 'eth-rpc-errors';
|
||||||
import { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider';
|
import { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider';
|
||||||
import { PollingBlockTracker } from 'eth-block-tracker';
|
import { PollingBlockTracker } from 'eth-block-tracker';
|
||||||
|
import { hexToDecimal } from '../../../../shared/modules/conversion.utils';
|
||||||
import {
|
import {
|
||||||
INFURA_PROVIDER_TYPES,
|
INFURA_PROVIDER_TYPES,
|
||||||
INFURA_BLOCKED_KEY,
|
INFURA_BLOCKED_KEY,
|
||||||
@ -301,16 +302,22 @@ function isErrorWithCode(error: unknown): error is { code: string | number } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that the given value is a network ID, i.e., that it is a decimal
|
* Convert the given value into a valid network ID. The ID is accepted
|
||||||
* number represented as a string.
|
* as either a number, a decimal string, or a 0x-prefixed hex string.
|
||||||
*
|
*
|
||||||
* @param value - The value to check.
|
* @param value - The network ID to convert, in an unknown format.
|
||||||
|
* @returns A valid network ID (as a decimal string)
|
||||||
|
* @throws If the given value cannot be safely parsed.
|
||||||
*/
|
*/
|
||||||
function assertNetworkId(value: any): asserts value is NetworkId {
|
function convertNetworkId(value: unknown): NetworkId {
|
||||||
assert(
|
if (typeof value === 'number' && !Number.isNaN(value)) {
|
||||||
/^\d+$/u.test(value) && !Number.isNaN(Number(value)),
|
return `${value}`;
|
||||||
'value is not a number',
|
} else if (isStrictHexString(value)) {
|
||||||
);
|
return hexToDecimal(value) as NetworkId;
|
||||||
|
} else if (typeof value === 'string' && /^\d+$/u.test(value)) {
|
||||||
|
return value as NetworkId;
|
||||||
|
}
|
||||||
|
throw new Error(`Cannot parse as a valid network ID: '${value}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -619,8 +626,7 @@ export class NetworkController extends EventEmitter {
|
|||||||
this.#determineEIP1559Compatibility(provider),
|
this.#determineEIP1559Compatibility(provider),
|
||||||
]);
|
]);
|
||||||
const possibleNetworkId = results[0];
|
const possibleNetworkId = results[0];
|
||||||
assertNetworkId(possibleNetworkId);
|
networkId = convertNetworkId(possibleNetworkId);
|
||||||
networkId = possibleNetworkId;
|
|
||||||
supportsEIP1559 = results[1];
|
supportsEIP1559 = results[1];
|
||||||
networkStatus = NetworkStatus.Available;
|
networkStatus = NetworkStatus.Available;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "metamask-crx",
|
"name": "metamask-crx",
|
||||||
"version": "10.30.2",
|
"version": "10.30.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
Loading…
Reference in New Issue
Block a user