cargo_tangle/command/run/
eigenlayer.rs1use blueprint_runner::config::{BlueprintEnvironment, SupportedChains};
2use blueprint_std::fs;
3use blueprint_std::path::PathBuf;
4use color_eyre::eyre::{Result, eyre};
5use tokio::io::AsyncBufReadExt;
6use tokio::io::BufReader;
7use tokio::process::{Child, Command};
8use toml::Value;
9use tracing::info;
10
11fn get_binary_name() -> Result<String> {
12 let cargo_toml = fs::read_to_string("Cargo.toml")?;
13 let cargo_data: Value = toml::from_str(&cargo_toml)?;
14
15 if let Some(Value::Array(bins)) = cargo_data.get("bin") {
17 if let Some(first_bin) = bins.first() {
18 if let Some(name) = first_bin.get("name").and_then(|n| n.as_str()) {
19 return Ok(name.to_string());
20 }
21 }
22 }
23
24 if let Some(package) = cargo_data.get("package") {
26 if let Some(name) = package.get("name").and_then(|n| n.as_str()) {
27 return Ok(name.to_string());
28 }
29 }
30
31 Err(eyre!("Could not find binary name in Cargo.toml"))
32}
33
34#[allow(clippy::missing_panics_doc)]
41pub async fn run_eigenlayer_avs(
42 config: BlueprintEnvironment,
43 chain: SupportedChains,
44 binary_path: Option<PathBuf>,
45) -> Result<Child> {
46 let binary_path = if let Some(path) = binary_path {
47 path
48 } else {
49 let target_dir = PathBuf::from("./target/release");
50 let binary_name = get_binary_name()?;
51 target_dir.join(&binary_name)
52 };
53
54 println!(
55 "Attempting to run Eigenlayer AVS binary at: {}",
56 binary_path.display()
57 );
58
59 if !binary_path.exists() {
61 info!("Binary not found at {}, building...", binary_path.display());
62 let status = Command::new("cargo")
63 .arg("build")
64 .arg("--release")
65 .status()
66 .await?;
67
68 if !status.success() {
69 return Err(eyre!("Failed to build AVS binary"));
70 }
71 }
72
73 let contract_addresses = config
75 .protocol_settings
76 .eigenlayer()
77 .map_err(|_| eyre!("Missing Eigenlayer contract addresses"))?;
78
79 println!("Starting AVS...");
81 let mut command = Command::new(&binary_path);
82
83 command.arg("run");
85
86 command
88 .arg("--http-rpc-url")
89 .arg(&config.http_rpc_endpoint)
90 .arg("--ws-rpc-url")
91 .arg(&config.ws_rpc_endpoint)
92 .arg("--keystore-uri")
93 .arg(&config.keystore_uri)
94 .arg("--chain")
95 .arg(chain.to_string())
96 .arg("--protocol")
97 .arg("eigenlayer");
98
99 command
107 .arg("--registry-coordinator")
108 .arg(contract_addresses.registry_coordinator_address.to_string())
109 .arg("--operator-state-retriever")
110 .arg(
111 contract_addresses
112 .operator_state_retriever_address
113 .to_string(),
114 )
115 .arg("--delegation-manager")
116 .arg(contract_addresses.delegation_manager_address.to_string())
117 .arg("--strategy-manager")
118 .arg(contract_addresses.strategy_manager_address.to_string())
119 .arg("--service-manager")
120 .arg(contract_addresses.service_manager_address.to_string())
121 .arg("--stake-registry")
122 .arg(contract_addresses.stake_registry_address.to_string())
123 .arg("--avs-directory")
124 .arg(contract_addresses.avs_directory_address.to_string())
125 .arg("--rewards-coordinator")
126 .arg(contract_addresses.rewards_coordinator_address.to_string())
127 .arg("--allocation-manager")
128 .arg(contract_addresses.allocation_manager_address.to_string())
129 .arg("--permission-controller")
130 .arg(contract_addresses.permission_controller_address.to_string())
131 .arg("--strategy")
132 .arg(contract_addresses.strategy_address.to_string());
133
134 assert!(binary_path.exists(), "Binary path does not exist");
135
136 let mut child = command
137 .stdout(std::process::Stdio::piped())
138 .stderr(std::process::Stdio::piped())
139 .spawn()?;
140
141 let stdout = child.stdout.take().expect("Failed to capture stdout");
143 let mut stdout_reader = BufReader::new(stdout).lines();
144
145 let stderr = child.stderr.take().expect("Failed to capture stderr");
147 let mut stderr_reader = BufReader::new(stderr).lines();
148
149 let stdout_task = tokio::spawn(async move {
151 while let Some(line) = stdout_reader
152 .next_line()
153 .await
154 .expect("Failed to read stdout")
155 {
156 println!("{}", line);
157 }
158 });
159
160 let stderr_task = tokio::spawn(async move {
161 while let Some(line) = stderr_reader
162 .next_line()
163 .await
164 .expect("Failed to read stderr")
165 {
166 eprintln!("{}", line);
167 }
168 });
169
170 let _ = tokio::join!(stdout_task, stderr_task);
172
173 println!(
174 "AVS is running with PID: {}",
175 child.id().unwrap_or_default()
176 );
177 Ok(child)
178}