diff --git a/app/scripts/controllers/network/create-network-client.test.js b/app/scripts/controllers/network/create-network-client.test.js new file mode 100644 index 000000000..7e674392b --- /dev/null +++ b/app/scripts/controllers/network/create-network-client.test.js @@ -0,0 +1,7 @@ +import { NetworkClientType } from './create-network-client'; +import { testsForProviderType } from './provider-api-tests/shared-tests'; + +describe('createNetworkClient', () => { + testsForProviderType(NetworkClientType.Infura); + testsForProviderType(NetworkClientType.Custom); +}); diff --git a/app/scripts/controllers/network/create-network-client.ts b/app/scripts/controllers/network/create-network-client.ts new file mode 100644 index 000000000..6e96b71f5 --- /dev/null +++ b/app/scripts/controllers/network/create-network-client.ts @@ -0,0 +1,191 @@ +import { + createAsyncMiddleware, + createScaffoldMiddleware, + JsonRpcEngine, + mergeMiddleware, + JsonRpcMiddleware, +} from 'json-rpc-engine'; +import { + createBlockCacheMiddleware, + createBlockRefMiddleware, + createBlockRefRewriteMiddleware, + createBlockTrackerInspectorMiddleware, + createInflightCacheMiddleware, + createFetchMiddleware, + createRetryOnEmptyMiddleware, +} from '@metamask/eth-json-rpc-middleware'; +import { + providerFromEngine, + providerFromMiddleware, + SafeEventEmitterProvider, +} from '@metamask/eth-json-rpc-provider'; +import { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura'; +import type { Hex } from '@metamask/utils/dist'; +import { PollingBlockTracker } from 'eth-block-tracker/dist'; +import { SECOND } from '../../../../shared/constants/time'; +import { + BUILT_IN_INFURA_NETWORKS, + BuiltInInfuraNetwork, +} from '../../../../shared/constants/network'; + +export enum NetworkClientType { + Custom = 'custom', + Infura = 'infura', +} + +type CustomNetworkConfiguration = { + chainId: Hex; + rpcUrl: string; + type: NetworkClientType.Custom; +}; + +type InfuraNetworkConfiguration = { + network: BuiltInInfuraNetwork; + infuraProjectId: string; + type: NetworkClientType.Infura; +}; + +/** + * Create a JSON RPC network client for a specific network. + * + * @param networkConfig - The network configuration. + * @returns + */ +export function createNetworkClient( + networkConfig: CustomNetworkConfiguration | InfuraNetworkConfiguration, +): { provider: SafeEventEmitterProvider; blockTracker: PollingBlockTracker } { + const rpcApiMiddleware = + networkConfig.type === NetworkClientType.Infura + ? createInfuraMiddleware({ + network: networkConfig.network, + projectId: networkConfig.infuraProjectId, + maxAttempts: 5, + source: 'metamask', + }) + : createFetchMiddleware({ + btoa: global.btoa, + fetch: global.fetch, + rpcUrl: networkConfig.rpcUrl, + }); + + const rpcProvider = providerFromMiddleware(rpcApiMiddleware); + + const blockTrackerOpts = + process.env.IN_TEST && networkConfig.type === 'custom' + ? { pollingInterval: SECOND } + : {}; + const blockTracker = new PollingBlockTracker({ + ...blockTrackerOpts, + provider: rpcProvider, + }); + + const networkMiddleware = + networkConfig.type === NetworkClientType.Infura + ? createInfuraNetworkMiddleware({ + blockTracker, + network: networkConfig.network, + rpcProvider, + rpcApiMiddleware, + }) + : createCustomNetworkMiddleware({ + blockTracker, + chainId: networkConfig.chainId, + rpcApiMiddleware, + }); + + const engine = new JsonRpcEngine(); + + engine.push(networkMiddleware); + + const provider = providerFromEngine(engine); + + return { provider, blockTracker }; +} + +function createInfuraNetworkMiddleware({ + blockTracker, + network, + rpcProvider, + rpcApiMiddleware, +}: { + blockTracker: PollingBlockTracker; + network: BuiltInInfuraNetwork; + rpcProvider: SafeEventEmitterProvider; + rpcApiMiddleware: JsonRpcMiddleware; +}) { + return mergeMiddleware([ + createNetworkAndChainIdMiddleware({ network }), + createBlockCacheMiddleware({ blockTracker }), + createInflightCacheMiddleware(), + createBlockRefMiddleware({ blockTracker, provider: rpcProvider }), + createRetryOnEmptyMiddleware({ blockTracker, provider: rpcProvider }), + createBlockTrackerInspectorMiddleware({ blockTracker }), + rpcApiMiddleware, + ]); +} + +function createNetworkAndChainIdMiddleware({ + network, +}: { + network: BuiltInInfuraNetwork; +}) { + if (!BUILT_IN_INFURA_NETWORKS[network]) { + throw new Error(`createInfuraClient - unknown network "${network}"`); + } + + const { chainId, networkId } = BUILT_IN_INFURA_NETWORKS[network]; + + return createScaffoldMiddleware({ + eth_chainId: chainId, + net_version: networkId, + }); +} + +const createChainIdMiddleware = ( + chainId: string, +): JsonRpcMiddleware => { + return (req, res, next, end) => { + if (req.method === 'eth_chainId') { + res.result = chainId; + return end(); + } + return next(); + }; +}; + +function createCustomNetworkMiddleware({ + blockTracker, + chainId, + rpcApiMiddleware, +}: { + blockTracker: PollingBlockTracker; + chainId: string; + rpcApiMiddleware: any; +}) { + const testMiddlewares = process.env.IN_TEST + ? [createEstimateGasDelayTestMiddleware()] + : []; + + return mergeMiddleware([ + ...testMiddlewares, + createChainIdMiddleware(chainId), + createBlockRefRewriteMiddleware({ blockTracker }), + createBlockCacheMiddleware({ blockTracker }), + createInflightCacheMiddleware(), + createBlockTrackerInspectorMiddleware({ blockTracker }), + rpcApiMiddleware, + ]); +} + +/** + * For use in tests only. + * Adds a delay to `eth_estimateGas` calls. + */ +function createEstimateGasDelayTestMiddleware() { + return createAsyncMiddleware(async (req, _, next) => { + if (req.method === 'eth_estimateGas') { + await new Promise((resolve) => setTimeout(resolve, SECOND * 2)); + } + return next(); + }); +} diff --git a/app/scripts/controllers/network/createInfuraClient.js b/app/scripts/controllers/network/createInfuraClient.js deleted file mode 100644 index 76461eb62..000000000 --- a/app/scripts/controllers/network/createInfuraClient.js +++ /dev/null @@ -1,49 +0,0 @@ -import { createScaffoldMiddleware, mergeMiddleware } from 'json-rpc-engine'; -import { - createBlockRefMiddleware, - createRetryOnEmptyMiddleware, - createBlockCacheMiddleware, - createInflightCacheMiddleware, - createBlockTrackerInspectorMiddleware, - providerFromMiddleware, -} from '@metamask/eth-json-rpc-middleware'; - -import { createInfuraMiddleware } from '@metamask/eth-json-rpc-infura'; -import { PollingBlockTracker } from 'eth-block-tracker'; - -import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network'; - -export default function createInfuraClient({ network, projectId }) { - const infuraMiddleware = createInfuraMiddleware({ - network, - projectId, - maxAttempts: 5, - source: 'metamask', - }); - const infuraProvider = providerFromMiddleware(infuraMiddleware); - const blockTracker = new PollingBlockTracker({ provider: infuraProvider }); - - const networkMiddleware = mergeMiddleware([ - createNetworkAndChainIdMiddleware({ network }), - createBlockCacheMiddleware({ blockTracker }), - createInflightCacheMiddleware(), - createBlockRefMiddleware({ blockTracker, provider: infuraProvider }), - createRetryOnEmptyMiddleware({ blockTracker, provider: infuraProvider }), - createBlockTrackerInspectorMiddleware({ blockTracker }), - infuraMiddleware, - ]); - return { networkMiddleware, blockTracker }; -} - -function createNetworkAndChainIdMiddleware({ network }) { - if (!BUILT_IN_NETWORKS[network]) { - throw new Error(`createInfuraClient - unknown network "${network}"`); - } - - const { chainId, networkId } = BUILT_IN_NETWORKS[network]; - - return createScaffoldMiddleware({ - eth_chainId: chainId, - net_version: networkId, - }); -} diff --git a/app/scripts/controllers/network/createInfuraClient.test.js b/app/scripts/controllers/network/createInfuraClient.test.js deleted file mode 100644 index d1b1a7ccf..000000000 --- a/app/scripts/controllers/network/createInfuraClient.test.js +++ /dev/null @@ -1,5 +0,0 @@ -import { testsForProviderType } from './provider-api-tests/shared-tests'; - -describe('createInfuraClient', () => { - testsForProviderType('infura'); -}); diff --git a/app/scripts/controllers/network/createJsonRpcClient.js b/app/scripts/controllers/network/createJsonRpcClient.js deleted file mode 100644 index b8cf0e7aa..000000000 --- a/app/scripts/controllers/network/createJsonRpcClient.js +++ /dev/null @@ -1,61 +0,0 @@ -import { createAsyncMiddleware, mergeMiddleware } from 'json-rpc-engine'; -import { - createFetchMiddleware, - createBlockRefRewriteMiddleware, - createBlockCacheMiddleware, - createInflightCacheMiddleware, - createBlockTrackerInspectorMiddleware, - providerFromMiddleware, -} from '@metamask/eth-json-rpc-middleware'; -import { PollingBlockTracker } from 'eth-block-tracker'; -import { SECOND } from '../../../../shared/constants/time'; - -export default function createJsonRpcClient({ rpcUrl, chainId }) { - const blockTrackerOpts = process.env.IN_TEST - ? { pollingInterval: SECOND } - : {}; - const fetchMiddleware = createFetchMiddleware({ rpcUrl }); - const blockProvider = providerFromMiddleware(fetchMiddleware); - const blockTracker = new PollingBlockTracker({ - ...blockTrackerOpts, - provider: blockProvider, - }); - const testMiddlewares = process.env.IN_TEST - ? [createEstimateGasDelayTestMiddleware()] - : []; - - const networkMiddleware = mergeMiddleware([ - ...testMiddlewares, - createChainIdMiddleware(chainId), - createBlockRefRewriteMiddleware({ blockTracker }), - createBlockCacheMiddleware({ blockTracker }), - createInflightCacheMiddleware(), - createBlockTrackerInspectorMiddleware({ blockTracker }), - fetchMiddleware, - ]); - - return { networkMiddleware, blockTracker }; -} - -function createChainIdMiddleware(chainId) { - return (req, res, next, end) => { - if (req.method === 'eth_chainId') { - res.result = chainId; - return end(); - } - return next(); - }; -} - -/** - * For use in tests only. - * Adds a delay to `eth_estimateGas` calls. - */ -function createEstimateGasDelayTestMiddleware() { - return createAsyncMiddleware(async (req, _, next) => { - if (req.method === 'eth_estimateGas') { - await new Promise((resolve) => setTimeout(resolve, SECOND * 2)); - } - return next(); - }); -} diff --git a/app/scripts/controllers/network/createJsonRpcClient.test.js b/app/scripts/controllers/network/createJsonRpcClient.test.js deleted file mode 100644 index 1c3443d25..000000000 --- a/app/scripts/controllers/network/createJsonRpcClient.test.js +++ /dev/null @@ -1,5 +0,0 @@ -import { testsForProviderType } from './provider-api-tests/shared-tests'; - -describe('createJsonRpcClient', () => { - testsForProviderType('custom'); -}); diff --git a/app/scripts/controllers/network/network-controller.js b/app/scripts/controllers/network/network-controller.js index 20869f227..06d236e26 100644 --- a/app/scripts/controllers/network/network-controller.js +++ b/app/scripts/controllers/network/network-controller.js @@ -1,8 +1,6 @@ import { strict as assert } from 'assert'; import EventEmitter from 'events'; import { ComposedStore, ObservableStore } from '@metamask/obs-store'; -import { JsonRpcEngine } from 'json-rpc-engine'; -import { providerFromEngine } from '@metamask/eth-json-rpc-middleware'; import log from 'loglevel'; import { createSwappableProxy, @@ -24,8 +22,7 @@ import { isSafeChainId, } from '../../../../shared/modules/network.utils'; import { EVENT } from '../../../../shared/constants/metametrics'; -import createInfuraClient from './createInfuraClient'; -import createJsonRpcClient from './createJsonRpcClient'; +import { createNetworkClient } from './create-network-client'; /** * @typedef {object} NetworkConfiguration @@ -428,7 +425,10 @@ export default class NetworkController extends EventEmitter { // infura type-based endpoints const isInfura = INFURA_PROVIDER_TYPES.includes(type); if (isInfura) { - this._configureInfuraProvider(type, this._infuraProjectId); + this._configureInfuraProvider({ + type, + infuraProjectId: this._infuraProjectId, + }); // url-based rpc endpoints } else if (type === NETWORK_TYPES.RPC) { this._configureStandardProvider(rpcUrl, chainId); @@ -439,25 +439,23 @@ export default class NetworkController extends EventEmitter { } } - _configureInfuraProvider(type, projectId) { + _configureInfuraProvider({ type, infuraProjectId }) { log.info('NetworkController - configureInfuraProvider', type); - const networkClient = createInfuraClient({ + const { provider, blockTracker } = createNetworkClient({ network: type, - projectId, + infuraProjectId, + type: 'infura', }); - this._setNetworkClient(networkClient); + this._setProviderAndBlockTracker({ provider, blockTracker }); } _configureStandardProvider(rpcUrl, chainId) { log.info('NetworkController - configureStandardProvider', rpcUrl); - const networkClient = createJsonRpcClient({ rpcUrl, chainId }); - this._setNetworkClient(networkClient); - } - - _setNetworkClient({ networkMiddleware, blockTracker }) { - const engine = new JsonRpcEngine(); - engine.push(networkMiddleware); - const provider = providerFromEngine(engine); + const { provider, blockTracker } = createNetworkClient({ + chainId, + rpcUrl, + type: 'custom', + }); this._setProviderAndBlockTracker({ provider, blockTracker }); } diff --git a/app/scripts/controllers/network/network-controller.test.js b/app/scripts/controllers/network/network-controller.test.js index a3743ae56..cd4e9a782 100644 --- a/app/scripts/controllers/network/network-controller.test.js +++ b/app/scripts/controllers/network/network-controller.test.js @@ -3,15 +3,15 @@ import { isMatch } from 'lodash'; import { v4 } from 'uuid'; import nock from 'nock'; import sinon from 'sinon'; -import * as ethJsonRpcMiddlewareModule from '@metamask/eth-json-rpc-middleware'; +import * as ethJsonRpcProvider from '@metamask/eth-json-rpc-provider'; import { BUILT_IN_NETWORKS } from '../../../../shared/constants/network'; import { EVENT } from '../../../../shared/constants/metametrics'; import NetworkController from './network-controller'; -jest.mock('@metamask/eth-json-rpc-middleware', () => { +jest.mock('@metamask/eth-json-rpc-provider', () => { return { __esModule: true, - ...jest.requireActual('@metamask/eth-json-rpc-middleware'), + ...jest.requireActual('@metamask/eth-json-rpc-provider'), }; }); @@ -1760,7 +1760,7 @@ describe('NetworkController', () => { }, ]; jest - .spyOn(ethJsonRpcMiddlewareModule, 'providerFromEngine') + .spyOn(ethJsonRpcProvider, 'providerFromEngine') .mockImplementationOnce(() => fakeProviders[0]) .mockImplementationOnce(() => fakeProviders[1]); await withoutCallingLookupNetwork({ @@ -1876,7 +1876,7 @@ describe('NetworkController', () => { }, ]; jest - .spyOn(ethJsonRpcMiddlewareModule, 'providerFromEngine') + .spyOn(ethJsonRpcProvider, 'providerFromEngine') .mockImplementationOnce(() => fakeProviders[0]) .mockImplementationOnce(() => fakeProviders[1]); await withoutCallingLookupNetwork({ diff --git a/app/scripts/controllers/network/provider-api-tests/helpers.js b/app/scripts/controllers/network/provider-api-tests/helpers.js index a5d92b91e..afa91a7bb 100644 --- a/app/scripts/controllers/network/provider-api-tests/helpers.js +++ b/app/scripts/controllers/network/provider-api-tests/helpers.js @@ -1,10 +1,7 @@ import nock from 'nock'; import sinon from 'sinon'; -import { JsonRpcEngine } from 'json-rpc-engine'; -import { providerFromEngine } from '@metamask/eth-json-rpc-middleware'; import EthQuery from 'eth-query'; -import createInfuraClient from '../createInfuraClient'; -import createJsonRpcClient from '../createJsonRpcClient'; +import { createNetworkClient } from '../create-network-client'; /** * @typedef {import('nock').Scope} NockScope @@ -414,20 +411,21 @@ export async function withNetworkClient( delete process.env.IN_TEST; const clientUnderTest = providerType === 'infura' - ? createInfuraClient({ + ? createNetworkClient({ network: infuraNetwork, - projectId: MOCK_INFURA_PROJECT_ID, + infuraProjectId: MOCK_INFURA_PROJECT_ID, + type: 'infura', }) - : createJsonRpcClient({ rpcUrl: customRpcUrl, chainId: customChainId }); + : createNetworkClient({ + chainId: customChainId, + rpcUrl: customRpcUrl, + type: 'custom', + }); process.env.IN_TEST = inTest; - const { networkMiddleware, blockTracker } = clientUnderTest; + const { provider, blockTracker } = clientUnderTest; - const engine = new JsonRpcEngine(); - engine.push(networkMiddleware); - const provider = providerFromEngine(engine); const ethQuery = new EthQuery(provider); - const curriedMakeRpcCall = (request) => makeRpcCall(ethQuery, request); const makeRpcCallsInSeries = async (requests) => { const responses = []; diff --git a/app/scripts/controllers/network/provider-api-tests/shared-tests.js b/app/scripts/controllers/network/provider-api-tests/shared-tests.js index d61595670..04412d3f0 100644 --- a/app/scripts/controllers/network/provider-api-tests/shared-tests.js +++ b/app/scripts/controllers/network/provider-api-tests/shared-tests.js @@ -291,9 +291,9 @@ export function testsForProviderType(providerType) { // tests on the core side. { name: 'net_listening', numberOfParameters: 0 }, - - { name: 'eth_subscribe', numberOfParameters: 1 }, - { name: 'eth_unsubscribe', numberOfParameters: 1 }, + // TODO: Methods to add back when we add testing for subscribe middleware + // { name: 'eth_subscribe', numberOfParameters: 1 }, + // { name: 'eth_unsubscribe', numberOfParameters: 1 }, { name: 'custom_rpc_method', numberOfParameters: 1 }, { name: 'net_peerCount', numberOfParameters: 0 }, { name: 'parity_nextNonce', numberOfParameters: 1 }, diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json index 17687c27b..7d933f82d 100644 --- a/lavamoat/browserify/beta/policy.json +++ b/lavamoat/browserify/beta/policy.json @@ -871,8 +871,9 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": true, + "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, + "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -881,57 +882,19 @@ "vinyl>clone": true } }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true, - "ethereumjs-abi": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": true, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true, - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>rlp": true, - "ethereumjs-wallet>safe-buffer": true, - "ganache>secp256k1>elliptic": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": { - "packages": { - "browserify>buffer": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethereumjs-util>ethereum-cryptography>secp256k1": true, - "ethereumjs-wallet>randombytes": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": { - "packages": { - "browserify>buffer": true, - "ethjs>ethjs-util>is-hex-prefixed": true, - "ethjs>ethjs-util>strip-hex-prefix": true - } - }, "@metamask/eth-json-rpc-middleware": { "globals": { "URL": true, - "btoa": true, "console.error": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/eth-json-rpc-middleware>@metamask/utils": true, "@metamask/eth-json-rpc-middleware>pify": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, - "lavamoat>json-stable-stringify": true, "vinyl>clone": true } }, @@ -947,6 +910,12 @@ "semver": true } }, + "@metamask/eth-json-rpc-provider": { + "packages": { + "json-rpc-engine": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, "@metamask/eth-keyring-controller": { "packages": { "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, @@ -2610,6 +2579,11 @@ "document.createElement": true } }, + "btoa": { + "packages": { + "browserify>buffer": true + } + }, "classnames": { "globals": { "classNames": "write", diff --git a/lavamoat/browserify/desktop/policy.json b/lavamoat/browserify/desktop/policy.json index ceadebd90..46ce15ef8 100644 --- a/lavamoat/browserify/desktop/policy.json +++ b/lavamoat/browserify/desktop/policy.json @@ -925,8 +925,9 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": true, + "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, + "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -935,57 +936,19 @@ "vinyl>clone": true } }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true, - "ethereumjs-abi": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": true, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true, - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>rlp": true, - "ethereumjs-wallet>safe-buffer": true, - "ganache>secp256k1>elliptic": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": { - "packages": { - "browserify>buffer": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethereumjs-util>ethereum-cryptography>secp256k1": true, - "ethereumjs-wallet>randombytes": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": { - "packages": { - "browserify>buffer": true, - "ethjs>ethjs-util>is-hex-prefixed": true, - "ethjs>ethjs-util>strip-hex-prefix": true - } - }, "@metamask/eth-json-rpc-middleware": { "globals": { "URL": true, - "btoa": true, "console.error": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/eth-json-rpc-middleware>@metamask/utils": true, "@metamask/eth-json-rpc-middleware>pify": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, - "lavamoat>json-stable-stringify": true, "vinyl>clone": true } }, @@ -1001,6 +964,12 @@ "semver": true } }, + "@metamask/eth-json-rpc-provider": { + "packages": { + "json-rpc-engine": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, "@metamask/eth-keyring-controller": { "packages": { "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, @@ -3051,6 +3020,11 @@ "document.createElement": true } }, + "btoa": { + "packages": { + "browserify>buffer": true + } + }, "classnames": { "globals": { "classNames": "write", diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json index ceadebd90..46ce15ef8 100644 --- a/lavamoat/browserify/flask/policy.json +++ b/lavamoat/browserify/flask/policy.json @@ -925,8 +925,9 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": true, + "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, + "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -935,57 +936,19 @@ "vinyl>clone": true } }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true, - "ethereumjs-abi": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": true, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true, - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>rlp": true, - "ethereumjs-wallet>safe-buffer": true, - "ganache>secp256k1>elliptic": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": { - "packages": { - "browserify>buffer": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethereumjs-util>ethereum-cryptography>secp256k1": true, - "ethereumjs-wallet>randombytes": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": { - "packages": { - "browserify>buffer": true, - "ethjs>ethjs-util>is-hex-prefixed": true, - "ethjs>ethjs-util>strip-hex-prefix": true - } - }, "@metamask/eth-json-rpc-middleware": { "globals": { "URL": true, - "btoa": true, "console.error": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/eth-json-rpc-middleware>@metamask/utils": true, "@metamask/eth-json-rpc-middleware>pify": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, - "lavamoat>json-stable-stringify": true, "vinyl>clone": true } }, @@ -1001,6 +964,12 @@ "semver": true } }, + "@metamask/eth-json-rpc-provider": { + "packages": { + "json-rpc-engine": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, "@metamask/eth-keyring-controller": { "packages": { "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, @@ -3051,6 +3020,11 @@ "document.createElement": true } }, + "btoa": { + "packages": { + "browserify>buffer": true + } + }, "classnames": { "globals": { "classNames": "write", diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json index 17687c27b..7d933f82d 100644 --- a/lavamoat/browserify/main/policy.json +++ b/lavamoat/browserify/main/policy.json @@ -871,8 +871,9 @@ "setTimeout": true }, "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": true, + "@metamask/eth-json-rpc-infura>@metamask/utils": true, "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true, + "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, @@ -881,57 +882,19 @@ "vinyl>clone": true } }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": true, - "ethereumjs-abi": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util": { - "packages": { - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": true, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": true, - "bn.js": true, - "browserify>assert": true, - "browserify>buffer": true, - "ethereumjs-util>create-hash": true, - "ethereumjs-util>rlp": true, - "ethereumjs-wallet>safe-buffer": true, - "ganache>secp256k1>elliptic": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethereum-cryptography": { - "packages": { - "browserify>buffer": true, - "ethereumjs-util>ethereum-cryptography>keccak": true, - "ethereumjs-util>ethereum-cryptography>secp256k1": true, - "ethereumjs-wallet>randombytes": true - } - }, - "@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>eth-sig-util>ethereumjs-util>ethjs-util": { - "packages": { - "browserify>buffer": true, - "ethjs>ethjs-util>is-hex-prefixed": true, - "ethjs>ethjs-util>strip-hex-prefix": true - } - }, "@metamask/eth-json-rpc-middleware": { "globals": { "URL": true, - "btoa": true, "console.error": true, - "fetch": true, "setTimeout": true }, "packages": { "@metamask/eth-json-rpc-middleware>@metamask/utils": true, "@metamask/eth-json-rpc-middleware>pify": true, + "@metamask/eth-json-rpc-middleware>safe-stable-stringify": true, "@metamask/eth-keyring-controller>@metamask/eth-sig-util": true, - "browserify>browser-resolve": true, "eth-rpc-errors": true, "json-rpc-engine": true, - "json-rpc-engine>@metamask/safe-event-emitter": true, - "lavamoat>json-stable-stringify": true, "vinyl>clone": true } }, @@ -947,6 +910,12 @@ "semver": true } }, + "@metamask/eth-json-rpc-provider": { + "packages": { + "json-rpc-engine": true, + "json-rpc-engine>@metamask/safe-event-emitter": true + } + }, "@metamask/eth-keyring-controller": { "packages": { "@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true, @@ -2610,6 +2579,11 @@ "document.createElement": true } }, + "btoa": { + "packages": { + "browserify>buffer": true + } + }, "classnames": { "globals": { "classNames": "write", diff --git a/package.json b/package.json index 6441e7a86..e76f1c517 100644 --- a/package.json +++ b/package.json @@ -232,8 +232,9 @@ "@metamask/controller-utils": "^1.0.0", "@metamask/design-tokens": "^1.9.0", "@metamask/desktop": "^0.3.0", - "@metamask/eth-json-rpc-infura": "^7.0.0", - "@metamask/eth-json-rpc-middleware": "^10.0.0", + "@metamask/eth-json-rpc-infura": "^8.0.0", + "@metamask/eth-json-rpc-middleware": "^11.0.0", + "@metamask/eth-json-rpc-provider": "^1.0.0", "@metamask/eth-keyring-controller": "^10.0.1", "@metamask/eth-ledger-bridge-keyring": "^0.13.0", "@metamask/eth-token-tracker": "^4.0.0", @@ -285,7 +286,7 @@ "debounce-stream": "^2.0.0", "deep-freeze-strict": "1.1.1", "end-of-stream": "^1.4.4", - "eth-block-tracker": "^6.0.0", + "eth-block-tracker": "^7.0.0", "eth-ens-namehash": "^2.0.8", "eth-json-rpc-filters": "^6.0.0", "eth-lattice-keyring": "^0.12.3", diff --git a/shared/constants/network.ts b/shared/constants/network.ts index 16bafb208..077412623 100644 --- a/shared/constants/network.ts +++ b/shared/constants/network.ts @@ -1,4 +1,4 @@ -import { capitalize } from 'lodash'; +import { capitalize, pick } from 'lodash'; /** * A type representing any valid value for 'type' for setProviderType and other * methods that add or manipulate networks in MetaMask state. @@ -301,6 +301,13 @@ export const BUILT_IN_NETWORKS = { }, } as const; +export const BUILT_IN_INFURA_NETWORKS = pick( + BUILT_IN_NETWORKS, + INFURA_PROVIDER_TYPES, +); + +export type BuiltInInfuraNetwork = keyof typeof BUILT_IN_INFURA_NETWORKS; + export const NETWORK_TO_NAME_MAP = { [NETWORK_TYPES.MAINNET]: MAINNET_DISPLAY_NAME, [NETWORK_TYPES.GOERLI]: GOERLI_DISPLAY_NAME, diff --git a/types/eth-json-rpc-filters/index.d.ts b/types/eth-json-rpc-filters/index.d.ts new file mode 100644 index 000000000..f7515bccd --- /dev/null +++ b/types/eth-json-rpc-filters/index.d.ts @@ -0,0 +1 @@ +declare module 'eth-json-rpc-filters'; diff --git a/types/eth-json-rpc-filters/subscriptionManager.d.ts b/types/eth-json-rpc-filters/subscriptionManager.d.ts new file mode 100644 index 000000000..a79ff8ee4 --- /dev/null +++ b/types/eth-json-rpc-filters/subscriptionManager.d.ts @@ -0,0 +1 @@ +declare module 'eth-json-rpc-filters/subscriptionManager'; diff --git a/yarn.lock b/yarn.lock index 6e98cfa41..6ea77ae8f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3849,35 +3849,43 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-json-rpc-infura@npm:^7.0.0": - version: 7.0.0 - resolution: "@metamask/eth-json-rpc-infura@npm:7.0.0" +"@metamask/eth-json-rpc-infura@npm:^8.0.0": + version: 8.0.0 + resolution: "@metamask/eth-json-rpc-infura@npm:8.0.0" dependencies: "@metamask/utils": ^3.0.1 - eth-json-rpc-middleware: ^8.1.0 + eth-json-rpc-middleware: ^9.0.0 eth-rpc-errors: ^4.0.3 json-rpc-engine: ^6.1.0 node-fetch: ^2.6.7 - checksum: 6230cb289b66db39d27f08ffc72cfb79274e632e4e14eb52ca72d19167d17bbf22c58718d80f801818058631dec0638bcc21ef4b229fa8d53e7f9328be870fc6 + checksum: e8c3a4b75d4f2bb09f68d7d2ac6b992f264df893921b50a05c35968ee684b7bba90180870eebecfc89b7fbf40d11de2a545ab68f1d511f569ce0a6519c64b0aa languageName: node linkType: hard -"@metamask/eth-json-rpc-middleware@npm:^10.0.0": - version: 10.0.0 - resolution: "@metamask/eth-json-rpc-middleware@npm:10.0.0" +"@metamask/eth-json-rpc-middleware@npm:^11.0.0": + version: 11.0.0 + resolution: "@metamask/eth-json-rpc-middleware@npm:11.0.0" dependencies: + "@metamask/eth-json-rpc-provider": ^1.0.0 "@metamask/eth-sig-util": ^5.0.0 - "@metamask/safe-event-emitter": ^2.0.0 "@metamask/utils": ^3.0.3 - btoa: ^1.2.1 clone: ^2.1.1 - eth-block-tracker: ^5.0.1 + eth-block-tracker: ^7.0.0 eth-rpc-errors: ^4.0.3 json-rpc-engine: ^6.1.0 - json-stable-stringify: ^1.0.1 - node-fetch: ^2.6.7 pify: ^3.0.0 - checksum: c754b3a39f175698070b4d07076e692d3080738bd25157c3b93114d286c975ee6895d5793b4188ca3d0abbcdef04bfde9e2d4835251a6b725b002d3750bf98de + safe-stable-stringify: ^2.3.2 + checksum: c866d07a199ab480ceeb7ab8df61c08284640b5ac13aee3dd81dae9e0e5575f4a425d95728070ab5402c0c6cd5f9237fb5f4f22dbcdc99fe0b50bb47df561830 + languageName: node + linkType: hard + +"@metamask/eth-json-rpc-provider@npm:^1.0.0": + version: 1.0.0 + resolution: "@metamask/eth-json-rpc-provider@npm:1.0.0" + dependencies: + "@metamask/safe-event-emitter": ^2.0.0 + json-rpc-engine: ^6.1.0 + checksum: 27865d84d90030db1a9e5a66bc0b0ae079706fb7be635ec1e9bd4f64771e819aae78f0a026c6629d3a1a2eb277fcd51977315c049c47a70df1dd95d1d4106982 languageName: node linkType: hard @@ -15563,15 +15571,16 @@ __metadata: languageName: node linkType: hard -"eth-block-tracker@npm:^6.0.0": - version: 6.0.0 - resolution: "eth-block-tracker@npm:6.0.0" +"eth-block-tracker@npm:^7.0.0": + version: 7.0.0 + resolution: "eth-block-tracker@npm:7.0.0" dependencies: + "@metamask/eth-json-rpc-provider": ^1.0.0 "@metamask/safe-event-emitter": ^2.0.0 "@metamask/utils": ^3.0.1 json-rpc-random-id: ^1.0.1 pify: ^3.0.0 - checksum: ad1199b822a9a3ff2673ecc92ca7cda0a37828e5bfd1927fd917a8085a99904fc29d3ef2392068bcfb14e47589df097940ef28f3e9025d1681e56a89b07e284e + checksum: b76f6ba022947eec0161e5592bc5386e8f05bff8a2c3e0e10c76bce21bc51900ef1cb153eb8bf31858fb0027e929c6a85a159bdf84aa1e3ef77b24e53e82ba84 languageName: node linkType: hard @@ -15640,21 +15649,22 @@ __metadata: languageName: node linkType: hard -"eth-json-rpc-middleware@npm:^8.1.0": - version: 8.1.0 - resolution: "eth-json-rpc-middleware@npm:8.1.0" +"eth-json-rpc-middleware@npm:^9.0.0": + version: 9.0.1 + resolution: "eth-json-rpc-middleware@npm:9.0.1" dependencies: + "@metamask/eth-sig-util": ^5.0.0 "@metamask/safe-event-emitter": ^2.0.0 + "@metamask/utils": ^3.0.3 btoa: ^1.2.1 clone: ^2.1.1 eth-block-tracker: ^5.0.1 eth-rpc-errors: ^4.0.3 - eth-sig-util: ^1.4.2 json-rpc-engine: ^6.1.0 json-stable-stringify: ^1.0.1 node-fetch: ^2.6.7 pify: ^3.0.0 - checksum: ec10bbc04e3b7696f82db2db528b052c8f6de811c90a12d4eb32f23cbe6ea198d86656afa5b53c52de06b631fef633cf29409bb56c04a16f173da94ee1d89ab6 + checksum: 9512829a6958df6ef739b891a0c0804b51a140407fd2e3ddaaa6b18d975796646cfcf7f7305a18beb7903db09e0c7a91b06dc5434b6bd2d6cdb85d992d9fd3ab languageName: node linkType: hard @@ -24268,8 +24278,9 @@ __metadata: "@metamask/eslint-config-mocha": ^9.0.0 "@metamask/eslint-config-nodejs": ^9.0.0 "@metamask/eslint-config-typescript": ^9.0.1 - "@metamask/eth-json-rpc-infura": ^7.0.0 - "@metamask/eth-json-rpc-middleware": ^10.0.0 + "@metamask/eth-json-rpc-infura": ^8.0.0 + "@metamask/eth-json-rpc-middleware": ^11.0.0 + "@metamask/eth-json-rpc-provider": ^1.0.0 "@metamask/eth-keyring-controller": ^10.0.1 "@metamask/eth-ledger-bridge-keyring": ^0.13.0 "@metamask/eth-token-tracker": ^4.0.0 @@ -24402,7 +24413,7 @@ __metadata: eslint-plugin-react: ^7.23.1 eslint-plugin-react-hooks: ^4.2.0 eslint-plugin-storybook: ^0.6.4 - eth-block-tracker: ^6.0.0 + eth-block-tracker: ^7.0.0 eth-ens-namehash: ^2.0.8 eth-json-rpc-filters: ^6.0.0 eth-lattice-keyring: ^0.12.3 @@ -30453,10 +30464,10 @@ __metadata: languageName: node linkType: hard -"safe-stable-stringify@npm:^2.1.0": - version: 2.3.1 - resolution: "safe-stable-stringify@npm:2.3.1" - checksum: a0a0bad0294c3e2a9d1bf3cf2b1096dfb83c162d09a5e4891e488cce082120bd69161d2a92aae7fc48255290f17700decae9c89a07fe139794e61b5c8b411377 +"safe-stable-stringify@npm:^2.1.0, safe-stable-stringify@npm:^2.3.2": + version: 2.4.2 + resolution: "safe-stable-stringify@npm:2.4.2" + checksum: 0324ba2e40f78cae63e31a02b1c9bdf1b786621f9e8760845608eb9e81aef401944ac2078e5c9c1533cf516aea34d08fa8052ca853637ced84b791caaf1e394e languageName: node linkType: hard