From ab59d452b9d8ab305dbb52a51169b546f990cf85 Mon Sep 17 00:00:00 2001 From: tommasini <46944231+tommasini@users.noreply.github.com> Date: Thu, 12 Jan 2023 01:26:51 +0000 Subject: [PATCH] Sepolia support (#1041) BREAKING: This update adds support for Sepolia (so that mobile can support it), and removes support for deprecated test networks Rinkeby, Kovan and Ropsten. The test cases were changed to use Sepolia and Goerli instead of the deprecated networks, and test coverage for NetworkController was increased. Finally the package `ethereumjs-common` was upgraded to version 2.6.1, which adds support for Sepolia (see changelog: ). Co-authored-by: Elliot Winkler --- .../src/AccountTrackerController.test.ts | 2 +- .../src/CurrencyRateController.test.ts | 2 +- .../src/CurrencyRateController.ts | 2 +- .../src/NftController.test.ts | 12 +-- .../assets-controllers/src/NftController.ts | 13 ---- .../src/NftDetectionController.test.ts | 6 +- .../src/TokenDetectionController.test.ts | 2 +- .../src/TokenListController.test.ts | 12 +-- .../src/TokensController.test.ts | 36 ++++----- .../assets-controllers/src/assetsUtil.test.ts | 8 +- packages/controller-utils/src/constants.ts | 9 +-- packages/controller-utils/src/types.ts | 8 +- packages/controller-utils/src/util.test.ts | 6 +- packages/controller-utils/src/util.ts | 8 +- packages/keyring-controller/package.json | 4 +- .../src/KeyringController.test.ts | 16 ++-- .../src/NetworkController.test.ts | 76 ++++++++++++++++--- .../src/NetworkController.ts | 8 +- packages/transaction-controller/package.json | 4 +- .../src/TransactionController.test.ts | 44 +++++------ .../src/TransactionController.ts | 2 +- .../transaction-controller/src/utils.test.ts | 6 +- yarn.lock | 40 ++++------ 23 files changed, 169 insertions(+), 157 deletions(-) diff --git a/packages/assets-controllers/src/AccountTrackerController.test.ts b/packages/assets-controllers/src/AccountTrackerController.test.ts index c2c99a9306d..c87f10e9d52 100644 --- a/packages/assets-controllers/src/AccountTrackerController.test.ts +++ b/packages/assets-controllers/src/AccountTrackerController.test.ts @@ -20,7 +20,7 @@ const mockedQuery = query as jest.Mock< >; const provider = new HttpProvider( - 'https://ropsten.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', + 'https://goerli.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); describe('AccountTrackerController', () => { diff --git a/packages/assets-controllers/src/CurrencyRateController.test.ts b/packages/assets-controllers/src/CurrencyRateController.test.ts index a201120272e..431ba9548d5 100644 --- a/packages/assets-controllers/src/CurrencyRateController.test.ts +++ b/packages/assets-controllers/src/CurrencyRateController.test.ts @@ -233,7 +233,7 @@ describe('CurrencyRateController', () => { expect(controller.state.conversionRate).toStrictEqual(1); - await controller.setNativeCurrency(TESTNET_TICKER_SYMBOLS.RINKEBY); + await controller.setNativeCurrency(TESTNET_TICKER_SYMBOLS.GOERLI); expect(controller.state.conversionRate).toStrictEqual(10); diff --git a/packages/assets-controllers/src/CurrencyRateController.ts b/packages/assets-controllers/src/CurrencyRateController.ts index 0256224e0d2..ad6ddf08631 100644 --- a/packages/assets-controllers/src/CurrencyRateController.ts +++ b/packages/assets-controllers/src/CurrencyRateController.ts @@ -228,7 +228,7 @@ export class CurrencyRateController extends BaseControllerV2< const currentCurrency = pendingCurrentCurrency ?? stateCurrentCurrency; const nativeCurrency = pendingNativeCurrency ?? stateNativeCurrency; - // For preloaded testnets (Rinkeby, Ropsten, Goerli, Kovan) we want to fetch exchange rate for real ETH. + // For preloaded testnets (Goerli, Sepolia) we want to fetch exchange rate for real ETH. const nativeCurrencyForExchangeRate = Object.values( TESTNET_TICKER_SYMBOLS, ).includes(nativeCurrency) diff --git a/packages/assets-controllers/src/NftController.test.ts b/packages/assets-controllers/src/NftController.test.ts index 41c92929777..6ff38ced034 100644 --- a/packages/assets-controllers/src/NftController.test.ts +++ b/packages/assets-controllers/src/NftController.test.ts @@ -806,8 +806,8 @@ describe('NftController', () => { it('should add NFT by provider type', async () => { const { nftController, network, messenger } = setupController(); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; const { selectedAddress } = nftController.config; sinon .stub(nftController, 'getNftInformation' as any) @@ -1365,8 +1365,8 @@ describe('NftController', () => { sinon .stub(nftController, 'getNftInformation' as any) .returns({ name: 'name', image: 'url', description: 'description' }); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; network.setProviderType(firstNetworkType); await nftController.addNft('0x02', '4321'); network.setProviderType(secondNetworkType); @@ -1961,8 +1961,8 @@ describe('NftController', () => { it('should check whether the passed NFT is still owned by the the selectedAddress/chainId combination passed in the accountParams argument and update its isCurrentlyOwned property in state, when the currently configured selectedAddress/chainId are different from those passed', async () => { const { nftController, network, preferences, messenger } = setupController(); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; preferences.update({ selectedAddress: OWNER_ADDRESS }); network.setProviderType(firstNetworkType); diff --git a/packages/assets-controllers/src/NftController.ts b/packages/assets-controllers/src/NftController.ts index e915e495b88..285cb5ed6d5 100644 --- a/packages/assets-controllers/src/NftController.ts +++ b/packages/assets-controllers/src/NftController.ts @@ -15,13 +15,11 @@ import { BNToHex, fetchWithErrorHandling, MAINNET, - RINKEBY_CHAIN_ID, IPFS_DEFAULT_GATEWAY_URL, ERC721, ERC1155, OPENSEA_API_URL, OPENSEA_PROXY_URL, - OPENSEA_TEST_API_URL, NetworkType, } from '@metamask/controller-utils'; import type { @@ -180,11 +178,6 @@ export class NftController extends BaseController { tokenId: string; useProxy: boolean; }) { - const { chainId } = this.config; - - if (chainId === RINKEBY_CHAIN_ID) { - return `${OPENSEA_TEST_API_URL}/asset/${contractAddress}/${tokenId}`; - } return useProxy ? `${OPENSEA_PROXY_URL}/asset/${contractAddress}/${tokenId}` : `${OPENSEA_API_URL}/asset/${contractAddress}/${tokenId}`; @@ -197,12 +190,6 @@ export class NftController extends BaseController { contractAddress: string; useProxy: boolean; }) { - const { chainId } = this.config; - - if (chainId === RINKEBY_CHAIN_ID) { - return `${OPENSEA_TEST_API_URL}/asset_contract/${contractAddress}`; - } - return useProxy ? `${OPENSEA_PROXY_URL}/asset_contract/${contractAddress}` : `${OPENSEA_API_URL}/asset_contract/${contractAddress}`; diff --git a/packages/assets-controllers/src/NftDetectionController.test.ts b/packages/assets-controllers/src/NftDetectionController.test.ts index eace03070e5..e058d29c71f 100644 --- a/packages/assets-controllers/src/NftDetectionController.test.ts +++ b/packages/assets-controllers/src/NftDetectionController.test.ts @@ -13,7 +13,7 @@ import { NftDetectionController } from './NftDetectionController'; const DEFAULT_INTERVAL = 180000; const MAINNET = 'mainnet'; -const ROPSTEN = 'ropsten'; +const GOERLI = 'goerli'; describe('NftDetectionController', () => { let nftDetection: NftDetectionController; @@ -258,7 +258,7 @@ describe('NftDetectionController', () => { it('should detect mainnet correctly', () => { nftDetection.configure({ networkType: MAINNET }); expect(nftDetection.isMainnet()).toStrictEqual(true); - nftDetection.configure({ networkType: ROPSTEN }); + nftDetection.configure({ networkType: GOERLI }); expect(nftDetection.isMainnet()).toStrictEqual(false); }); @@ -279,7 +279,7 @@ describe('NftDetectionController', () => { addNft: nftController.addNft.bind(nftController), getNftState: () => nftController.state, }, - { interval: 10, networkType: ROPSTEN }, + { interval: 10, networkType: GOERLI }, ); expect(mockNfts.called).toBe(false); resolve(''); diff --git a/packages/assets-controllers/src/TokenDetectionController.test.ts b/packages/assets-controllers/src/TokenDetectionController.test.ts index 17b3a42aaee..1d6bfc46451 100644 --- a/packages/assets-controllers/src/TokenDetectionController.test.ts +++ b/packages/assets-controllers/src/TokenDetectionController.test.ts @@ -249,7 +249,7 @@ describe('TokenDetectionController', () => { expect( isTokenDetectionSupportedForNetwork(tokenDetection.config.chainId), ).toStrictEqual(true); - tokenDetection.configure({ chainId: NetworksChainId.ropsten }); + tokenDetection.configure({ chainId: NetworksChainId.goerli }); expect( isTokenDetectionSupportedForNetwork(tokenDetection.config.chainId), ).toStrictEqual(false); diff --git a/packages/assets-controllers/src/TokenListController.test.ts b/packages/assets-controllers/src/TokenListController.test.ts index b88207edd89..d56005acdf7 100644 --- a/packages/assets-controllers/src/TokenListController.test.ts +++ b/packages/assets-controllers/src/TokenListController.test.ts @@ -1069,8 +1069,8 @@ describe('TokenListController', () => { nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) .reply(200, sampleMainnetTokenList) - .get(`/tokens/${NetworksChainId.ropsten}`) - .reply(200, { error: 'ChainId 3 is not supported' }) + .get(`/tokens/${NetworksChainId.goerli}`) + .reply(200, { error: 'ChainId 5 is not supported' }) .get(`/tokens/56`) .reply(200, sampleBinanceTokenList) .persist(); @@ -1097,7 +1097,7 @@ describe('TokenListController', () => { sampleTwoChainState.tokensChainsCache[NetworksChainId.mainnet].data, ); - network.setProviderType('ropsten'); + network.setProviderType('goerli'); await new Promise((resolve) => setTimeout(() => resolve(), 500)); @@ -1157,8 +1157,8 @@ describe('TokenListController', () => { nock(TOKEN_END_POINT_API) .get(`/tokens/${NetworksChainId.mainnet}`) .reply(200, sampleMainnetTokenList) - .get(`/tokens/${NetworksChainId.ropsten}`) - .reply(200, { error: 'ChainId 3 is not supported' }) + .get(`/tokens/${NetworksChainId.goerli}`) + .reply(200, { error: 'ChainId 5 is not supported' }) .get(`/tokens/56`) .reply(200, sampleBinanceTokenList) .persist(); @@ -1167,7 +1167,7 @@ describe('TokenListController', () => { const { network } = setupNetworkController(controllerMessenger); const messenger = getRestrictedMessenger(controllerMessenger); const controller = new TokenListController({ - chainId: NetworksChainId.ropsten, + chainId: NetworksChainId.goerli, preventPollingOnNetworkRestart: true, messenger, interval: 100, diff --git a/packages/assets-controllers/src/TokensController.test.ts b/packages/assets-controllers/src/TokensController.test.ts index fcb8f87de89..a6a9e30d0ed 100644 --- a/packages/assets-controllers/src/TokensController.test.ts +++ b/packages/assets-controllers/src/TokensController.test.ts @@ -262,8 +262,8 @@ describe('TokensController', () => { it('should add token by network', async () => { const stub = stubCreateEthers(tokensController, false); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; network.setProviderType(firstNetworkType); await tokensController.addToken('0x01', 'bar', 2); network.setProviderType(secondNetworkType); @@ -275,7 +275,7 @@ describe('TokensController', () => { address: '0x01', decimals: 2, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/4/0x01.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/11155111/0x01.png', symbol: 'bar', isERC721: false, aggregators: [], @@ -317,8 +317,8 @@ describe('TokensController', () => { it('should remove token by provider type', async () => { const stub = stubCreateEthers(tokensController, false); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; network.setProviderType(firstNetworkType); await tokensController.addToken('0x02', 'baz', 2); @@ -332,7 +332,7 @@ describe('TokensController', () => { address: '0x02', decimals: 2, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/4/0x02.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/11155111/0x02.png', symbol: 'baz', isERC721: false, aggregators: [], @@ -341,7 +341,7 @@ describe('TokensController', () => { }); it('should subscribe to new sibling preference controllers', async () => { - const networkType = 'rinkeby'; + const networkType = 'sepolia'; const address = '0x123'; preferences.update({ selectedAddress: address }); expect(preferences.state.selectedAddress).toStrictEqual(address); @@ -350,7 +350,7 @@ describe('TokensController', () => { }); describe('ignoredTokens', () => { - const defaultSelectedNetwork: NetworkType = 'rinkeby'; + const defaultSelectedNetwork: NetworkType = 'sepolia'; const defaultSelectedAddress = '0x0001'; let createEthersStub: sinon.SinonStub; @@ -380,7 +380,7 @@ describe('TokensController', () => { it('should remove a token from the ignoredTokens/allIgnoredTokens lists if re-added as part of a bulk addTokens add', async () => { const selectedAddress = '0x0001'; - const chain = 'rinkeby'; + const chain = 'sepolia'; preferences.setSelectedAddress(selectedAddress); network.setProviderType(chain); await tokensController.addToken('0x01', 'bar', 2); @@ -425,8 +425,8 @@ describe('TokensController', () => { it('should ignore tokens by [chainID][accountAddress]', async () => { const selectedAddress1 = '0x0001'; const selectedAddress2 = '0x0002'; - const chain1 = 'rinkeby'; - const chain2 = 'ropsten'; + const chain1 = 'sepolia'; + const chain2 = 'goerli'; preferences.setSelectedAddress(selectedAddress1); network.setProviderType(chain1); @@ -714,7 +714,7 @@ describe('TokensController', () => { const DETECTED_CHAINID = '0xDetectedChainId'; const CONFIGURED_ADDRESS = '0xabc'; - const CONFIGURED_NETWORK = 'rinkeby'; + const CONFIGURED_NETWORK = 'sepolia'; preferences.update({ selectedAddress: CONFIGURED_ADDRESS }); network.setProviderType(CONFIGURED_NETWORK); @@ -1127,8 +1127,8 @@ describe('TokensController', () => { it('should remove a token from its state on corresponding network', async function () { const stub = stubCreateEthers(tokensController, false); - const firstNetworkType = 'rinkeby'; - const secondNetworkType = 'ropsten'; + const firstNetworkType = 'sepolia'; + const secondNetworkType = 'goerli'; network.setProviderType(firstNetworkType); await tokensController.addToken('0x01', 'A', 4); @@ -1149,7 +1149,7 @@ describe('TokensController', () => { address: '0x01', decimals: 4, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/4/0x01.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/11155111/0x01.png', isERC721: false, symbol: 'A', aggregators: [], @@ -1158,7 +1158,7 @@ describe('TokensController', () => { address: '0x02', decimals: 5, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/4/0x02.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/11155111/0x02.png', isERC721: false, symbol: 'B', aggregators: [], @@ -1170,7 +1170,7 @@ describe('TokensController', () => { address: '0x03', decimals: 4, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/3/0x03.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/5/0x03.png', isERC721: false, symbol: 'C', aggregators: [], @@ -1179,7 +1179,7 @@ describe('TokensController', () => { address: '0x04', decimals: 5, image: - 'https://static.metaswap.codefi.network/api/v1/tokenIcons/3/0x04.png', + 'https://static.metaswap.codefi.network/api/v1/tokenIcons/5/0x04.png', isERC721: false, symbol: 'D', aggregators: [], diff --git a/packages/assets-controllers/src/assetsUtil.test.ts b/packages/assets-controllers/src/assetsUtil.test.ts index e224a7c07ee..4ff3dd079ce 100644 --- a/packages/assets-controllers/src/assetsUtil.test.ts +++ b/packages/assets-controllers/src/assetsUtil.test.ts @@ -264,8 +264,8 @@ describe('assetsUtil', () => { ).toBe(true); }); - it('returns false for testnets such as Ropsten', () => { - expect(assetsUtil.isTokenDetectionSupportedForNetwork('3')).toBe(false); + it('returns false for testnets such as Goerli', () => { + expect(assetsUtil.isTokenDetectionSupportedForNetwork('5')).toBe(false); }); }); @@ -296,9 +296,9 @@ describe('assetsUtil', () => { ).toBe(true); }); - it('returns false for testnets such as Ropsten', () => { + it('returns false for testnets such as Goerli', () => { expect( - assetsUtil.isTokenListSupportedForNetwork(NetworksChainId.ropsten), + assetsUtil.isTokenListSupportedForNetwork(NetworksChainId.goerli), ).toBe(false); }); }); diff --git a/packages/controller-utils/src/constants.ts b/packages/controller-utils/src/constants.ts index 24c4dfb0bae..136236b2cab 100644 --- a/packages/controller-utils/src/constants.ts +++ b/packages/controller-utils/src/constants.ts @@ -6,7 +6,6 @@ export const FALL_BACK_VS_CURRENCY = 'ETH'; export const IPFS_DEFAULT_GATEWAY_URL = 'https://cloudflare-ipfs.com/ipfs/'; // NETWORKS ID -export const RINKEBY_CHAIN_ID = '4'; export const GANACHE_CHAIN_ID = '1337'; // TOKEN STANDARDS @@ -35,19 +34,15 @@ export const ASSET_TYPES = { // TICKER SYMBOLS export const TESTNET_TICKER_SYMBOLS = { - RINKEBY: 'RinkebyETH', GOERLI: 'GoerliETH', - ROPSTEN: 'RopstenETH', - KOVAN: 'KovanETH', + SEPOLIA: 'SepoliaETH', }; // TYPED NetworkType TICKER SYMBOLS export const TESTNET_NETWORK_TYPE_TO_TICKER_SYMBOL: { [K in NetworkType]: string; } = { - rinkeby: 'RinkebyETH', goerli: 'GoerliETH', - ropsten: 'RopstenETH', - kovan: 'KovanETH', + sepolia: 'SepoliaETH', mainnet: '', rpc: '', localhost: '', diff --git a/packages/controller-utils/src/types.ts b/packages/controller-utils/src/types.ts index 3dcf9dd5519..5be4fc21bc8 100644 --- a/packages/controller-utils/src/types.ts +++ b/packages/controller-utils/src/types.ts @@ -2,20 +2,16 @@ * Human-readable network name */ export type NetworkType = - | 'kovan' | 'localhost' | 'mainnet' - | 'rinkeby' | 'goerli' - | 'ropsten' + | 'sepolia' | 'rpc'; export enum NetworksChainId { mainnet = '1', - kovan = '42', - rinkeby = '4', goerli = '5', - ropsten = '3', + sepolia = '11155111', localhost = '', rpc = '', } diff --git a/packages/controller-utils/src/util.test.ts b/packages/controller-utils/src/util.test.ts index eb2b27e0577..540d3868e17 100644 --- a/packages/controller-utils/src/util.test.ts +++ b/packages/controller-utils/src/util.test.ts @@ -27,12 +27,8 @@ describe('util', () => { expect(util.getBuyURL('1', 'foo', 1337)).toBe( 'https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=1337&address=foo&crypto_currency=ETH', ); - expect(util.getBuyURL('3')).toBe('https://faucet.metamask.io/'); - expect(util.getBuyURL('4')).toBe('https://www.rinkeby.io/'); expect(util.getBuyURL('5')).toBe('https://goerli-faucet.slock.it/'); - expect(util.getBuyURL('42')).toBe( - 'https://github.com/kovan-testnet/faucet', - ); + expect(util.getBuyURL('11155111')).toBe('https://sepoliafaucet.net/'); expect(util.getBuyURL('unrecognized network ID')).toBeUndefined(); }); diff --git a/packages/controller-utils/src/util.ts b/packages/controller-utils/src/util.ts index 914bab51984..d16fbf8adb5 100644 --- a/packages/controller-utils/src/util.ts +++ b/packages/controller-utils/src/util.ts @@ -104,14 +104,10 @@ export function getBuyURL( switch (networkCode) { case '1': return `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`; - case '3': - return 'https://faucet.metamask.io/'; - case '4': - return 'https://www.rinkeby.io/'; case '5': return 'https://goerli-faucet.slock.it/'; - case '42': - return 'https://github.com/kovan-testnet/faucet'; + case '11155111': + return 'https://sepoliafaucet.net/'; default: return undefined; } diff --git a/packages/keyring-controller/package.json b/packages/keyring-controller/package.json index 4589d3d9a42..a18efe265a6 100644 --- a/packages/keyring-controller/package.json +++ b/packages/keyring-controller/package.json @@ -41,8 +41,8 @@ "ethereumjs-wallet": "^1.0.1" }, "devDependencies": { - "@ethereumjs/common": "^2.3.1", - "@ethereumjs/tx": "^3.2.1", + "@ethereumjs/common": "^2.6.1", + "@ethereumjs/tx": "^3.5.2", "@keystonehq/bc-ur-registry-eth": "^0.9.0", "@metamask/auto-changelog": "^3.1.0", "@types/jest": "^26.0.22", diff --git a/packages/keyring-controller/src/KeyringController.test.ts b/packages/keyring-controller/src/KeyringController.test.ts index 52acbcdc227..ad342ff2f82 100644 --- a/packages/keyring-controller/src/KeyringController.test.ts +++ b/packages/keyring-controller/src/KeyringController.test.ts @@ -40,7 +40,7 @@ const privateKey = '1e4e6a4c0c077f4ae8ddfbf372918e61dd0fb4a4cfa592cb16e7546d505e68fc'; const password = 'password123'; -const commonConfig = { chain: 'rinkeby', hardfork: 'berlin' }; +const commonConfig = { chain: 'goerli', hardfork: 'berlin' }; describe('KeyringController', () => { let keyringController: KeyringController; @@ -260,10 +260,12 @@ describe('KeyringController', () => { ).rejects.toThrow('Unexpected end of JSON input'); const address = '0xb97c80fab7a3793bbe746864db80d236f1345ea7'; + const obj = await keyringController.importAccountWithStrategy( AccountImportStrategy.json, [input, somePassword], ); + const newKeyring = { accounts: [address], type: 'Simple Key Pair' }; const modifiedState = { ...initialState, @@ -615,7 +617,7 @@ describe('KeyringController', () => { it('should sign transaction', async () => { const account = initialState.keyrings[0].accounts[0]; const txParams = { - chainId: 3, + chainId: 5, data: '0x1', from: account, gasLimit: '0x5108', @@ -640,7 +642,7 @@ describe('KeyringController', () => { await expect(async () => { const account = initialState.keyrings[0].accounts[0]; const txParams = { - chainId: 3, + chainId: 5, data: '0x1', from: account, gasLimit: '0x5108', @@ -967,7 +969,7 @@ describe('KeyringController', () => { const tx = TransactionFactory.fromTxData( { accessList: [], - chainId: '0x4', + chainId: '0x5', data: '0x', gasLimit: '0x5208', maxFeePerGas: '0x2540be400', @@ -984,9 +986,9 @@ describe('KeyringController', () => { common: Common.forCustomChain( MAINNET, { - name: 'rinkeby', - chainId: parseInt('4'), - networkId: parseInt('4'), + name: 'goerli', + chainId: parseInt('5'), + networkId: parseInt('5'), }, 'london', ), diff --git a/packages/network-controller/src/NetworkController.test.ts b/packages/network-controller/src/NetworkController.test.ts index 3b1ce6176c2..bec3813a02d 100644 --- a/packages/network-controller/src/NetworkController.test.ts +++ b/packages/network-controller/src/NetworkController.test.ts @@ -11,6 +11,18 @@ import { const RPC_TARGET = 'http://foo'; +const ethQuerySendAsyncMock = jest + .fn() + .mockImplementation((_: any, cb: any) => { + cb(null, {}); + }); + +jest.mock('eth-query', () => + jest.fn().mockImplementation(() => ({ + sendAsync: ethQuerySendAsyncMock, + })), +); + const setupController = ( pType: NetworkType, messenger: NetworkControllerMessenger, @@ -74,17 +86,17 @@ describe('NetworkController', () => { expect(controller.provider instanceof Web3ProviderEngine).toBe(true); }); - ( - ['kovan', 'rinkeby', 'ropsten', 'mainnet', 'localhost'] as NetworkType[] - ).forEach((n) => { - it(`should create a provider instance for ${n} infura network`, () => { - const networkController = setupController(n, messenger); - expect(networkController.provider instanceof Web3ProviderEngine).toBe( - true, - ); - expect(networkController.state.isCustomNetwork).toBe(false); - }); - }); + (['sepolia', 'goerli', 'mainnet', 'localhost'] as NetworkType[]).forEach( + (n) => { + it(`should create a provider instance for ${n} infura network`, () => { + const networkController = setupController(n, messenger); + expect(networkController.provider instanceof Web3ProviderEngine).toBe( + true, + ); + expect(networkController.state.isCustomNetwork).toBe(false); + }); + }, + ); it('should create a provider instance for optimism network', () => { const networkControllerOpts: NetworkControllerOptions = { @@ -165,6 +177,32 @@ describe('NetworkController', () => { expect(controller.state.providerConfig.nickname).toBeUndefined(); }); + it('should set sepolia provider type', () => { + const controller = new NetworkController({ + messenger, + infuraProjectId: '123', + }); + controller.setProviderType('sepolia' as NetworkType); + expect(controller.state.providerConfig.type).toBe('sepolia'); + expect(controller.state.providerConfig.ticker).toBe('SepoliaETH'); + expect(controller.state.isCustomNetwork).toBe(false); + expect(controller.state.providerConfig.rpcTarget).toBeUndefined(); + expect(controller.state.providerConfig.nickname).toBeUndefined(); + }); + + it('should set goerli provider type', () => { + const controller = new NetworkController({ + messenger, + infuraProjectId: '123', + }); + controller.setProviderType('goerli' as NetworkType); + expect(controller.state.providerConfig.type).toBe('goerli'); + expect(controller.state.providerConfig.ticker).toBe('GoerliETH'); + expect(controller.state.isCustomNetwork).toBe(false); + expect(controller.state.providerConfig.rpcTarget).toBeUndefined(); + expect(controller.state.providerConfig.nickname).toBeUndefined(); + }); + it('should set rpcTarget and nickname props to undefined when set a provider type', () => { const controller = new NetworkController({ messenger, @@ -186,6 +224,22 @@ describe('NetworkController', () => { ); }); + it('should be EIP1559 compatible', () => { + ethQuerySendAsyncMock.mockImplementationOnce((_: any, cb: any) => { + cb(null, { baseFeePerGas: true }); + }); + + const controller = new NetworkController({ + messenger, + infuraProjectId: '123', + state: { + network: 'loading', + }, + }); + controller.providerConfig = {} as ProviderConfig; + expect(controller.state.properties.isEIP1559Compatible).toBe(true); + }); + it('should verify the network on an error', async () => { const controller = new NetworkController({ messenger, diff --git a/packages/network-controller/src/NetworkController.ts b/packages/network-controller/src/NetworkController.ts index 730094891cb..621f4749c37 100644 --- a/packages/network-controller/src/NetworkController.ts +++ b/packages/network-controller/src/NetworkController.ts @@ -173,11 +173,9 @@ export class NetworkController extends BaseControllerV2< }); switch (type) { - case 'kovan': case MAINNET: - case 'rinkeby': case 'goerli': - case 'ropsten': + case 'sepolia': this.setupInfuraProvider(type); break; case 'localhost': @@ -230,10 +228,8 @@ export class NetworkController extends BaseControllerV2< private getIsCustomNetwork(chainId?: string) { return ( chainId !== NetworksChainId.mainnet && - chainId !== NetworksChainId.kovan && - chainId !== NetworksChainId.rinkeby && chainId !== NetworksChainId.goerli && - chainId !== NetworksChainId.ropsten && + chainId !== NetworksChainId.sepolia && chainId !== NetworksChainId.localhost ); } diff --git a/packages/transaction-controller/package.json b/packages/transaction-controller/package.json index 7aa74aab1ad..3782bee820d 100644 --- a/packages/transaction-controller/package.json +++ b/packages/transaction-controller/package.json @@ -29,8 +29,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@ethereumjs/common": "^2.3.1", - "@ethereumjs/tx": "^3.2.1", + "@ethereumjs/common": "^2.6.1", + "@ethereumjs/tx": "^3.5.2", "@metamask/base-controller": "workspace:^", "@metamask/controller-utils": "workspace:^", "@metamask/network-controller": "workspace:^", diff --git a/packages/transaction-controller/src/TransactionController.test.ts b/packages/transaction-controller/src/TransactionController.test.ts index 2cd18b8ac65..8bbac4cec1a 100644 --- a/packages/transaction-controller/src/TransactionController.test.ts +++ b/packages/transaction-controller/src/TransactionController.test.ts @@ -123,7 +123,7 @@ function mockFetchWithDynamicResponse(dataForUrl: any) { const MOCK_PRFERENCES = { state: { selectedAddress: 'foo' } }; const PROVIDER = new HttpProvider( - 'https://ropsten.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', + 'https://goerli.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', ); const MAINNET_PROVIDER = new HttpProvider( 'https://mainnet.infura.io/v3/341eacb578dd44a1a049cbc5f6fd4035', @@ -131,12 +131,12 @@ const MAINNET_PROVIDER = new HttpProvider( const MOCK_NETWORK = { getProvider: () => PROVIDER, state: { - network: '3', + network: '5', isCustomNetwork: false, properties: { isEIP1559Compatible: false }, providerConfig: { - type: 'ropsten' as NetworkType, - chainId: NetworksChainId.ropsten, + type: 'goerli' as NetworkType, + chainId: NetworksChainId.goerli, }, }, subscribe: () => undefined, @@ -157,7 +157,7 @@ const MOCK_NETWORK_CUSTOM = { const MOCK_NETWORK_WITHOUT_CHAIN_ID = { getProvider: () => PROVIDER, isCustomNetwork: false, - state: { network: '3', providerConfig: { type: 'ropsten' as NetworkType } }, + state: { network: '5', providerConfig: { type: 'goerli' as NetworkType } }, subscribe: () => undefined, }; const MOCK_MAINNET_NETWORK = { @@ -243,28 +243,28 @@ const TOKEN_TX_HISTORY_DATA_FROM_BLOCK = { status: '1', }; -const ETH_TX_HISTORY_DATA_ROPSTEN_NO_TRANSACTIONS_FOUND = { +const ETH_TX_HISTORY_DATA_GOERLI_NO_TRANSACTIONS_FOUND = { message: 'No transactions found', result: [], status: '0', }; const MOCK_FETCH_TX_HISTORY_DATA_OK = { - 'https://api-ropsten.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=tokentx&tag=latest&page=1': - ETH_TX_HISTORY_DATA_ROPSTEN_NO_TRANSACTIONS_FOUND, + 'https://api-goerli.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=tokentx&tag=latest&page=1': + ETH_TX_HISTORY_DATA_GOERLI_NO_TRANSACTIONS_FOUND, 'https://api.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=tokentx&tag=latest&page=1': TOKEN_TX_HISTORY_DATA, 'https://api.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&startBlock=999&offset=40&order=desc&action=tokentx&tag=latest&page=1': TOKEN_TX_HISTORY_DATA_FROM_BLOCK, 'https://api.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=txlist&tag=latest&page=1': ETH_TX_HISTORY_DATA, - 'https://api-ropsten.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=txlist&tag=latest&page=1': + 'https://api-goerli.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=40&order=desc&action=txlist&tag=latest&page=1': ETH_TX_HISTORY_DATA, 'https://api.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&startBlock=999&offset=40&order=desc&action=txlist&tag=latest&page=1': ETH_TX_HISTORY_DATA_FROM_BLOCK, - 'https://api-ropsten.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=2&order=desc&action=tokentx&tag=latest&page=1': - ETH_TX_HISTORY_DATA_ROPSTEN_NO_TRANSACTIONS_FOUND, - 'https://api-ropsten.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=2&order=desc&action=txlist&tag=latest&page=1': + 'https://api-goerli.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=2&order=desc&action=tokentx&tag=latest&page=1': + ETH_TX_HISTORY_DATA_GOERLI_NO_TRANSACTIONS_FOUND, + 'https://api-goerli.etherscan.io/api?module=account&address=0x6bf137f335ea1b8f193b8f6ea92561a60d23a207&offset=2&order=desc&action=txlist&tag=latest&page=1': ETH_TX_HISTORY_DATA, }; @@ -529,7 +529,7 @@ describe('TransactionController', () => { getProvider, }); - // switch from Ropsten to Mainnet + // switch from Goerli to Mainnet getNetworkState.returns(MOCK_MAINNET_NETWORK.state); getProvider.returns(MAINNET_PROVIDER); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -568,7 +568,7 @@ describe('TransactionController', () => { getProvider, }); - // switch from Ropsten to Mainnet + // switch from Goerli to Mainnet getNetworkState.returns(MOCK_NETWORK_CUSTOM.state); getProvider.returns(PROVIDER); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -649,7 +649,7 @@ describe('TransactionController', () => { controller.state.transactions.push({ from: MOCK_PRFERENCES.state.selectedAddress, id: 'foo', - networkID: '3', + networkID: '5', status: TransactionStatus.submitted, transactionHash: '1337', } as any); @@ -853,8 +853,8 @@ describe('TransactionController', () => { controller.state.transactions.push({ from: MOCK_PRFERENCES.state.selectedAddress, id: 'foo', - networkID: '3', - chainId: '3', + networkID: '5', + chainId: '5', status: TransactionStatus.submitted, transactionHash: '1337', } as any); @@ -889,7 +889,7 @@ describe('TransactionController', () => { controller.state.transactions.push({ from: MOCK_PRFERENCES.state.selectedAddress, id: 'foo', - networkID: '3', + networkID: '5', status: TransactionStatus.submitted, transactionHash: '1337', } as any); @@ -922,7 +922,7 @@ describe('TransactionController', () => { controller.state.transactions.push({ from: MOCK_PRFERENCES.state.selectedAddress, id: 'foo', - networkID: '3', + networkID: '5', status: TransactionStatus.submitted, transactionHash: '1338', } as any); @@ -946,8 +946,8 @@ describe('TransactionController', () => { controller.state.transactions.push({ from: MOCK_PRFERENCES.state.selectedAddress, id: 'foo', - networkID: '3', - chainId: '3', + networkID: '5', + chainId: '5', status: TransactionStatus.confirmed, transactionHash: '1337', verifiedOnBlockchain: false, @@ -960,7 +960,7 @@ describe('TransactionController', () => { expect(controller.state.transactions[0].transaction.gasUsed).toBe('0x5208'); }); - it('should fetch all the transactions from an address, including incoming transactions, in ropsten', async () => { + it('should fetch all the transactions from an address, including incoming transactions, in goerli', async () => { mockFetchWithDynamicResponse(MOCK_FETCH_TX_HISTORY_DATA_OK); const controller = new TransactionController({ getNetworkState: () => MOCK_NETWORK.state, diff --git a/packages/transaction-controller/src/TransactionController.ts b/packages/transaction-controller/src/TransactionController.ts index b31107bcd26..9ab549976cb 100644 --- a/packages/transaction-controller/src/TransactionController.ts +++ b/packages/transaction-controller/src/TransactionController.ts @@ -1132,7 +1132,7 @@ export class TransactionController extends BaseController< const { chainId: currentChainId, type: networkType } = providerConfig; const { transactions } = this.state; - const supportedNetworkIds = ['1', '3', '4', '42']; + const supportedNetworkIds = ['1', '5', '11155111']; /* istanbul ignore next */ if (supportedNetworkIds.indexOf(currentNetworkID) === -1) { return undefined; diff --git a/packages/transaction-controller/src/utils.test.ts b/packages/transaction-controller/src/utils.test.ts index f1404784c5b..dca3347f665 100644 --- a/packages/transaction-controller/src/utils.test.ts +++ b/packages/transaction-controller/src/utils.test.ts @@ -33,9 +33,9 @@ describe('utils', () => { }); it('should return a correctly structured url with testnet subdomain', () => { - const ropsten = 'ropsten'; - const url = util.getEtherscanApiUrl(ropsten, { address, action }); - expect(url.indexOf(`https://api-${ropsten}`)).toBe(0); + const goerli = 'goerli'; + const url = util.getEtherscanApiUrl(goerli, { address, action }); + expect(url.indexOf(`https://api-${goerli}`)).toBe(0); }); it('should return a correctly structured url with apiKey', () => { diff --git a/yarn.lock b/yarn.lock index e2a2247a40a..e1243a2f52b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -595,16 +595,6 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/common@npm:^2.3.1": - version: 2.3.1 - resolution: "@ethereumjs/common@npm:2.3.1" - dependencies: - crc-32: ^1.2.0 - ethereumjs-util: ^7.0.10 - checksum: 860d79c4c79684b532ba6cdc6f8f34d0c29e75d19edbf462b54f598615949d64aaea9d1e96a2b22da846677471d15b681675508bab3555db739e8276143f760a - languageName: node - linkType: hard - "@ethereumjs/common@npm:^2.4.0": version: 2.4.0 resolution: "@ethereumjs/common@npm:2.4.0" @@ -615,7 +605,7 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/common@npm:^2.6.3": +"@ethereumjs/common@npm:^2.6.1, @ethereumjs/common@npm:^2.6.3, @ethereumjs/common@npm:^2.6.4": version: 2.6.5 resolution: "@ethereumjs/common@npm:2.6.5" dependencies: @@ -644,16 +634,6 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/tx@npm:^3.2.1": - version: 3.2.1 - resolution: "@ethereumjs/tx@npm:3.2.1" - dependencies: - "@ethereumjs/common": ^2.3.1 - ethereumjs-util: ^7.0.10 - checksum: 311404f0569fea03e5133c49d129ed9d814cc8baaca90bebb5fc8eae0d4cbc146cb66c2a2c3c54343d4699ff7e0475376bbe9bb9c38dc8dc1b2df0c6e2aaeb73 - languageName: node - linkType: hard - "@ethereumjs/tx@npm:^3.3.0": version: 3.3.0 resolution: "@ethereumjs/tx@npm:3.3.0" @@ -664,6 +644,16 @@ __metadata: languageName: node linkType: hard +"@ethereumjs/tx@npm:^3.5.2": + version: 3.5.2 + resolution: "@ethereumjs/tx@npm:3.5.2" + dependencies: + "@ethereumjs/common": ^2.6.4 + ethereumjs-util: ^7.1.5 + checksum: a34a7228a623b40300484d15875b9f31f0a612cfeab64a845f6866cf0bfe439519e9455ac6396149f29bc527cf0ee277ace082ae013a1075dcbf7193220a0146 + languageName: node + linkType: hard + "@ethereumjs/util@npm:^8.0.0": version: 8.0.0 resolution: "@ethereumjs/util@npm:8.0.0" @@ -1771,8 +1761,8 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/keyring-controller@workspace:packages/keyring-controller" dependencies: - "@ethereumjs/common": ^2.3.1 - "@ethereumjs/tx": ^3.2.1 + "@ethereumjs/common": ^2.6.1 + "@ethereumjs/tx": ^3.5.2 "@keystonehq/bc-ur-registry-eth": ^0.9.0 "@keystonehq/metamask-airgapped-keyring": ^0.6.1 "@metamask/auto-changelog": ^3.1.0 @@ -1995,8 +1985,8 @@ __metadata: version: 0.0.0-use.local resolution: "@metamask/transaction-controller@workspace:packages/transaction-controller" dependencies: - "@ethereumjs/common": ^2.3.1 - "@ethereumjs/tx": ^3.2.1 + "@ethereumjs/common": ^2.6.1 + "@ethereumjs/tx": ^3.5.2 "@metamask/auto-changelog": ^3.1.0 "@metamask/base-controller": "workspace:^" "@metamask/controller-utils": "workspace:^"