foundry_evm_traces/identifier/
mod.rsuse alloy_json_abi::JsonAbi;
use alloy_primitives::Address;
use foundry_common::ContractsByArtifact;
use foundry_compilers::ArtifactId;
use foundry_config::{Chain, Config};
use std::borrow::Cow;
mod local;
pub use local::LocalTraceIdentifier;
mod etherscan;
pub use etherscan::EtherscanIdentifier;
mod signatures;
pub use signatures::{SignaturesIdentifier, SingleSignaturesIdentifier};
pub struct AddressIdentity<'a> {
pub address: Address,
pub label: Option<String>,
pub contract: Option<String>,
pub abi: Option<Cow<'a, JsonAbi>>,
pub artifact_id: Option<ArtifactId>,
}
pub trait TraceIdentifier {
fn identify_addresses<'a, A>(&mut self, addresses: A) -> Vec<AddressIdentity<'_>>
where
A: Iterator<Item = (&'a Address, Option<&'a [u8]>, Option<&'a [u8]>)> + Clone;
}
pub struct TraceIdentifiers<'a> {
pub local: Option<LocalTraceIdentifier<'a>>,
pub etherscan: Option<EtherscanIdentifier>,
}
impl Default for TraceIdentifiers<'_> {
fn default() -> Self {
Self::new()
}
}
impl TraceIdentifier for TraceIdentifiers<'_> {
fn identify_addresses<'a, A>(&mut self, addresses: A) -> Vec<AddressIdentity<'_>>
where
A: Iterator<Item = (&'a Address, Option<&'a [u8]>, Option<&'a [u8]>)> + Clone,
{
let mut identities = Vec::new();
if let Some(local) = &mut self.local {
identities.extend(local.identify_addresses(addresses.clone()));
}
if let Some(etherscan) = &mut self.etherscan {
identities.extend(etherscan.identify_addresses(addresses));
}
identities
}
}
impl<'a> TraceIdentifiers<'a> {
pub const fn new() -> Self {
Self { local: None, etherscan: None }
}
pub fn with_local(mut self, known_contracts: &'a ContractsByArtifact) -> Self {
self.local = Some(LocalTraceIdentifier::new(known_contracts));
self
}
pub fn with_etherscan(mut self, config: &Config, chain: Option<Chain>) -> eyre::Result<Self> {
self.etherscan = EtherscanIdentifier::new(config, chain)?;
Ok(self)
}
pub fn is_empty(&self) -> bool {
self.local.is_none() && self.etherscan.is_none()
}
}