diff --git a/packages/web3-rpc-providers/src/index.ts b/packages/web3-rpc-providers/src/index.ts
index f7c0e6c2613..83a04a55b71 100644
--- a/packages/web3-rpc-providers/src/index.ts
+++ b/packages/web3-rpc-providers/src/index.ts
@@ -16,12 +16,15 @@ along with web3.js. If not, see .
*/
import { QuickNodeProvider } from './web3_provider_quicknode.js';
+import { AlchemyProvider } from './web3_provider_alchemy.js';
export * from './types.js';
export * from './web3_provider_quicknode.js';
export * from './web3_provider_publicnode.js';
export * from './web3_provider.js';
export * from './errors.js';
+export * from './web3_provider_alchemy.js';
// default providers
export const mainnet = new QuickNodeProvider();
+export const alchemy = new AlchemyProvider();
diff --git a/packages/web3-rpc-providers/src/types.ts b/packages/web3-rpc-providers/src/types.ts
index 258d6411c57..dad9ef0c3b3 100644
--- a/packages/web3-rpc-providers/src/types.ts
+++ b/packages/web3-rpc-providers/src/types.ts
@@ -29,6 +29,11 @@ export enum Network {
ETH_HOLESKY = 'eth_holesky',
POLYGON_MAINNET = 'polygon_mainnet',
+ POLYGON_MUMBAI = 'polygon_mumbai',
+ POLYGON_AMONY = 'polygon_amony',
+ POLYGON_POS_MAINNET = 'polygon_pos_mainnet',
+ POLYGON_ZKEVM_MAINNET = 'polygon_zkevm_mainnet',
+ POLYGON_ZKEVM_CARDONA = 'polygon_zkevm_cardona',
POLYGON_AMOY = 'polygon_amoy',
AVALANCHE_C_MAINNET = 'avalanche_c_mainnet',
@@ -37,6 +42,7 @@ export enum Network {
ARBITRUM_MAINNET = 'arbitrum_mainnet',
ARBITRUM_SEPOLIA = 'arbitrum_sepolia',
+ ARBITRUM_NOVA_MAINNET = 'arbitrum_nova_mainnet',
BASE_MAINNET = 'base_mainnet',
BASE_SEPOLIA = 'base_sepolia',
@@ -53,6 +59,55 @@ export enum Network {
BNB_MAINNET = 'bnb_mainnet',
BNB_TESTNET = 'bnb_testnet',
+ WORLD_CHAIN_MAINNET = 'world_chain_mainnet',
+ WORLD_CHAIN_SEPOLIA = 'world_chain_sepolia',
+
+ SHAPE_MAINNET = 'shape_mainnet',
+ SHAPE_SEPOLIA = 'shape_sepolia',
+
+ ZKSYNC_MAINNET = 'zksync_mainnet',
+ ZKSYNC_SEPOLIA = 'zksync_sepolia',
+
+ STARKNET_MAINNET = 'starknet_mainnet',
+ STARKNET_SEPOLIA = 'starknet_sepolia',
+
+ ZETACHAIN_MAINNET = 'zetachain_mainnet',
+ ZETACHAIN_TESTNET = 'zetachain_testnet',
+
+ FANTOM_OPERA_MAINNET = 'fantom_opera_mainnet',
+ FANTOM_OPERA_TESTNET = 'fantom_opera_testnet',
+
+ BERACHAIN_ARTIO = 'berachain_artio',
+
+ BLAST_SEPOLIA = 'blast_sepolia',
+
+ ZORA_MAINNET = 'zora_mainnet',
+ ZORA_SEPOLIA = 'zora_sepolia',
+
+ POLYNOMIAL_MAINNET = 'polynomial_mainnet',
+ POLYNOMIAL_SEPOLIA = 'polynomial_sepolia',
+
+ FRAX_MAINNET = 'frax_mainnet',
+ FRAX_SEPOLIA = 'frax_sepolia',
+
+ SOLANA_MAINNET = 'solana_mainnet',
+ SOLANA_DEVNET = 'solana_devnet',
+
+ CROSSFI_TESTNET = 'crossfi_testnet',
+
+ ASTAR_MAINNET = 'astar_mainnet',
+
+ FLOW_EVM_TESTNET = 'flow_evm_testnet',
+
+ SONEIUM_MINATO = 'soneium_minato',
+
+ GEIST_POLTER = 'geist_polter',
+
+ ROOTSTOCK_MAINNET = 'rootstock_mainnet',
+ ROOTSTOCK_TESTNET = 'rootstock_testnet',
+
+ UNICHAIN_SEPOLIA = 'unichain_sepolia',
+
BSC_MAINNET = 'bsc_mainnet',
BSC_TESTNET = 'bsc_testnet',
diff --git a/packages/web3-rpc-providers/src/web3_provider_alchemy.ts b/packages/web3-rpc-providers/src/web3_provider_alchemy.ts
new file mode 100644
index 00000000000..750bb348d0b
--- /dev/null
+++ b/packages/web3-rpc-providers/src/web3_provider_alchemy.ts
@@ -0,0 +1,107 @@
+/*
+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 { HttpProviderOptions } from 'web3-providers-http';
+import { Web3ExternalProvider } from './web3_provider.js';
+import { Network, Transport, SocketOptions } from './types.js';
+
+function isValid(value: string): boolean {
+ return !!(value && value.trim().length > 0);
+}
+
+export class AlchemyProvider extends Web3ExternalProvider {
+ 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 networkStringMap: { [key: string]: string } = {
+ [Network.ETH_MAINNET]: 'eth-mainnet.g.alchemy.com',
+ [Network.ETH_SEPOLIA]: 'eth-sepolia.g.alchemy.com',
+ [Network.ETH_HOLESKY]: 'eth-holesky.g.alchemy.com',
+ [Network.ARBITRUM_MAINNET]: 'arb-mainnet.g.alchemy.com',
+ [Network.ARBITRUM_SEPOLIA]: 'arb-sepolia.g.alchemy.com',
+ [Network.ARBITRUM_NOVA_MAINNET]: 'arb-nova.g.alchemy.com',
+ [Network.BASE_MAINNET]: 'base-mainnet.g.alchemy.com',
+ [Network.BASE_SEPOLIA]: 'base-sepolia.g.alchemy.com',
+ [Network.POLYGON_MAINNET]: 'polygon-mainnet.g.alchemy.com',
+ [Network.POLYGON_MUMBAI]: 'polygon-mumbai.g.alchemy.com',
+ [Network.POLYGON_AMOY]: 'polygon-amoy.g.alchemy.com',
+ [Network.POLYGON_POS_MAINNET]: 'polygon-mainnet.g.alchemy.com',
+ [Network.POLYGON_ZKEVM_MAINNET]: 'polygonzkevm-mainnet.g.alchemy.com',
+ [Network.POLYGON_ZKEVM_CARDONA]: 'polygonzkevm-cardona.g.alchemy.com',
+ [Network.OPTIMISM_MAINNET]: 'opt-mainnet.g.alchemy.com',
+ [Network.OPTIMISM_SEPOLIA]: 'opt-sepolia.g.alchemy.com',
+ [Network.ASTAR_MAINNET]: 'astar-mainnet.g.alchemy.com',
+ [Network.WORLD_CHAIN_MAINNET]: 'worldchain-mainnet.g.alchemy.com',
+ [Network.WORLD_CHAIN_SEPOLIA]: 'worldchain-sepolia.g.alchemy.com',
+ [Network.SHAPE_MAINNET]: 'shape-mainnet.g.alchemy.com',
+ [Network.SHAPE_SEPOLIA]: 'shape-sepolia.g.alchemy.com',
+ [Network.ZKSYNC_MAINNET]: 'zksync-mainnet.g.alchemy.com',
+ [Network.ZKSYNC_SEPOLIA]: 'zksync-sepolia.g.alchemy.com',
+ [Network.STARKNET_MAINNET]: 'starknet-mainnet.g.alchemy.com',
+ [Network.STARKNET_SEPOLIA]: 'starknet-sepolia.g.alchemy.com',
+ [Network.ZETACHAIN_MAINNET]: 'zetachain-mainnet.g.alchemy.com',
+ [Network.ZETACHAIN_TESTNET]: 'zetachain-testnet.g.alchemy.com',
+ [Network.FANTOM_OPERA_MAINNET]: 'fantom-mainnet.g.alchemy.com',
+ [Network.FANTOM_OPERA_TESTNET]: 'fantom-testnet.g.alchemy.com',
+ [Network.MANTLE_MAINNET]: 'mantle-mainnet.g.alchemy.com',
+ [Network.BERACHAIN_ARTIO]: 'berachain-artio.g.alchemy.com',
+ [Network.BLAST_MAINNET]: 'blast-mainnet.g.alchemy.com',
+ [Network.BLAST_SEPOLIA]: 'blast-sepolia.g.alchemy.com',
+ [Network.LINEA_MAINNET]: 'linea-mainnet.g.alchemy.com',
+ [Network.LINEA_SEPOLIA]: 'linea-sepolia.g.alchemy.com',
+ [Network.ZORA_MAINNET]: 'zora-mainnet.g.alchemy.com',
+ [Network.ZORA_SEPOLIA]: 'zora-sepolia.g.alchemy.com',
+ [Network.POLYNOMIAL_MAINNET]: 'polynomial-mainnet.g.alchemy.com',
+ [Network.POLYNOMIAL_SEPOLIA]: 'polynomial-sepolia.g.alchemy.com',
+ [Network.SCROLL_MAINNET]: 'scroll-mainnet.g.alchemy.com',
+ [Network.SCROLL_SEPOLIA]: 'scroll-sepolia.g.alchemy.com',
+ [Network.FRAX_MAINNET]: 'frax-mainnet.g.alchemy.com',
+ [Network.FRAX_SEPOLIA]: 'frax-sepolia.g.alchemy.com',
+ [Network.SOLANA_MAINNET]: 'solana-mainnet.g.alchemy.com',
+ [Network.SOLANA_DEVNET]: 'solana-devnet.g.alchemy.com',
+ [Network.CROSSFI_TESTNET]: 'crossfi-testnet.g.alchemy.com',
+ [Network.FLOW_EVM_TESTNET]: 'flow-testnet.g.alchemy.com',
+ [Network.SONEIUM_MINATO]: 'soneium-minato.g.alchemy.com',
+ [Network.GEIST_POLTER]: 'geist-polter.g.alchemy.com',
+ [Network.ROOTSTOCK_MAINNET]: 'rootstock-mainnet.g.alchemy.com',
+ [Network.ROOTSTOCK_TESTNET]: 'rootstock-testnet.g.alchemy.com',
+ [Network.UNICHAIN_SEPOLIA]: 'unichain-sepolia.g.alchemy.com',
+ [Network.GNOSIS_MAINNET]: 'gnosis-mainnet.g.alchemy.com',
+ [Network.BNB_MAINNET]: 'bnb-mainnet.g.alchemy.com',
+ [Network.BNB_TESTNET]: 'bnb-testnet.g.alchemy.com',
+ [Network.OPBNB_MAINNET]: 'opbnb-mainnet.g.alchemy.com',
+ [Network.OPBNB_TESTNET]: 'opbnb-testnet.g.alchemy.com',
+ };
+
+ // eslint-disable-next-line class-methods-use-this
+ public getRPCURL(network: Network, transport: Transport, _token: string, _host: string) {
+ const host = AlchemyProvider.networkStringMap[network] || '';
+ const token = isValid(_token) ? _token : `alchemy-${network.toLowerCase()}-token`;
+
+ if (!host) {
+ throw new Error('Network info not available.');
+ }
+
+ return `${transport}://${host}/v2/${token}`;
+ }
+}
diff --git a/packages/web3/test/integration/web3RPCProviders.test.ts b/packages/web3/test/integration/web3RPCProviders.test.ts
index 6e6d2994f9c..d192a54cd88 100644
--- a/packages/web3/test/integration/web3RPCProviders.test.ts
+++ b/packages/web3/test/integration/web3RPCProviders.test.ts
@@ -21,12 +21,13 @@ import {
QuickNodeProvider,
Transport,
PublicNodeProvider,
+ AlchemyProvider,
} from 'web3-rpc-providers';
import { Web3 } from '../../src/index';
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 +40,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);
@@ -53,6 +54,81 @@ describe('Web3 RPC Provider Integration tests', () => {
}
});
});
+
+ const alchemyNetworks = [
+ Network.ETH_MAINNET,
+ Network.ETH_SEPOLIA,
+ Network.ETH_HOLESKY,
+ Network.ARBITRUM_MAINNET,
+ Network.ARBITRUM_SEPOLIA,
+ Network.ARBITRUM_NOVA_MAINNET,
+ Network.BASE_MAINNET,
+ Network.BASE_SEPOLIA,
+ Network.POLYGON_MAINNET,
+ Network.POLYGON_MUMBAI,
+ Network.POLYGON_AMOY,
+ Network.POLYGON_POS_MAINNET,
+ Network.POLYGON_ZKEVM_MAINNET,
+ Network.POLYGON_ZKEVM_CARDONA,
+ Network.OPTIMISM_MAINNET,
+ Network.OPTIMISM_SEPOLIA,
+ Network.ASTAR_MAINNET,
+ Network.WORLD_CHAIN_MAINNET,
+ Network.WORLD_CHAIN_SEPOLIA,
+ Network.SHAPE_MAINNET,
+ Network.SHAPE_SEPOLIA,
+ Network.ZKSYNC_MAINNET,
+ Network.ZKSYNC_SEPOLIA,
+ Network.STARKNET_MAINNET,
+ Network.STARKNET_SEPOLIA,
+ Network.ZETACHAIN_MAINNET,
+ Network.ZETACHAIN_TESTNET,
+ Network.FANTOM_OPERA_MAINNET,
+ Network.FANTOM_OPERA_TESTNET,
+ Network.MANTLE_MAINNET,
+ Network.BERACHAIN_ARTIO,
+ Network.BLAST_MAINNET,
+ Network.BLAST_SEPOLIA,
+ Network.LINEA_MAINNET,
+ Network.LINEA_SEPOLIA,
+ Network.ZORA_MAINNET,
+ Network.ZORA_SEPOLIA,
+ Network.POLYNOMIAL_MAINNET,
+ Network.POLYNOMIAL_SEPOLIA,
+ Network.SCROLL_MAINNET,
+ Network.SCROLL_SEPOLIA,
+ Network.FRAX_MAINNET,
+ Network.FRAX_SEPOLIA,
+ Network.SOLANA_MAINNET,
+ Network.SOLANA_DEVNET,
+ Network.CROSSFI_TESTNET,
+ Network.FLOW_EVM_TESTNET,
+ Network.SONEIUM_MINATO,
+ Network.GEIST_POLTER,
+ Network.ROOTSTOCK_MAINNET,
+ Network.ROOTSTOCK_TESTNET,
+ Network.UNICHAIN_SEPOLIA,
+ Network.GNOSIS_MAINNET,
+ Network.BNB_MAINNET,
+ Network.BNB_TESTNET,
+ Network.OPBNB_MAINNET,
+ Network.OPBNB_TESTNET,
+ ];
+
+ alchemyNetworks.forEach(network => {
+ it(`AlchemyProvider should work with ${transport} transport and ${network} network`, async () => {
+ const provider = new AlchemyProvider(network, transport);
+ const web3 = new Web3(provider);
+ const result = await web3.eth.getBlockNumber();
+
+ expect(typeof result).toBe('bigint');
+ expect(result > 0).toBe(true);
+
+ if (transport === Transport.WebSocket) {
+ web3.provider?.disconnect();
+ }
+ });
+ });
});
const publicNodeNetworks = [