Skip to content

Commit 3b7bac3

Browse files
committed
feat: Refactor ABI fetching to use a unified Etherscan v2 API and enhance transaction prompts with detailed, safety-focused instructions.
1 parent 1e1d879 commit 3b7bac3

1 file changed

Lines changed: 14 additions & 23 deletions

File tree

src/core/services/abi.ts

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { type Address } from 'viem';
2+
import { resolveChainId, getSupportedNetworks } from '../chains.js';
23

34
/**
4-
* Fetch contract ABI from Etherscan API
5+
* Fetch contract ABI from Etherscan v2 API (unified endpoint for all EVM chains)
56
* Requires ETHERSCAN_API_KEY environment variable to be set
67
*
78
* @param contractAddress The contract address to fetch ABI for
8-
* @param network The network to use (etherscan, polygonscan, etc.)
9+
* @param network The network name or chain ID
910
* @returns The contract ABI as a JSON string
1011
*/
1112
export async function fetchContractABI(
@@ -14,35 +15,25 @@ export async function fetchContractABI(
1415
): Promise<string> {
1516
const apiKey = process.env.ETHERSCAN_API_KEY;
1617
if (!apiKey) {
17-
throw new Error('ETHERSCAN_API_KEY environment variable is not set. Set it to fetch contract ABIs.');
18+
throw new Error('ETHERSCAN_API_KEY environment variable is not set. Set it to fetch contract ABIs from block explorers.');
1819
}
1920

20-
// Map network names to Etherscan-compatible API domains
21-
const networkMap: { [key: string]: string } = {
22-
'ethereum': 'https://api.etherscan.io',
23-
'sepolia': 'https://api-sepolia.etherscan.io',
24-
'polygon': 'https://api.polygonscan.com',
25-
'mumbai': 'https://api-testnet.polygonscan.com',
26-
'arbitrum': 'https://api.arbiscan.io',
27-
'arbitrum-sepolia': 'https://api-sepolia.arbiscan.io',
28-
'optimism': 'https://api-optimistic.etherscan.io',
29-
'optimism-sepolia': 'https://api-sepolia-optimistic.etherscan.io',
30-
'base': 'https://api.basescan.org',
31-
'base-sepolia': 'https://api-sepolia.basescan.org',
32-
'avalanche': 'https://api.snowtrace.io',
33-
'avalanche-fuji': 'https://api-testnet.snowtrace.io',
34-
};
35-
36-
const apiUrl = networkMap[network.toLowerCase()];
37-
if (!apiUrl) {
38-
throw new Error(`Network "${network}" is not supported for ABI fetching. Supported: ${Object.keys(networkMap).join(', ')}`);
21+
// Resolve chain ID using the chains.ts utilities
22+
let chainId: number;
23+
try {
24+
chainId = resolveChainId(network);
25+
} catch (error) {
26+
const supported = getSupportedNetworks();
27+
throw new Error(`Network "${network}" is not supported. Supported: ${supported.join(', ')}`);
3928
}
4029

4130
try {
42-
const url = new URL(`${apiUrl}/api`);
31+
// Use unified Etherscan v2 API endpoint
32+
const url = new URL('https://api.etherscan.io/v2/api');
4333
url.searchParams.set('module', 'contract');
4434
url.searchParams.set('action', 'getabi');
4535
url.searchParams.set('address', contractAddress);
36+
url.searchParams.set('chainid', chainId.toString());
4637
url.searchParams.set('apikey', apiKey);
4738

4839
const response = await fetch(url.toString());

0 commit comments

Comments
 (0)