mod config;
mod decoder;
mod etherscan;
mod renderer;
mod signatures;
use config::TraceConfig;
use decoder::CallTraceDecoder;
use renderer::render_trace_arena;
use revm_inspectors::tracing::CallTraceArena;
pub use signatures::SignaturesIdentifier;
type Traces = Vec<CallTraceArena>;
#[derive(Debug, Clone)]
pub(crate) struct TraceResult {
pub success: bool,
pub traces: Option<Traces>,
pub gas_used: u64,
}
pub(crate) async fn handle_traces(
mut result: TraceResult,
etherscan_api_key: Option<String>,
chain: tycho_common::models::Chain,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let offline = etherscan_api_key.is_none();
let trace_config = TraceConfig::new(chain)
.with_etherscan_api_key(etherscan_api_key.unwrap_or_default())
.with_offline(offline);
let mut decoder = CallTraceDecoder::with_config(&trace_config).await?;
if let Some(traces) = result.traces.as_mut() {
for arena in traces {
decoder.decode_arena(arena).await?;
}
}
print_traces(&mut result, &decoder).await?;
Ok(())
}
async fn print_traces(
result: &mut TraceResult,
_decoder: &CallTraceDecoder, ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let traces = result
.traces
.as_ref()
.ok_or_else(|| std::io::Error::other("No traces found"))?;
println!("Traces:");
for arena in traces {
let rendered = render_trace_arena(arena);
println!("{}", rendered);
}
println!();
if result.success {
println!("Transaction successfully executed.");
} else {
println!("Transaction failed.");
}
println!("Gas used: {gas}", gas = result.gas_used);
Ok(())
}