Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ build/

# Finder (MacOS) folder config
.DS_Store

# Env files
.env
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ The mnemonic option supports hierarchical deterministic (HD) wallet derivation:
- Store mnemonics securely - they provide access to all derived accounts
- Consider using different account indices for different purposes


#### Alchemy configuration

```bash
export ALCHEMY_API_KEY="your-alchemy-api-key-here"
```

If you use [Alchemy](https://alchemy.com) and want to use its RPC endpoints, you can specify app's API key.
Otherwise, default JSON RPC rate-limited endpoints will be used.

#### API Keys (For ABI Fetching)

```bash
Expand Down
96 changes: 96 additions & 0 deletions src/core/alchemy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Alchemy RPC URL mapping by chain
// Reference: https://www.alchemy.com/docs/reference/node-supported-chains

import {
mainnet,
optimism,
arbitrum,
arbitrumNova,
base,
polygon,
polygonZkEvm,
avalanche,
bsc,
zksync,
linea,
celo,
scroll,
mantle,
blast,
metis,
moonbeam,
flowMainnet,
sepolia,
holesky,
optimismSepolia,
arbitrumSepolia,
baseSepolia,
polygonAmoy,
avalancheFuji,
bscTestnet,
zksyncSepoliaTestnet,
lineaSepolia,
celoAlfajores,
scrollSepolia,
mantleSepoliaTestnet,
blastSepolia,
metisSepolia,
flowTestnet,
type Chain,
} from 'viem/chains';

export const alchemyNetworkMap = new Map<Chain, string>([
// Mainnets
[mainnet, 'eth-mainnet'],
[optimism, 'opt-mainnet'],
[arbitrum, 'arb-mainnet'],
[arbitrumNova, 'arbnova-mainnet'],
[base, 'base-mainnet'],
[polygon, 'polygon-mainnet'],
[polygonZkEvm, 'polygonzkevm-mainnet'],
[avalanche, 'avax-mainnet'],
[bsc, 'bnb-mainnet'],
[zksync, 'zksync-mainnet'],
[linea, 'linea-mainnet'],
[celo, 'celo-mainnet'],
[scroll, 'scroll-mainnet'],
[mantle, 'mantle-mainnet'],
[blast, 'blast-mainnet'],
[metis, 'metis-mainnet'],
[moonbeam, 'moonbeam-mainnet'],
[flowMainnet, 'flow-mainnet'],

// Testnets
[sepolia, 'eth-sepolia'],
[holesky, 'eth-holesky'],
[optimismSepolia, 'opt-sepolia'],
[arbitrumSepolia, 'arb-sepolia'],
[baseSepolia, 'base-sepolia'],
[polygonAmoy, 'polygon-amoy'],
[avalancheFuji, 'avax-fuji'],
[bscTestnet, 'bnb-testnet'],
[zksyncSepoliaTestnet, 'zksync-sepolia'],
[lineaSepolia, 'linea-sepolia'],
[celoAlfajores, 'celo-alfajores'],
[scrollSepolia, 'scroll-sepolia'],
[mantleSepoliaTestnet, 'mantle-sepolia'],
[blastSepolia, 'blast-sepolia'],
[metisSepolia, 'metis-sepolia'],
[flowTestnet, 'flow-testnet'],
]);

const alchemyNetworkByChainId: Record<number, string> = Object.fromEntries(
[...alchemyNetworkMap.entries()].map(([chain, network]) => [chain.id, network])
);

export function getAlchemyRpcUrl(chainId: number, apiKey: string): string | null {
const network = alchemyNetworkByChainId[chainId];
if (!network) {
return null;
}
return `https://${network}.g.alchemy.com/v2/${apiKey}`;
}

export function isAlchemySupported(chainId: number): boolean {
return chainId in alchemyNetworkByChainId;
}
10 changes: 9 additions & 1 deletion src/core/chains.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Chain } from 'viem';
import { getAlchemyRpcUrl } from './alchemy.js';
import {
// Mainnets
mainnet,
Expand Down Expand Up @@ -342,7 +343,14 @@ export function getRpcUrl(chainIdentifier: number | string = DEFAULT_CHAIN_ID):
const chainId = typeof chainIdentifier === 'string'
? resolveChainId(chainIdentifier)
: chainIdentifier;


if (process.env.ALCHEMY_API_KEY) {
const alchemyUrl = getAlchemyRpcUrl(chainId, process.env.ALCHEMY_API_KEY);
if (alchemyUrl) {
return alchemyUrl;
}
}

return rpcUrlMap[chainId] || DEFAULT_RPC_URL;
}

Expand Down