diff --git a/FUNDING.json b/FUNDING.json
index c9df9ba5e72..da00866a57f 100644
--- a/FUNDING.json
+++ b/FUNDING.json
@@ -1,7 +1,7 @@
{
- "drips": {
- "ethereum": {
- "ownedBy": "0x04E504Acb5f6A9CB387fa37ec5Fc457A9D36D371"
- }
- }
+ "drips": {
+ "ethereum": {
+ "ownedBy": "0x04E504Acb5f6A9CB387fa37ec5Fc457A9D36D371"
+ }
+ }
}
diff --git a/packages/web3-rpc-providers/CHANGELOG.md b/packages/web3-rpc-providers/CHANGELOG.md
index 110b620707d..0511d7dfc0d 100644
--- a/packages/web3-rpc-providers/CHANGELOG.md
+++ b/packages/web3-rpc-providers/CHANGELOG.md
@@ -62,4 +62,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+- InfuraProvider was added (#7286)
- PublicNodeProvider was added (#7322)
diff --git a/packages/web3-rpc-providers/src/index.ts b/packages/web3-rpc-providers/src/index.ts
index f7c0e6c2613..1eaffe648f1 100644
--- a/packages/web3-rpc-providers/src/index.ts
+++ b/packages/web3-rpc-providers/src/index.ts
@@ -19,6 +19,7 @@ import { QuickNodeProvider } from './web3_provider_quicknode.js';
export * from './types.js';
export * from './web3_provider_quicknode.js';
+export * from './web3_provider_infura.js';
export * from './web3_provider_publicnode.js';
export * from './web3_provider.js';
export * from './errors.js';
diff --git a/packages/web3-rpc-providers/src/types.ts b/packages/web3-rpc-providers/src/types.ts
index 258d6411c57..c4718d3572c 100644
--- a/packages/web3-rpc-providers/src/types.ts
+++ b/packages/web3-rpc-providers/src/types.ts
@@ -26,8 +26,27 @@ export enum Transport {
export enum Network {
ETH_MAINNET = 'eth_mainnet',
ETH_SEPOLIA = 'eth_sepolia',
+ ETH_GOERLI = 'eth_goerli',
ETH_HOLESKY = 'eth_holesky',
+ PALM_MAINNET = 'palm_mainnet',
+ PALM_TESTNET = 'palm_testnet',
+
+ BLAST_MAINNET = 'blast_mainnet',
+ BLAST_SEPOLIA = 'blast_sepolia',
+
+ STARKNET_MAINNET = 'starknet_mainnet',
+ STARKNET_SEPOLIA = 'starknet_sepolia',
+
+ ZKSYNC_MAINNET = 'zksync_mainnet',
+ ZKSYNC_SEPOLIA = 'zksync_sepolia',
+
+ CELO_MAINNET = 'celo_mainnet',
+ CELO_ALFAJORES = 'celo_alfajores',
+
+ AVALANCHE_MAINNET = 'avalanche_mainnet',
+ AVALANCHE_FUJI = 'avalanche_fuji',
+
POLYGON_MAINNET = 'polygon_mainnet',
POLYGON_AMOY = 'polygon_amoy',
@@ -37,12 +56,15 @@ export enum Network {
ARBITRUM_MAINNET = 'arbitrum_mainnet',
ARBITRUM_SEPOLIA = 'arbitrum_sepolia',
+ ARBITRUM_GOERLI = 'arbitrum_goerli',
BASE_MAINNET = 'base_mainnet',
BASE_SEPOLIA = 'base_sepolia',
+ BASE_GOERLI = 'base_foerli',
OPTIMISM_MAINNET = 'optimism_mainnet',
OPTIMISM_SEPOLIA = 'optimism_sepolia',
+ OPTIMISM_GOERLI = 'optimism_goerli',
FANTOM_MAINNET = 'fantom_mainnet',
FANTOM_TESTNET = 'fantom_testnet',
@@ -56,12 +78,16 @@ export enum Network {
BSC_MAINNET = 'bsc_mainnet',
BSC_TESTNET = 'bsc_testnet',
+ MANTLE_SEPOLIA = 'mantle_sepolia',
+
+ LINEA_MAINNET = 'linea_mainnet',
+ LINEA_SEPOLIA = 'linea_sepolia',
+ LINEA_GOERLI = 'linea_goerli',
ARBITRUM_ONE = 'arbitrum_one',
ARBITRUM_NOVA = 'arbitrum_nova',
AVALANCHE_FUJI_C = 'avalanche_fuji_c',
AVALANCHE_FUJI_P = 'avalanche_fuji_p',
AVALANCHE_FUJI_X = 'avalanche_fuji_x',
- BLAST_MAINNET = 'blast_mainnet',
OPBNB_MAINNET = 'opbnb_mainnet',
OPBNB_TESTNET = 'opbnb_testnet',
GNOSIS_MAINNET = 'gnosis_mainnet',
@@ -76,8 +102,6 @@ export enum Network {
MOONBEAM_MAINNET = 'moonbeam_mainnet',
TAIKO_MAINNET = 'taiko_mainnet',
TAIKO_HEKLA = 'taiko_hekla',
- LINEA_MAINNET = 'linea_mainnet',
- LINEA_SEPOLIA = 'linea_sepolia',
BAHAMUT_MAINNET = 'bahamut_mainnet',
SCROLL_MAINNET = 'scroll_mainnet',
SCROLL_SEPOLIA = 'scroll_sepolia',
diff --git a/packages/web3-rpc-providers/src/web3_provider_infura.ts b/packages/web3-rpc-providers/src/web3_provider_infura.ts
new file mode 100644
index 00000000000..04e7fa6d0db
--- /dev/null
+++ b/packages/web3-rpc-providers/src/web3_provider_infura.ts
@@ -0,0 +1,83 @@
+/*
+This file is part of web3.js.
+
+web3.js is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+web3.js is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with web3.js. If not, see .
+*/
+
+import { EthExecutionAPI, Web3APISpec } from 'web3-types';
+import { HttpProviderOptions } from 'web3-providers-http';
+import { Network, SocketOptions, Transport } from './types.js';
+import { Web3ExternalProvider } from './web3_provider.js';
+
+const isValid = (str: string) => str !== undefined && str.trim().length > 0;
+
+export class InfuraProvider<
+ API extends Web3APISpec = EthExecutionAPI,
+> extends Web3ExternalProvider {
+ // eslint-disable-next-line default-param-last
+ public constructor(
+ network: Network = Network.ETH_MAINNET,
+ transport: Transport = Transport.HTTPS,
+ token = '',
+ host = '',
+ providerConfigOptions?: HttpProviderOptions | SocketOptions,
+ ) {
+ super(network, transport, token, host, providerConfigOptions);
+ }
+ public static readonly networkHostMap: { [key: string]: string } = {
+ [Network.PALM_MAINNET]: 'palm-mainnet',
+ [Network.PALM_TESTNET]: 'palm-testnet',
+ [Network.BLAST_MAINNET]: 'blast-mainnet',
+ [Network.BLAST_SEPOLIA]: 'blast-sepolia',
+ [Network.AVALANCHE_MAINNET]: 'avalanche-mainnet',
+ [Network.AVALANCHE_FUJI]: 'avalanche-fuji',
+ [Network.STARKNET_MAINNET]: 'starknet-mainnet',
+ [Network.STARKNET_SEPOLIA]: 'starknet-sepolia',
+ [Network.ZKSYNC_MAINNET]: 'zksync-mainnet',
+ [Network.ZKSYNC_SEPOLIA]: 'zksync-sepolia',
+ [Network.CELO_MAINNET]: 'celo-mainnet',
+ [Network.CELO_ALFAJORES]: 'celo-alfajores',
+ [Network.BSC_MAINNET]: 'bsc-mainnet',
+ [Network.BSC_TESTNET]: 'bsc-testnet',
+ [Network.MANTLE_MAINNET]: 'mantle-mainnet',
+ [Network.MANTLE_SEPOLIA]: 'mantle-sepolia',
+ [Network.ETH_MAINNET]: 'mainnet',
+ [Network.ETH_HOLESKY]: 'holesky',
+ [Network.ETH_SEPOLIA]: 'sepolia',
+ [Network.ARBITRUM_MAINNET]: 'arbitrum-mainnet',
+ [Network.ARBITRUM_SEPOLIA]: 'arbitrum-sepolia',
+ [Network.BASE_MAINNET]: 'base-mainnet',
+ [Network.BASE_SEPOLIA]: 'base-sepolia',
+ [Network.BNB_MAINNET]: 'opbnb-mainnet',
+ [Network.BNB_TESTNET]: 'opbnb-testnet',
+ [Network.LINEA_MAINNET]: 'linea-mainnet',
+ [Network.LINEA_SEPOLIA]: 'linea-sepolia',
+ [Network.POLYGON_MAINNET]: 'polygon-mainnet',
+ [Network.POLYGON_AMOY]: 'polygon-amoy',
+ [Network.OPTIMISM_MAINNET]: 'optimism-mainnet',
+ [Network.OPTIMISM_SEPOLIA]: 'optimism-sepolia',
+ };
+ // eslint-disable-next-line class-methods-use-this
+ public getRPCURL(network: Network, transport: Transport, token: string, _host: string) {
+ if (!InfuraProvider.networkHostMap[network]) {
+ throw new Error('Network info not avalible.');
+ }
+ const defaultHost = `${InfuraProvider.networkHostMap[network]}.infura.io`;
+ const host = isValid(_host) ? _host : defaultHost;
+
+ return `${transport}://${host}/${
+ transport === Transport.WebSocket ? 'ws/' : ''
+ }v3/${token}`;
+ }
+}
diff --git a/packages/web3-rpc-providers/test/unit/constructor.test.ts b/packages/web3-rpc-providers/test/unit/constructor.test.ts
index cc34cb1fcd3..dfc0e4b25c2 100644
--- a/packages/web3-rpc-providers/test/unit/constructor.test.ts
+++ b/packages/web3-rpc-providers/test/unit/constructor.test.ts
@@ -23,7 +23,7 @@ import { Web3ExternalProvider } from '../../src/web3_provider';
import { Network, SocketOptions, Transport } from '../../src/types';
import { ProviderConfigOptionsError } from '../../src/errors';
-// Mock implementation so ws doesnt have openhandle after test exits as it attempts to connects at start
+// Mock implementation so ws doesnt have openhandle after test exits as it attempts to connect at start
jest.mock('isomorphic-ws', () => {
return {
__esModule: true,
diff --git a/packages/web3-rpc-providers/test/unit/request.test.ts b/packages/web3-rpc-providers/test/unit/request.test.ts
index da07c2a578c..29a0372b808 100644
--- a/packages/web3-rpc-providers/test/unit/request.test.ts
+++ b/packages/web3-rpc-providers/test/unit/request.test.ts
@@ -83,7 +83,7 @@ describe('Web3ExternalProvider', () => {
expect(result).toEqual({ result: 'mock-result' });
});
- it('should throw a rate limiting error when status code is 429', async () => {
+ it('QuickNodeProvider: should throw a rate limiting error when status code is 429', async () => {
const network: Network = Network.ETH_MAINNET;
const transport: Transport = Transport.HTTPS;
const token = 'your-token';
diff --git a/packages/web3/test/integration/external-providers/infura-rpc.test.ts b/packages/web3/test/integration/external-providers/infura-rpc.test.ts
deleted file mode 100644
index 479949c06f8..00000000000
--- a/packages/web3/test/integration/external-providers/infura-rpc.test.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-This file is part of web3.js.
-
-web3.js is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-web3.js is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with web3.js. If not, see .
-*/
-
-import Web3 from '../../../src/index';
-import { describeIf, isIpc, itIf } from '../../shared_fixtures/system_tests_utils';
-
-describeIf(!isIpc)('compatibility with `infura` remote rpc providers', () => {
- itIf(
- process.env.INFURA_GOERLI_WS
- ? process.env.INFURA_GOERLI_WS.toString().includes('ws')
- : false,
- )('should create Web3 class instance with `ws` string connection', () => {
- const web3 = new Web3(process.env.INFURA_GOERLI_WS);
- // eslint-disable-next-line jest/no-standalone-expect
- expect(web3).toBeInstanceOf(Web3);
- });
-
- itIf(
- process.env.INFURA_GOERLI_HTTP
- ? process.env.INFURA_GOERLI_HTTP.toString().includes('http')
- : false,
- )('should create Web3 class instance with `http` string connection', () => {
- const web3 = new Web3(process.env.INFURA_GOERLI_HTTP);
- // eslint-disable-next-line jest/no-standalone-expect
- expect(web3).toBeInstanceOf(Web3);
- });
-});
diff --git a/packages/web3/test/integration/web3RPCProviders.test.ts b/packages/web3/test/integration/web3RPCProviders.test.ts
index 6e6d2994f9c..6b60097da3d 100644
--- a/packages/web3/test/integration/web3RPCProviders.test.ts
+++ b/packages/web3/test/integration/web3RPCProviders.test.ts
@@ -20,13 +20,15 @@ import {
Network,
QuickNodeProvider,
Transport,
+ InfuraProvider,
PublicNodeProvider,
} from 'web3-rpc-providers';
import { Web3 } from '../../src/index';
+jest.setTimeout(10000);
describe('Web3 RPC Provider Integration tests', () => {
const transports = Object.values(Transport);
- const networks = [
+ const quickNodeNetworks = [
Network.ETH_MAINNET,
Network.ETH_HOLESKY,
Network.ETH_SEPOLIA,
@@ -39,7 +41,7 @@ describe('Web3 RPC Provider Integration tests', () => {
];
transports.forEach(transport => {
- networks.forEach(network => {
+ quickNodeNetworks.forEach(network => {
it(`QuickNodeProvider should work with ${transport} transport and ${network} network`, async () => {
const provider = new QuickNodeProvider(network, transport);
const web3 = new Web3(provider);
@@ -55,6 +57,85 @@ describe('Web3 RPC Provider Integration tests', () => {
});
});
+ const infuraNetworks = [
+ Network.PALM_MAINNET,
+ Network.PALM_TESTNET,
+ Network.BLAST_MAINNET,
+ Network.BLAST_SEPOLIA,
+ Network.AVALANCHE_MAINNET,
+ Network.AVALANCHE_FUJI,
+ Network.STARKNET_MAINNET,
+ Network.STARKNET_SEPOLIA,
+ Network.ZKSYNC_MAINNET,
+ Network.ZKSYNC_SEPOLIA,
+ Network.CELO_MAINNET,
+ Network.CELO_ALFAJORES,
+ Network.BSC_MAINNET,
+ Network.BSC_TESTNET,
+ Network.MANTLE_MAINNET,
+ Network.MANTLE_SEPOLIA,
+ Network.ETH_MAINNET,
+ Network.ETH_HOLESKY,
+ Network.ETH_SEPOLIA,
+ Network.ARBITRUM_MAINNET,
+ Network.ARBITRUM_SEPOLIA,
+ Network.BASE_MAINNET,
+ Network.BASE_SEPOLIA,
+ Network.BNB_MAINNET,
+ Network.BNB_TESTNET,
+ Network.LINEA_MAINNET,
+ Network.LINEA_SEPOLIA,
+ Network.POLYGON_MAINNET,
+ Network.POLYGON_AMOY,
+ Network.OPTIMISM_MAINNET,
+ Network.OPTIMISM_SEPOLIA,
+ ];
+ transports.forEach(transport => {
+ infuraNetworks.forEach(network => {
+ // skip not exists endpoints
+ if (
+ !(
+ [
+ Network.PALM_MAINNET,
+ Network.PALM_TESTNET,
+ Network.BLAST_SEPOLIA,
+ Network.STARKNET_MAINNET,
+ Network.STARKNET_SEPOLIA,
+ Network.ZKSYNC_SEPOLIA,
+ Network.BSC_TESTNET,
+ Network.MANTLE_SEPOLIA,
+ Network.BNB_TESTNET,
+ ].includes(network) && transport === Transport.WebSocket
+ )
+ ) {
+ it.skip(`InfuraProvider should work with ${transport} transport and ${network} network`, async () => {
+ const provider = new InfuraProvider(
+ network,
+ transport,
+ process.env.INFURA_PROVIDER_KEY,
+ );
+
+ const web3 = new Web3(provider);
+ const result =
+ network === Network.STARKNET_MAINNET || network === Network.STARKNET_SEPOLIA
+ ? BigInt(
+ await web3.requestManager.send({
+ method: 'starknet_blockNumber',
+ params: [],
+ }),
+ )
+ : await web3.eth.getBlockNumber();
+ expect(typeof result).toBe('bigint');
+ expect(result > 0).toBe(true);
+
+ if (transport === Transport.WebSocket) {
+ web3.provider?.disconnect();
+ }
+ });
+ }
+ });
+ });
+
const publicNodeNetworks = [
Network.POLYGON_AMOY,
Network.POLYGON_MAINNET,