tycho_simulation/evm/engine_db/
utils.rs1use std::{env, sync::Arc};
2
3use alloy::providers::ProviderBuilder;
4use dotenv::dotenv;
5use tokio::runtime::Runtime;
6use tycho_common::simulation::errors::SimulationError;
7
8use crate::evm::engine_db::simulation_db::EVMProvider;
9
10pub fn get_runtime() -> Result<Option<Arc<Runtime>>, SimulationError> {
11 if tokio::runtime::Handle::try_current().is_ok() {
12 Err(SimulationError::FatalError(
13 "A Tokio runtime is already running in this context".to_string(),
14 ))?;
15 }
16
17 Runtime::new()
18 .map(|runtime| Some(Arc::new(runtime)))
19 .map_err(|err| {
20 SimulationError::FatalError(format!("Failed to create Tokio runtime: {err}"))
21 })
22}
23
24pub fn get_client(rpc_url: Option<String>) -> Result<Arc<EVMProvider>, SimulationError> {
25 let runtime = get_runtime()?.ok_or(SimulationError::FatalError(
26 "A Tokio runtime is required to create the EVM client".to_string(),
27 ))?;
28
29 let url = rpc_url
30 .or_else(|| env::var("RPC_URL").ok())
31 .or_else(|| {
32 dotenv().ok()?;
33 env::var("RPC_URL").ok()
34 })
35 .ok_or_else(|| {
36 SimulationError::FatalError(
37 "Please provide RPC_URL environment variable or add it to .env file.".to_string(),
38 )
39 })?;
40
41 let connect_future = async {
42 ProviderBuilder::new()
43 .connect(&url)
44 .await
45 .map_err(|err| {
46 SimulationError::RecoverableError(format!(
47 "Failed to connect to RPC `{url}`: {err}"
48 ))
49 })
50 };
51
52 let client = runtime.block_on(connect_future)?;
53
54 Ok(Arc::new(client))
55}