foundry_test_utils/
etherscan.rs1use alloy_chains::Chain;
4use alloy_primitives::Address;
5use eyre::Result;
6use foundry_block_explorers::Client;
7use foundry_common::{compile::etherscan_project, flatten};
8use std::str::FromStr;
9
10pub async fn fetch_etherscan_source_flattened(
15 address: &str,
16 etherscan_api_key: &str,
17 chain: Chain,
18) -> Result<String> {
19 let client = Client::builder().chain(chain)?.with_api_key(etherscan_api_key).build()?;
20
21 let address = Address::from_str(address)?;
22 let metadata = client.contract_source_code(address).await?;
23 let Some(metadata) = metadata.items.first() else {
24 eyre::bail!("Empty contract source code for {address}")
25 };
26
27 let tmp = tempfile::tempdir()?;
28 let project = etherscan_project(metadata, tmp.path())?;
29 let target_path = project.find_contract_path(&metadata.contract_name)?;
30
31 flatten(project, &target_path)
32}