diff --git a/eslint-warning-thresholds.json b/eslint-warning-thresholds.json index b09cda9dd5e..39e61b37cdc 100644 --- a/eslint-warning-thresholds.json +++ b/eslint-warning-thresholds.json @@ -152,12 +152,6 @@ "packages/eip-5792-middleware/src/hooks/processSendCalls.ts": { "@typescript-eslint/no-misused-promises": 1 }, - "packages/eth-json-rpc-provider/src/safe-event-emitter-provider.test.ts": { - "import-x/namespace": 1 - }, - "packages/eth-json-rpc-provider/src/safe-event-emitter-provider.ts": { - "@typescript-eslint/prefer-readonly": 1 - }, "packages/gas-fee-controller/src/GasFeeController.test.ts": { "import-x/namespace": 2, "import-x/order": 1 @@ -258,9 +252,7 @@ "jsdoc/require-returns": 1 }, "packages/network-controller/src/NetworkController.ts": { - "@typescript-eslint/prefer-promise-reject-errors": 1, - "@typescript-eslint/prefer-readonly": 2, - "jsdoc/tag-lines": 1 + "@typescript-eslint/prefer-promise-reject-errors": 1 }, "packages/network-controller/tests/NetworkController.test.ts": { "@typescript-eslint/no-unused-vars": 1, diff --git a/packages/bridge-controller/src/utils/balance.test.ts b/packages/bridge-controller/src/utils/balance.test.ts index 7b818bd0d95..88c3654ea02 100644 --- a/packages/bridge-controller/src/utils/balance.test.ts +++ b/packages/bridge-controller/src/utils/balance.test.ts @@ -2,7 +2,7 @@ import { BigNumber } from '@ethersproject/bignumber'; import { AddressZero } from '@ethersproject/constants'; import { Contract } from '@ethersproject/contracts'; import { Web3Provider } from '@ethersproject/providers'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; import { abiERC20 } from '@metamask/metamask-eth-abis'; import * as balanceUtils from './balance'; @@ -11,7 +11,7 @@ import { FakeProvider } from '../../../../tests/fake-provider'; declare global { // eslint-disable-next-line no-var - var ethereumProvider: SafeEventEmitterProvider; + var ethereumProvider: InternalProvider; } jest.mock('@ethersproject/contracts', () => { diff --git a/packages/eth-json-rpc-provider/CHANGELOG.md b/packages/eth-json-rpc-provider/CHANGELOG.md index d4e5e031fbb..ad7215449cf 100644 --- a/packages/eth-json-rpc-provider/CHANGELOG.md +++ b/packages/eth-json-rpc-provider/CHANGELOG.md @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Replace `SafeEventEmitterProvider` with `InternalProvider` ([#6796](https://github.com/MetaMask/core/pull/6796)) + - The new class is behaviorally equivalent to the previous version except it does not extend `SafeEventEmitter`. + - `SafeEventEmitterProvider` is for now still exported as a deprecated alias of `InternalProvider` for backwards compatibility. - Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708)) ## [5.0.0] diff --git a/packages/eth-json-rpc-provider/package.json b/packages/eth-json-rpc-provider/package.json index d2f70b31fac..4181ff0937c 100644 --- a/packages/eth-json-rpc-provider/package.json +++ b/packages/eth-json-rpc-provider/package.json @@ -54,7 +54,6 @@ "dependencies": { "@metamask/json-rpc-engine": "^10.1.0", "@metamask/rpc-errors": "^7.0.2", - "@metamask/safe-event-emitter": "^3.0.0", "@metamask/utils": "^11.8.1", "uuid": "^8.3.2" }, diff --git a/packages/eth-json-rpc-provider/src/index.test.ts b/packages/eth-json-rpc-provider/src/index.test.ts index e59006be2bd..1c94f265e90 100644 --- a/packages/eth-json-rpc-provider/src/index.test.ts +++ b/packages/eth-json-rpc-provider/src/index.test.ts @@ -4,6 +4,7 @@ describe('Package exports', () => { it('has expected exports', () => { expect(Object.keys(allExports)).toMatchInlineSnapshot(` Array [ + "InternalProvider", "SafeEventEmitterProvider", "providerFromEngine", "providerFromMiddleware", diff --git a/packages/eth-json-rpc-provider/src/index.ts b/packages/eth-json-rpc-provider/src/index.ts index 8eb691ca701..a16f98b675c 100644 --- a/packages/eth-json-rpc-provider/src/index.ts +++ b/packages/eth-json-rpc-provider/src/index.ts @@ -1,3 +1,12 @@ +import { InternalProvider } from './internal-provider'; + export * from './provider-from-engine'; export * from './provider-from-middleware'; -export { SafeEventEmitterProvider } from './safe-event-emitter-provider'; + +/** + * @deprecated Use {@link InternalProvider} instead. + */ +type SafeEventEmitterProvider = InternalProvider; +const SafeEventEmitterProvider = InternalProvider; + +export { InternalProvider, SafeEventEmitterProvider }; diff --git a/packages/eth-json-rpc-provider/src/safe-event-emitter-provider.test.ts b/packages/eth-json-rpc-provider/src/internal-provider.test.ts similarity index 90% rename from packages/eth-json-rpc-provider/src/safe-event-emitter-provider.test.ts rename to packages/eth-json-rpc-provider/src/internal-provider.test.ts index e75b1e1dcd8..3e6a897746a 100644 --- a/packages/eth-json-rpc-provider/src/safe-event-emitter-provider.test.ts +++ b/packages/eth-json-rpc-provider/src/internal-provider.test.ts @@ -6,12 +6,13 @@ import { providerErrors } from '@metamask/rpc-errors'; import { type JsonRpcRequest, type Json } from '@metamask/utils'; import { BrowserProvider } from 'ethers'; import { promisify } from 'util'; +// eslint-disable-next-line import-x/namespace import * as uuid from 'uuid'; import { - SafeEventEmitterProvider, + InternalProvider, convertEip1193RequestToJsonRpcRequest, -} from './safe-event-emitter-provider'; +} from './internal-provider'; jest.mock('uuid'); @@ -34,9 +35,9 @@ function createMockEngine(method: string, response: Json) { return engine; } -describe('SafeEventEmitterProvider', () => { +describe('InternalProvider', () => { it('returns the correct block number with @metamask/eth-query', async () => { - const provider = new SafeEventEmitterProvider({ + const provider = new InternalProvider({ engine: createMockEngine('eth_blockNumber', 42), }); const ethQuery = new EthQuery(provider); @@ -47,7 +48,7 @@ describe('SafeEventEmitterProvider', () => { }); it('returns the correct block number with @metamask/ethjs-query', async () => { - const provider = new SafeEventEmitterProvider({ + const provider = new InternalProvider({ engine: createMockEngine('eth_blockNumber', 42), }); const ethJsQuery = new EthJsQuery(provider); @@ -58,7 +59,7 @@ describe('SafeEventEmitterProvider', () => { }); it('returns the correct block number with Web3Provider', async () => { - const provider = new SafeEventEmitterProvider({ + const provider = new InternalProvider({ engine: createMockEngine('eth_blockNumber', 42), }); const web3Provider = new Web3Provider(provider); @@ -69,7 +70,7 @@ describe('SafeEventEmitterProvider', () => { }); it('returns the correct block number with BrowserProvider', async () => { - const provider = new SafeEventEmitterProvider({ + const provider = new InternalProvider({ engine: createMockEngine('eth_blockNumber', 42), }); const browserProvider = new BrowserProvider(provider); @@ -88,7 +89,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const exampleRequest = { id: 1, jsonrpc: '2.0' as const, @@ -121,7 +122,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const exampleRequest = { method: 'test', params: { @@ -158,7 +159,7 @@ describe('SafeEventEmitterProvider', () => { }), ); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const exampleRequest = { id: 1, jsonrpc: '2.0' as const, @@ -172,9 +173,7 @@ describe('SafeEventEmitterProvider', () => { code: 1001, message: 'Test error', data: { cause: 'Test cause' }, - stack: expect.stringContaining( - 'safe-event-emitter-provider.test.ts:', - ), + stack: expect.stringContaining('internal-provider.test.ts:'), }), ); }); @@ -184,7 +183,7 @@ describe('SafeEventEmitterProvider', () => { engine.push(() => { throw new Error('Test error'); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const exampleRequest = { id: 1, jsonrpc: '2.0' as const, @@ -199,9 +198,7 @@ describe('SafeEventEmitterProvider', () => { message: 'Test error', data: { cause: expect.objectContaining({ - stack: expect.stringContaining( - 'safe-event-emitter-provider.test.ts:', - ), + stack: expect.stringContaining('internal-provider.test.ts:'), message: 'Test error', }), }, @@ -219,7 +216,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSendAsync = promisify(provider.sendAsync); const exampleRequest = { id: 1, @@ -253,7 +250,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSendAsync = promisify(provider.sendAsync); const exampleRequest = { method: 'test', @@ -283,7 +280,7 @@ describe('SafeEventEmitterProvider', () => { engine.push((_req, _res, _next, _end) => { throw new Error('Test error'); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSendAsync = promisify(provider.sendAsync); const exampleRequest = { id: 1, @@ -300,7 +297,7 @@ describe('SafeEventEmitterProvider', () => { describe('send', () => { it('throws if a callback is not provided', () => { const engine = new JsonRpcEngine(); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const exampleRequest = { id: 1, jsonrpc: '2.0' as const, @@ -320,7 +317,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSend = promisify(provider.send); const exampleRequest = { id: 1, @@ -354,7 +351,7 @@ describe('SafeEventEmitterProvider', () => { res.result = 42; end(); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSend = promisify(provider.send); const exampleRequest = { method: 'test', @@ -384,7 +381,7 @@ describe('SafeEventEmitterProvider', () => { engine.push((_req, _res, _next, _end) => { throw new Error('Test error'); }); - const provider = new SafeEventEmitterProvider({ engine }); + const provider = new InternalProvider({ engine }); const promisifiedSend = promisify(provider.send); const exampleRequest = { id: 1, diff --git a/packages/eth-json-rpc-provider/src/safe-event-emitter-provider.ts b/packages/eth-json-rpc-provider/src/internal-provider.ts similarity index 94% rename from packages/eth-json-rpc-provider/src/safe-event-emitter-provider.ts rename to packages/eth-json-rpc-provider/src/internal-provider.ts index e56bbede39a..9c1a59c0df2 100644 --- a/packages/eth-json-rpc-provider/src/safe-event-emitter-provider.ts +++ b/packages/eth-json-rpc-provider/src/internal-provider.ts @@ -1,6 +1,5 @@ import type { JsonRpcEngine } from '@metamask/json-rpc-engine'; import { JsonRpcError } from '@metamask/rpc-errors'; -import SafeEventEmitter from '@metamask/safe-event-emitter'; import type { Json, JsonRpcId, @@ -52,17 +51,16 @@ export function convertEip1193RequestToJsonRpcRequest< * This provider loosely follows conventions that pre-date EIP-1193. * It is not compliant with any Ethereum provider standard. */ -export class SafeEventEmitterProvider extends SafeEventEmitter { - #engine: JsonRpcEngine; +export class InternalProvider { + readonly #engine: JsonRpcEngine; /** - * Construct a SafeEventEmitterProvider from a JSON-RPC engine. + * Construct a InternalProvider from a JSON-RPC engine. * * @param options - Options. * @param options.engine - The JSON-RPC engine used to process requests. */ constructor({ engine }: { engine: JsonRpcEngine }) { - super(); this.#engine = engine; } diff --git a/packages/eth-json-rpc-provider/src/provider-from-engine.ts b/packages/eth-json-rpc-provider/src/provider-from-engine.ts index 00c62bd543c..0f90662507d 100644 --- a/packages/eth-json-rpc-provider/src/provider-from-engine.ts +++ b/packages/eth-json-rpc-provider/src/provider-from-engine.ts @@ -1,6 +1,6 @@ import type { JsonRpcEngine } from '@metamask/json-rpc-engine'; -import { SafeEventEmitterProvider } from './safe-event-emitter-provider'; +import { InternalProvider } from './internal-provider'; /** * Construct an Ethereum provider from the given JSON-RPC engine. @@ -8,8 +8,6 @@ import { SafeEventEmitterProvider } from './safe-event-emitter-provider'; * @param engine - The JSON-RPC engine to construct a provider from. * @returns An Ethereum provider. */ -export function providerFromEngine( - engine: JsonRpcEngine, -): SafeEventEmitterProvider { - return new SafeEventEmitterProvider({ engine }); +export function providerFromEngine(engine: JsonRpcEngine): InternalProvider { + return new InternalProvider({ engine }); } diff --git a/packages/eth-json-rpc-provider/src/provider-from-middleware.ts b/packages/eth-json-rpc-provider/src/provider-from-middleware.ts index 461af247880..e77d4874644 100644 --- a/packages/eth-json-rpc-provider/src/provider-from-middleware.ts +++ b/packages/eth-json-rpc-provider/src/provider-from-middleware.ts @@ -2,8 +2,8 @@ import { JsonRpcEngine } from '@metamask/json-rpc-engine'; import type { JsonRpcMiddleware } from '@metamask/json-rpc-engine'; import type { Json, JsonRpcParams } from '@metamask/utils'; +import type { InternalProvider } from './internal-provider'; import { providerFromEngine } from './provider-from-engine'; -import type { SafeEventEmitterProvider } from './safe-event-emitter-provider'; /** * Construct an Ethereum provider from the given middleware. @@ -14,9 +14,9 @@ import type { SafeEventEmitterProvider } from './safe-event-emitter-provider'; export function providerFromMiddleware< Params extends JsonRpcParams, Result extends Json, ->(middleware: JsonRpcMiddleware): SafeEventEmitterProvider { +>(middleware: JsonRpcMiddleware): InternalProvider { const engine: JsonRpcEngine = new JsonRpcEngine(); engine.push(middleware); - const provider: SafeEventEmitterProvider = providerFromEngine(engine); + const provider: InternalProvider = providerFromEngine(engine); return provider; } diff --git a/packages/network-controller/CHANGELOG.md b/packages/network-controller/CHANGELOG.md index 821d2dd4e5e..ba80d0e9225 100644 --- a/packages/network-controller/CHANGELOG.md +++ b/packages/network-controller/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING:** Use `InternalProvider` instead of `SafeEventEmitterProvider` ([#6796](https://github.com/MetaMask/core/pull/6796)) + - Providers accessible either via network clients or global proxies no longer emit events (or inherit from EventEmitter, for that matter). - Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708)) - Update `@metamask/eth-json-rpc-middleware` from `^17.0.1` to `^18.0.0` ([#6714](https://github.com/MetaMask/core/pull/6714)) - Bump `@metamask/error-reporting-service` from `^2.1.0` to `^2.2.0` ([#6782](https://github.com/MetaMask/core/pull/6782)) diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index 00ad77d0dea..f9ba1610309 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -21,7 +21,10 @@ import type { ErrorReportingServiceCaptureExceptionAction } from '@metamask/erro import type { PollingBlockTrackerOptions } from '@metamask/eth-block-tracker'; import EthQuery from '@metamask/eth-query'; import { errorCodes } from '@metamask/rpc-errors'; -import { createEventEmitterProxy } from '@metamask/swappable-obj-proxy'; +import { + createEventEmitterProxy, + createSwappableProxy, +} from '@metamask/swappable-obj-proxy'; import type { SwappableProxy } from '@metamask/swappable-obj-proxy'; import type { Hex } from '@metamask/utils'; import { hasProperty, isPlainObject, isStrictHexString } from '@metamask/utils'; @@ -72,8 +75,6 @@ export type NetworkMetadata = { /** * EIPs supported by the network. */ - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/naming-convention EIPS: { [eipNumber: number]: boolean; }; @@ -292,8 +293,6 @@ export type UpdateNetworkFields = Omit & { * @returns The keys of an object, typed according to the type of the object * itself. */ -// TODO: Either fix this lint violation or explain why it's necessary to ignore. -// eslint-disable-next-line @typescript-eslint/naming-convention export function knownKeysOf( // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -708,7 +707,7 @@ function getDefaultInfuraNetworkConfigurationsByChainId(): Record< } const rpcEndpointUrl = - // This ESLint rule mistakenly produces an error. + // False positive - this is a string. // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const; @@ -1139,7 +1138,7 @@ export class NetworkController extends BaseController< > { #ethQuery?: EthQuery; - #infuraProjectId: string; + readonly #infuraProjectId: string; #previouslySelectedNetworkClientId: string; @@ -1153,7 +1152,7 @@ export class NetworkController extends BaseController< | AutoManagedNetworkClient | AutoManagedNetworkClient; - #log: Logger | undefined; + readonly #log: Logger | undefined; readonly #getRpcServiceOptions: NetworkControllerOptions['getRpcServiceOptions']; @@ -1236,8 +1235,6 @@ export class NetworkController extends BaseController< ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:getEthQuery`, () => { return this.#ethQuery; @@ -1245,50 +1242,36 @@ export class NetworkController extends BaseController< ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:getNetworkClientById`, this.getNetworkClientById.bind(this), ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:getEIP1559Compatibility`, this.getEIP1559Compatibility.bind(this), ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:setActiveNetwork`, this.setActiveNetwork.bind(this), ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:setProviderType`, this.setProviderType.bind(this), ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:findNetworkClientIdByChainId`, this.findNetworkClientIdByChainId.bind(this), ); this.messagingSystem.registerActionHandler( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:getNetworkConfigurationByChainId`, this.getNetworkConfigurationByChainId.bind(this), ); this.messagingSystem.registerActionHandler( - // ESLint is mistaken here; `name` is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:getNetworkConfigurationByNetworkClientId`, this.getNetworkConfigurationByNetworkClientId.bind(this), ); @@ -1304,22 +1287,16 @@ export class NetworkController extends BaseController< ); this.messagingSystem.registerActionHandler( - // ESLint is mistaken here; `name` is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:addNetwork`, this.addNetwork.bind(this), ); this.messagingSystem.registerActionHandler( - // ESLint is mistaken here; `name` is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:removeNetwork`, this.removeNetwork.bind(this), ); this.messagingSystem.registerActionHandler( - // ESLint is mistaken here; `name` is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${this.name}:updateNetwork`, this.updateNetwork.bind(this), ); @@ -1386,6 +1363,7 @@ export class NetworkController extends BaseController< /** * Accesses the provider and block tracker for the currently selected network. + * * @returns The proxy and block tracker proxies. * @deprecated This method has been replaced by `getSelectedNetworkClient` (which has a more easily used return type) and will be removed in a future release. */ @@ -1495,8 +1473,6 @@ export class NetworkController extends BaseController< /* istanbul ignore if */ if (!infuraNetworkClient) { throw new Error( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `No Infura network client was found with the ID "${networkClientId}".`, ); } @@ -1509,8 +1485,6 @@ export class NetworkController extends BaseController< ]; if (!customNetworkClient) { throw new Error( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `No custom network client was found with the ID "${networkClientId}".`, ); } @@ -1881,8 +1855,6 @@ export class NetworkController extends BaseController< async setProviderType(type: InfuraNetworkType) { if ((type as unknown) === NetworkType.rpc) { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `NetworkController - cannot call "setProviderType" with type "${NetworkType.rpc}". Use "setActiveNetwork"`, ); } @@ -2317,8 +2289,6 @@ export class NetworkController extends BaseController< }) ) { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network: Cannot update RPC endpoints in such a way that the selected network '${this.state.selectedNetworkClientId}' would be removed without a replacement. Choose a different RPC endpoint as the selected network via the \`replacementSelectedRpcEndpointIndex\` option.`, ); } @@ -2561,14 +2531,10 @@ export class NetworkController extends BaseController< if (existingNetworkConfigurationViaChainId !== undefined) { if (existingNetworkConfiguration === null) { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not add network for chain ${args.networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`, ); } else { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Cannot move network from chain ${existingNetworkConfiguration.chainId} to ${networkFields.chainId} as another network for that chain already exists ('${existingNetworkConfigurationViaChainId.name}')`, ); } @@ -2597,8 +2563,6 @@ export class NetworkController extends BaseController< for (const rpcEndpointFields of networkFields.rpcEndpoints) { if (!isValidUrl(rpcEndpointFields.url)) { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${errorMessagePrefix}: An entry in \`rpcEndpoints\` has invalid URL '${rpcEndpointFields.url}'`, ); } @@ -2613,8 +2577,6 @@ export class NetworkController extends BaseController< isInfuraNetworkType(networkClientId) ) { throw new Error( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${errorMessagePrefix}: Custom RPC endpoint '${rpcEndpointFields.url}' has invalid network client ID '${networkClientId}'`, ); } @@ -2628,8 +2590,6 @@ export class NetworkController extends BaseController< ) ) { throw new Error( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `${errorMessagePrefix}: RPC endpoint '${rpcEndpointFields.url}' refers to network client '${networkClientId}' that does not exist`, ); } @@ -2662,14 +2622,10 @@ export class NetworkController extends BaseController< if (rpcEndpoint) { if (mode === 'update') { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network to point to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`, ); } else { throw new Error( - // This ESLint rule mistakenly produces an error. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not add network that points to same RPC endpoint as existing network for chain ${networkConfiguration.chainId} ('${networkConfiguration.name}')`, ); } @@ -2722,12 +2678,8 @@ export class NetworkController extends BaseController< if (networkFields.chainId !== infuraChainId) { throw new Error( mode === 'add' - ? // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - `Could not add network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict` - : // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions - `Could not update network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`, + ? `Could not add network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict` + : `Could not update network with chain ID ${networkFields.chainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`, ); } } @@ -3155,7 +3107,7 @@ export class NetworkController extends BaseController< if (this.#providerProxy) { this.#providerProxy.setTarget(this.#autoManagedNetworkClient.provider); } else { - this.#providerProxy = createEventEmitterProxy( + this.#providerProxy = createSwappableProxy( this.#autoManagedNetworkClient.provider, ); } @@ -3167,7 +3119,9 @@ export class NetworkController extends BaseController< } else { this.#blockTrackerProxy = createEventEmitterProxy( this.#autoManagedNetworkClient.blockTracker, - { eventFilter: 'skipInternal' }, + { + eventFilter: 'skipInternal', + }, ); } diff --git a/packages/network-controller/src/create-auto-managed-network-client.test.ts b/packages/network-controller/src/create-auto-managed-network-client.test.ts index 662b0f1a7df..e3dc65205fd 100644 --- a/packages/network-controller/src/create-auto-managed-network-client.test.ts +++ b/packages/network-controller/src/create-auto-managed-network-client.test.ts @@ -78,21 +78,6 @@ describe('createAutoManagedNetworkClient', () => { }); // This also tests the `has` trap in the proxy - expect('addListener' in provider).toBe(true); - expect('on' in provider).toBe(true); - expect('once' in provider).toBe(true); - expect('removeListener' in provider).toBe(true); - expect('off' in provider).toBe(true); - expect('removeAllListeners' in provider).toBe(true); - expect('setMaxListeners' in provider).toBe(true); - expect('getMaxListeners' in provider).toBe(true); - expect('listeners' in provider).toBe(true); - expect('rawListeners' in provider).toBe(true); - expect('emit' in provider).toBe(true); - expect('listenerCount' in provider).toBe(true); - expect('prependListener' in provider).toBe(true); - expect('prependOnceListener' in provider).toBe(true); - expect('eventNames' in provider).toBe(true); expect('send' in provider).toBe(true); expect('sendAsync' in provider).toBe(true); expect('request' in provider).toBe(true); diff --git a/packages/network-controller/src/create-auto-managed-network-client.ts b/packages/network-controller/src/create-auto-managed-network-client.ts index 0c4edd5ad3d..5ab700a1737 100644 --- a/packages/network-controller/src/create-auto-managed-network-client.ts +++ b/packages/network-controller/src/create-auto-managed-network-client.ts @@ -52,8 +52,6 @@ export type AutoManagedNetworkClient< * This is impossible when using the Proxy API, as the target object has to be * something, so this object represents that "something". */ -// TODO: Either fix this lint violation or explain why it's necessary to ignore. -// eslint-disable-next-line @typescript-eslint/naming-convention const UNINITIALIZED_TARGET = { __UNINITIALIZED__: true }; /** diff --git a/packages/network-controller/src/create-network-client.ts b/packages/network-controller/src/create-network-client.ts index 38fa0b620ea..515c625816c 100644 --- a/packages/network-controller/src/create-network-client.ts +++ b/packages/network-controller/src/create-network-client.ts @@ -12,7 +12,7 @@ import { createFetchMiddleware, createRetryOnEmptyMiddleware, } from '@metamask/eth-json-rpc-middleware'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; import { providerFromEngine, providerFromMiddleware, @@ -208,7 +208,7 @@ function createBlockTracker({ getOptions: ( rpcEndpointUrl: string, ) => Omit; - provider: SafeEventEmitterProvider; + provider: InternalProvider; }) { const testOptions = process.env.IN_TEST && networkClientType === NetworkClientType.Custom @@ -240,7 +240,7 @@ function createInfuraNetworkMiddleware({ }: { blockTracker: PollingBlockTracker; network: InfuraNetworkType; - rpcProvider: SafeEventEmitterProvider; + rpcProvider: InternalProvider; rpcApiMiddleware: JsonRpcMiddleware; }) { return mergeMiddleware([ @@ -267,8 +267,6 @@ function createNetworkAndChainIdMiddleware({ network: InfuraNetworkType; }) { return createScaffoldMiddleware({ - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/naming-convention eth_chainId: ChainId[network], }); } diff --git a/packages/network-controller/src/types.ts b/packages/network-controller/src/types.ts index adffecf160a..bcc0894f6ea 100644 --- a/packages/network-controller/src/types.ts +++ b/packages/network-controller/src/types.ts @@ -1,9 +1,9 @@ import type { InfuraNetworkType, ChainId } from '@metamask/controller-utils'; import type { BlockTracker as BaseBlockTracker } from '@metamask/eth-block-tracker'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; import type { Hex } from '@metamask/utils'; -export type Provider = SafeEventEmitterProvider; +export type Provider = InternalProvider; export type BlockTracker = BaseBlockTracker & { checkForLatestBlock(): Promise; diff --git a/packages/network-controller/tests/NetworkController.test.ts b/packages/network-controller/tests/NetworkController.test.ts index 358fbb79e2d..24de72e542d 100644 --- a/packages/network-controller/tests/NetworkController.test.ts +++ b/packages/network-controller/tests/NetworkController.test.ts @@ -1368,11 +1368,7 @@ describe('NetworkController', () => { const infuraChainId = ChainId[infuraNetworkType]; const infuraNetworkNickname = NetworkNickname[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`when the selectedNetworkClientId is changed to represent the Infura network "${infuraNetworkType}"`, () => { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`returns a provider object that was pointed to another network before the switch and is now pointed to ${infuraNetworkNickname} afterward`, async () => { const infuraProjectId = 'some-infura-project-id'; @@ -2411,8 +2407,6 @@ describe('NetworkController', () => { jest .spyOn(messenger, 'unsubscribe') .mockImplementation((eventType) => { - // This is okay. - // eslint-disable-next-line jest/no-conditional-in-test if (eventType === 'NetworkController:networkDidChange') { throw error; } @@ -2922,8 +2916,6 @@ describe('NetworkController', () => { jest .spyOn(messenger, 'unsubscribe') .mockImplementation((eventType) => { - // This is okay. - // eslint-disable-next-line jest/no-conditional-in-test if (eventType === 'NetworkController:networkDidChange') { throw error; } @@ -2962,8 +2954,6 @@ describe('NetworkController', () => { describe('setProviderType', () => { for (const infuraNetworkType of INFURA_NETWORKS) { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the Infura network "${infuraNetworkType}"`, () => { refreshNetworkTests({ expectedNetworkClientConfiguration: @@ -2975,8 +2965,6 @@ describe('NetworkController', () => { }); }); - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`sets selectedNetworkClientId in state to "${infuraNetworkType}"`, async () => { await withController(async ({ controller }) => { mockCreateNetworkClient().mockReturnValue(buildFakeClient()); @@ -3118,8 +3106,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`if the ID refers to a network client created for the Infura network "${infuraNetworkType}"`, () => { refreshNetworkTests({ expectedNetworkClientConfiguration: @@ -3145,8 +3131,6 @@ describe('NetworkController', () => { }, }); - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`sets selectedNetworkClientId in state to "${infuraNetworkType}"`, async () => { await withController({}, async ({ controller }) => { mockCreateNetworkClient().mockReturnValue(buildFakeClient()); @@ -3640,8 +3624,6 @@ describe('NetworkController', () => { describe('resetConnection', () => { for (const infuraNetworkType of INFURA_NETWORKS) { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`when the selected network client represents the Infura network "${infuraNetworkType}"`, () => { refreshNetworkTests({ expectedNetworkClientConfiguration: @@ -3756,8 +3738,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the ID of the Infura-supported chain "${infuraNetworkType}" that a network configuration is filed under`, () => { it('returns the network configuration', async () => { const registeredNetworkConfiguration = @@ -3871,8 +3851,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the ID of a network client that corresponds to an RPC endpoint for the Infura network "${infuraNetworkType}" in a network configuration`, () => { it('returns the network configuration', async () => { const registeredNetworkConfiguration = @@ -3979,8 +3957,6 @@ describe('NetworkController', () => { expect(() => controller.addNetwork( buildAddNetworkFields({ - // False negative - this is a number. - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands chainId: toHex(MAX_SAFE_CHAIN_ID + 1), }), ), @@ -4130,8 +4106,6 @@ describe('NetworkController', () => { const infuraNetworkNickname = NetworkNickname[infuraNetworkType]; const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`throws if rpcEndpoints contains an Infura RPC endpoint which is already present in the network configuration for the Infura-supported chain ${infuraChainId}`, async () => { const infuraRpcEndpoint = buildInfuraRpcEndpoint(infuraNetworkType); @@ -4158,8 +4132,6 @@ describe('NetworkController', () => { }), ), ).toThrow( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not add network that points to same RPC endpoint as existing network for chain ${infuraChainId} ('${infuraNetworkNickname}')`, ); }, @@ -4281,8 +4253,6 @@ describe('NetworkController', () => { const infuraNetworkNickname = NetworkNickname[infuraNetworkType]; const infuraChainId = ChainId[infuraNetworkType]; - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`throws if a network configuration for the Infura network "${infuraNetworkNickname}" is already registered under the given chain ID`, async () => { await withController( { @@ -4302,8 +4272,6 @@ describe('NetworkController', () => { }), ), ).toThrow( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not add network for chain ${infuraChainId} as another network for that chain already exists ('${infuraNetworkNickname}')`, ); }, @@ -4342,8 +4310,6 @@ describe('NetworkController', () => { const infuraNetworkNickname = NetworkNickname[infuraNetworkType]; const infuraNativeTokenName = NetworksTicker[infuraNetworkType]; - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the ID of the Infura-supported chain ${infuraChainId}`, () => { it('creates a new network client for not only each custom RPC endpoint, but also the Infura RPC endpoint', async () => { uuidV4Mock @@ -4398,8 +4364,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // ESLint is mistaken here. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const, }; @@ -4546,8 +4510,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const, }, { @@ -4577,8 +4539,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, }, { @@ -4633,8 +4593,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const, }, ], @@ -4653,8 +4611,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, }, ], @@ -4696,8 +4652,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}` as const, }, ], @@ -4716,8 +4670,6 @@ describe('NetworkController', () => { name: infuraNetworkNickname, networkClientId: infuraNetworkType, type: RpcEndpointType.Infura as const, - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, }, ], @@ -5167,8 +5119,6 @@ describe('NetworkController', () => { controller.updateNetwork( '0x1337', buildCustomNetworkConfiguration({ - // False negative - this is a number. - // eslint-disable-next-line @typescript-eslint/restrict-plus-operands chainId: toHex(MAX_SAFE_CHAIN_ID + 1), }), ), @@ -5414,8 +5364,6 @@ describe('NetworkController', () => { const infuraNetworkNickname = NetworkNickname[infuraNetworkType]; const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`throws if an Infura RPC endpoint is being added which is already present in the network configuration for the Infura-supported chain ${infuraChainId}`, async () => { const networkConfigurationToUpdate = buildCustomNetworkConfiguration({ chainId: '0x1337', @@ -5444,8 +5392,6 @@ describe('NetworkController', () => { rpcEndpoints: [infuraRpcEndpoint], }), ).rejects.toThrow( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network to point to same RPC endpoint as existing network for chain ${infuraChainId} ('${infuraNetworkNickname}')`, ); }, @@ -5781,8 +5727,6 @@ describe('NetworkController', () => { const infuraChainId = ChainId[infuraNetworkType]; const infuraNativeTokenName = NetworksTicker[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`if the existing chain ID is the Infura-supported chain ${infuraChainId} and is not being changed`, () => { describe('when a new Infura RPC endpoint is being added', () => { it('creates and registers a new network client for the RPC endpoint', async () => { @@ -5844,8 +5788,6 @@ describe('NetworkController', () => { const infuraRpcEndpoint: InfuraRpcEndpoint = { failoverUrls: ['https://failover.endpoint'], networkClientId: infuraNetworkType, - // ESLint is mistaken here. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, type: RpcEndpointType.Infura, }; @@ -5929,8 +5871,6 @@ describe('NetworkController', () => { const infuraRpcEndpoint: InfuraRpcEndpoint = { failoverUrls: ['https://failover.endpoint'], networkClientId: infuraNetworkType, - // ESLint is mistaken here. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, type: RpcEndpointType.Infura, }; @@ -5994,8 +5934,6 @@ describe('NetworkController', () => { const infuraRpcEndpoint: InfuraRpcEndpoint = { failoverUrls: ['https://failover.endpoint'], networkClientId: infuraNetworkType, - // ESLint is mistaken here. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions url: `https://${infuraNetworkType}.infura.io/v3/{infuraProjectId}`, type: RpcEndpointType.Infura, }; @@ -9761,11 +9699,7 @@ describe('NetworkController', () => { const anotherInfuraNetworkNickname = NetworkNickname[anotherInfuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`if the chain ID is being changed from a non-Infura-supported chain to the Infura-supported chain ${infuraChainId}`, () => { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`throws if a network configuration for the Infura network "${infuraNetworkNickname}" is already registered under the new chain ID`, async () => { const networkConfigurationToUpdate = buildCustomNetworkConfiguration({ chainId: '0x1337' }); @@ -9798,8 +9732,6 @@ describe('NetworkController', () => { chainId: infuraChainId, }), ).rejects.toThrow( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Cannot move network from chain 0x1337 to ${infuraChainId} as another network for that chain already exists ('${infuraNetworkNickname}')`, ); }, @@ -9844,8 +9776,6 @@ describe('NetworkController', () => { }), ).rejects.toThrow( new Error( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network to point to same RPC endpoint as existing network for chain ${anotherInfuraChainId} ('${anotherInfuraNetworkNickname}')`, ), ); @@ -10453,8 +10383,6 @@ describe('NetworkController', () => { }); }); - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`if the chain ID is being changed from the Infura-supported chain ${infuraChainId} to a non-Infura-supported chain`, () => { it('throws if a network configuration for a custom network is already registered under the new chain ID', async () => { const networkConfigurationToUpdate = @@ -10490,8 +10418,6 @@ describe('NetworkController', () => { chainId: '0x1337', }), ).rejects.toThrow( - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Cannot move network from chain ${infuraChainId} to 0x1337 as another network for that chain already exists ('Some Network')`, ); }, @@ -10529,8 +10455,6 @@ describe('NetworkController', () => { }), ).rejects.toThrow( new Error( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network with chain ID 0x1337 and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`, ), ); @@ -11186,11 +11110,7 @@ describe('NetworkController', () => { }); }); - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`if the chain ID is being changed from the Infura-supported chain ${infuraChainId} to a different Infura-supported chain ${anotherInfuraChainId}`, () => { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`throws if a network configuration for the Infura network "${infuraNetworkNickname}" is already registered under the new chain ID`, async () => { const networkConfigurationToUpdate = buildInfuraNetworkConfiguration(infuraNetworkType); @@ -11224,8 +11144,6 @@ describe('NetworkController', () => { chainId: anotherInfuraChainId, }), ).rejects.toThrow( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Cannot move network from chain ${infuraChainId} to ${anotherInfuraChainId} as another network for that chain already exists ('${anotherInfuraNetworkNickname}')`, ); }, @@ -11263,8 +11181,6 @@ describe('NetworkController', () => { }), ).rejects.toThrow( new Error( - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Could not update network with chain ID ${anotherInfuraChainId} and Infura RPC endpoint for '${infuraNetworkNickname}' which represents ${infuraChainId}, as the two conflict`, ), ); @@ -12610,8 +12526,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the ID of the Infura-supported chain ${infuraChainId}`, () => { it('makes no updates to state', async () => { const existingNetworkConfiguration = @@ -12957,8 +12871,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // This is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`given the ID of the Infura-supported chain ${infuraChainId}`, () => { it('removes the existing network configuration from state', async () => { await withController( @@ -13186,8 +13098,6 @@ describe('NetworkController', () => { describe('rollbackToPreviousProvider', () => { describe('when called not following any network switches', () => { for (const infuraNetworkType of INFURA_NETWORKS) { - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`when the selected network client represents the Infura network "${infuraNetworkType}"`, () => { refreshNetworkTests({ expectedNetworkClientConfiguration: @@ -13237,8 +13147,6 @@ describe('NetworkController', () => { for (const infuraNetworkType of INFURA_NETWORKS) { const infuraChainId = ChainId[infuraNetworkType]; - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions describe(`when called following a switch away from the Infura network "${infuraNetworkType}"`, () => { it('emits networkWillChange with state payload', async () => { await withController( @@ -13460,8 +13368,6 @@ describe('NetworkController', () => { ); }); - // False negative - this is a string. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`initializes a provider pointed to the "${infuraNetworkType}" Infura network`, async () => { const infuraProjectId = 'some-infura-project-id'; @@ -16275,8 +16181,6 @@ async function setFakeProvider( * @returns A promise that resolves to the list of payloads for the set of * events, optionally filtered, when a specific number of them have occurred. */ -// TODO: Either fix this lint violation or explain why it's necessary to ignore. -// eslint-disable-next-line @typescript-eslint/naming-convention async function waitForPublishedEvents({ messenger, eventType, @@ -16339,10 +16243,8 @@ async function waitForPublishedEvents({ if (interestingEventPayloads.length === expectedNumberOfEvents) { resolve(interestingEventPayloads); } else { - // Using a string instead of an Error leads to better backtraces. - /* eslint-disable-next-line prefer-promise-reject-errors */ reject( - // TODO: Either fix this lint violation or explain why it's necessary to ignore. + // False positive - eventType is a string. // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Expected to receive ${expectedNumberOfEvents} ${eventType} event(s), but received ${ interestingEventPayloads.length diff --git a/packages/network-controller/tests/network-client/block-hash-in-response.ts b/packages/network-controller/tests/network-client/block-hash-in-response.ts index 12f6a7ebeff..0bfae7d9a7e 100644 --- a/packages/network-controller/tests/network-client/block-hash-in-response.ts +++ b/packages/network-controller/tests/network-client/block-hash-in-response.ts @@ -204,8 +204,6 @@ export function testsForRpcMethodsThatCheckForBlockHashInResponse( }); for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method }; const mockResult = emptyValue; @@ -229,8 +227,6 @@ export function testsForRpcMethodsThatCheckForBlockHashInResponse( }); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [{ method }, { method }]; const mockResults = [emptyValue, { blockHash: '0x100' }]; diff --git a/packages/network-controller/tests/network-client/block-param.ts b/packages/network-controller/tests/network-client/block-param.ts index 1f66c39117a..6492ab9b381 100644 --- a/packages/network-controller/tests/network-client/block-param.ts +++ b/packages/network-controller/tests/network-client/block-param.ts @@ -210,8 +210,6 @@ export function testsForRpcMethodSupportingBlockParam( }); for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method, @@ -248,8 +246,6 @@ export function testsForRpcMethodSupportingBlockParam( }); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [ { method, params: buildMockParams({ blockParamIndex, blockParam }) }, @@ -1067,8 +1063,6 @@ export function testsForRpcMethodSupportingBlockParam( ['given a block tag of "earliest"', 'earliest', 'earliest'], ['given a block number', 'block number', '0x100'], ])('%s', (_desc, blockParamType, blockParam) => { - // This lint rule gets confused by `describe.each` - // eslint-disable-next-line jest/no-identical-title it('does not hit the RPC endpoint more than once for identical requests', async () => { const requests = [ { @@ -1234,8 +1228,6 @@ export function testsForRpcMethodSupportingBlockParam( }); for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method, @@ -1262,8 +1254,6 @@ export function testsForRpcMethodSupportingBlockParam( }); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [ { @@ -1372,8 +1362,6 @@ export function testsForRpcMethodSupportingBlockParam( for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { if (providerType === 'infura') { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`retries up to 10 times if a "${emptyValue}" response is returned, returning successful non-empty response if there is one on the 10th try`, async () => { const request = { method, @@ -1413,8 +1401,6 @@ export function testsForRpcMethodSupportingBlockParam( ); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`retries up to 10 times if a "${emptyValue}" response is returned, failing after the 10th try`, async () => { const request = { method, @@ -1453,8 +1439,6 @@ export function testsForRpcMethodSupportingBlockParam( ); }); } else { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method, @@ -1490,8 +1474,6 @@ export function testsForRpcMethodSupportingBlockParam( ); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [ { @@ -1574,8 +1556,6 @@ export function testsForRpcMethodSupportingBlockParam( }); for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method, @@ -1606,8 +1586,6 @@ export function testsForRpcMethodSupportingBlockParam( }); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [ { diff --git a/packages/network-controller/tests/network-client/helpers.ts b/packages/network-controller/tests/network-client/helpers.ts index f5456af666b..3d8dc8d7aa1 100644 --- a/packages/network-controller/tests/network-client/helpers.ts +++ b/packages/network-controller/tests/network-client/helpers.ts @@ -2,7 +2,7 @@ import type { JSONRPCResponse } from '@json-rpc-specification/meta-schema'; import type { InfuraNetworkType } from '@metamask/controller-utils'; import { BUILT_IN_NETWORKS } from '@metamask/controller-utils'; import type { BlockTracker } from '@metamask/eth-block-tracker'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; import EthQuery from '@metamask/eth-query'; import type { Hex } from '@metamask/utils'; import nock, { isDone as nockIsDone } from 'nock'; @@ -390,7 +390,7 @@ export async function withMockedCommunications( type MockNetworkClient = { blockTracker: BlockTracker; - provider: SafeEventEmitterProvider; + provider: InternalProvider; clock: sinon.SinonFakeTimers; // TODO: Replace `any` with type // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/network-controller/tests/network-client/no-block-param.ts b/packages/network-controller/tests/network-client/no-block-param.ts index 8d0ff3c06d5..97b6cbd10e2 100644 --- a/packages/network-controller/tests/network-client/no-block-param.ts +++ b/packages/network-controller/tests/network-client/no-block-param.ts @@ -150,8 +150,6 @@ export function testsForRpcMethodAssumingNoBlockParam( }); for (const emptyValue of [null, undefined, '\u003cnil\u003e']) { - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not retry an empty response of "${emptyValue}"`, async () => { const request = { method }; const mockResult = emptyValue; @@ -175,8 +173,6 @@ export function testsForRpcMethodAssumingNoBlockParam( }); }); - // TODO: Either fix this lint violation or explain why it's necessary to ignore. - // eslint-disable-next-line @typescript-eslint/restrict-template-expressions it(`does not reuse the result of a previous request if it was "${emptyValue}"`, async () => { const requests = [{ method }, { method }]; const mockResults = [emptyValue, 'some result']; diff --git a/packages/selected-network-controller/CHANGELOG.md b/packages/selected-network-controller/CHANGELOG.md index 9aa4122e993..a7f5cc2ed3f 100644 --- a/packages/selected-network-controller/CHANGELOG.md +++ b/packages/selected-network-controller/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Make compatible with `InternalProvider` ([#6796](https://github.com/MetaMask/core/pull/6796)) - Bump `@metamask/utils` from `^11.8.0` to `^11.8.1` ([#6708](https://github.com/MetaMask/core/pull/6708)) - Bump `@metamask/base-controller` from `^8.3.0` to `^8.4.0` ([#6632](https://github.com/MetaMask/core/pull/6632)) - Bump `@metamask/json-rpc-engine` from `^10.0.3` to `^10.1.0` ([#6678](https://github.com/MetaMask/core/pull/6678)) diff --git a/packages/selected-network-controller/src/SelectedNetworkController.ts b/packages/selected-network-controller/src/SelectedNetworkController.ts index 0cf0273eea7..9f07f11b63a 100644 --- a/packages/selected-network-controller/src/SelectedNetworkController.ts +++ b/packages/selected-network-controller/src/SelectedNetworkController.ts @@ -14,7 +14,10 @@ import type { GetSubjects as PermissionControllerGetSubjectsAction, HasPermissions as PermissionControllerHasPermissions, } from '@metamask/permission-controller'; -import { createEventEmitterProxy } from '@metamask/swappable-obj-proxy'; +import { + createEventEmitterProxy, + createSwappableProxy, +} from '@metamask/swappable-obj-proxy'; import type { Hex } from '@metamask/utils'; import type { Patch } from 'immer'; @@ -217,7 +220,6 @@ export class SelectedNetworkController extends BaseController< ); } else if (patch.op === 'replace') { // If the network was updated, redirect to the network's default endpoint - const updatedChainId = patch.path[1] as Hex; if (!chainIdForDomain || chainIdForDomain === updatedChainId) { const network = @@ -365,7 +367,7 @@ export class SelectedNetworkController extends BaseController< } } networkProxy = { - provider: createEventEmitterProxy(networkClient.provider), + provider: createSwappableProxy(networkClient.provider), blockTracker: createEventEmitterProxy(networkClient.blockTracker, { eventFilter: 'skipInternal', }), diff --git a/packages/selected-network-controller/tests/SelectedNetworkController.test.ts b/packages/selected-network-controller/tests/SelectedNetworkController.test.ts index c58c146ed95..8761c04f622 100644 --- a/packages/selected-network-controller/tests/SelectedNetworkController.test.ts +++ b/packages/selected-network-controller/tests/SelectedNetworkController.test.ts @@ -6,7 +6,10 @@ import { getDefaultNetworkControllerState, RpcEndpointType, } from '@metamask/network-controller'; -import { createEventEmitterProxy } from '@metamask/swappable-obj-proxy'; +import { + createEventEmitterProxy, + createSwappableProxy, +} from '@metamask/swappable-obj-proxy'; import type { Hex } from '@metamask/utils'; import type { @@ -150,9 +153,9 @@ const setup = ({ once: jest.fn(), }; - const createEventEmitterProxyMock = jest.mocked(createEventEmitterProxy); + // Non-polluting use of any for test mock. // eslint-disable-next-line @typescript-eslint/no-explicit-any - createEventEmitterProxyMock.mockImplementation((initialTarget: any) => { + const swappableProxyImplementation = (initialTarget: any) => { if (initialTarget?.request !== undefined) { return mockProviderProxy; } @@ -160,7 +163,13 @@ const setup = ({ return mockBlockTrackerProxy; } return mockProviderProxy; - }); + }; + const createSwappableProxyMock = jest + .mocked(createSwappableProxy) + .mockImplementation(swappableProxyImplementation); + const createEventEmitterProxyMock = jest + .mocked(createEventEmitterProxy) + .mockImplementation(swappableProxyImplementation); const messenger = buildMessenger(); const { restrictedMessenger, ...mockMessengerActions } = buildSelectedNetworkControllerMessenger({ @@ -180,6 +189,7 @@ const setup = ({ mockProviderProxy, mockBlockTrackerProxy, domainProxyMap, + createSwappableProxyMock, createEventEmitterProxyMock, ...mockMessengerActions, }; diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 15a3d8e1954..c9420089488 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -12,7 +12,7 @@ import { ORIGIN_METAMASK, InfuraNetworkType, } from '@metamask/controller-utils'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; import EthQuery from '@metamask/eth-query'; import HttpProvider from '@metamask/ethjs-provider-http'; import type { @@ -301,7 +301,7 @@ function buildMockEthQuery(): EthQuery { */ function buildMockBlockTracker( latestBlockNumber: string, - provider: SafeEventEmitterProvider, + provider: InternalProvider, ): BlockTracker { const fakeBlockTracker = new FakeBlockTracker({ provider }); fakeBlockTracker.mockLatestBlockNumber(latestBlockNumber); diff --git a/tests/fake-block-tracker.ts b/tests/fake-block-tracker.ts index 52474b9ae4a..d1313aa175c 100644 --- a/tests/fake-block-tracker.ts +++ b/tests/fake-block-tracker.ts @@ -1,5 +1,5 @@ import { PollingBlockTracker } from '@metamask/eth-block-tracker'; -import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import type { InternalProvider } from '@metamask/eth-json-rpc-provider'; /** * Acts like a PollingBlockTracker, but doesn't start the polling loop or @@ -8,7 +8,7 @@ import type { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; export class FakeBlockTracker extends PollingBlockTracker { #latestBlockNumber = '0x0'; - constructor({ provider }: { provider: SafeEventEmitterProvider }) { + constructor({ provider }: { provider: InternalProvider }) { super({ provider, }); diff --git a/tests/fake-provider.ts b/tests/fake-provider.ts index 4e76a4136f4..7d30aa46216 100644 --- a/tests/fake-provider.ts +++ b/tests/fake-provider.ts @@ -1,4 +1,4 @@ -import { SafeEventEmitterProvider } from '@metamask/eth-json-rpc-provider'; +import { InternalProvider } from '@metamask/eth-json-rpc-provider'; import { JsonRpcEngine } from '@metamask/json-rpc-engine'; import type { Json, @@ -93,16 +93,16 @@ type FakeProviderEngineOptions = { /** * An implementation of the provider that NetworkController exposes, which is - * actually an instance of SafeEventEmitterProvider (from the + * actually an instance of InternalProvider (from the * `@metamask/eth-json-rpc-provider` package). Hence it supports the same - * interface as SafeEventEmitterProvider, except that fake responses for any RPC + * interface as InternalProvider, except that fake responses for any RPC * methods that are accessed can be supplied via an API that is more succinct * than using Jest's mocking API. */ // NOTE: We shouldn't need to extend from the "real" provider here, but -// we'd need a `SafeEventEmitterProvider` _interface_ and that doesn't exist (at +// we'd need a `InternalProvider` _interface_ and that doesn't exist (at // least not yet). -export class FakeProvider extends SafeEventEmitterProvider { +export class FakeProvider extends InternalProvider { calledStubs: FakeProviderStub[]; #originalStubs: FakeProviderStub[]; diff --git a/yarn.lock b/yarn.lock index 8dbaec41939..a2005723c25 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3316,7 +3316,6 @@ __metadata: "@metamask/ethjs-query": "npm:^0.5.3" "@metamask/json-rpc-engine": "npm:^10.1.0" "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/safe-event-emitter": "npm:^3.0.0" "@metamask/utils": "npm:^11.8.1" "@types/jest": "npm:^27.4.1" deepmerge: "npm:^4.2.2"