cargo_tangle/command/run/
tangle.rs1use alloy_signer_local::PrivateKeySigner;
2use blueprint_crypto::tangle_pair_signer::TanglePairSigner;
3use blueprint_manager::config::BlueprintManagerConfig;
4use blueprint_manager::executor::run_blueprint_manager;
5use blueprint_runner::config::BlueprintEnvironment;
6use color_eyre::eyre::{Result, eyre};
7use dialoguer::console::style;
8use indicatif::{ProgressBar, ProgressStyle};
9use sp_core::sr25519;
10use std::path::PathBuf;
11use std::time::Duration;
12use tokio::signal;
13
14#[derive(Clone)]
15pub struct RunOpts {
16 pub http_rpc_url: String,
18 pub ws_rpc_url: String,
20 pub signer: Option<TanglePairSigner<sr25519::Pair>>,
22 pub signer_evm: Option<PrivateKeySigner>,
24 pub blueprint_id: Option<u64>,
26 pub keystore_path: Option<String>,
28 pub data_dir: Option<PathBuf>,
30}
31
32#[allow(clippy::missing_panics_doc)]
45pub async fn run_blueprint(opts: RunOpts) -> Result<()> {
46 let blueprint_id = opts
47 .blueprint_id
48 .ok_or_else(|| eyre!("Blueprint ID is required"))?;
49
50 let mut gadget_config = BlueprintEnvironment::default();
51 gadget_config.http_rpc_endpoint = opts.http_rpc_url.clone();
52 gadget_config.ws_rpc_endpoint = opts.ws_rpc_url.clone();
53
54 if let Some(keystore_path) = opts.keystore_path {
55 gadget_config.keystore_uri = keystore_path;
56 }
57
58 gadget_config.data_dir = opts.data_dir;
59
60 let blueprint_manager_config = BlueprintManagerConfig {
61 gadget_config: None,
62 keystore_uri: gadget_config.keystore_uri.clone(),
63 data_dir: gadget_config
64 .data_dir
65 .clone()
66 .unwrap_or_else(|| PathBuf::from("./data")),
67 verbose: 2,
68 pretty: true,
69 instance_id: Some(format!("Blueprint-{}", blueprint_id)),
70 test_mode: false,
71 };
72
73 println!(
74 "{}",
75 style(format!(
76 "Starting blueprint manager for blueprint ID: {}",
77 blueprint_id
78 ))
79 .cyan()
80 .bold()
81 );
82
83 let shutdown_signal = async move {
84 let _ = signal::ctrl_c().await;
85 println!(
86 "{}",
87 style("Received shutdown signal, stopping blueprint manager")
88 .yellow()
89 .bold()
90 );
91 };
92
93 println!(
94 "{}",
95 style("Preparing Blueprint to run, this may take a few minutes...").cyan()
96 );
97
98 let pb = ProgressBar::new_spinner();
99 pb.set_style(
100 ProgressStyle::default_spinner()
101 .tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ")
102 .template("{spinner:.blue} {msg}")
103 .unwrap(),
104 );
105 pb.set_message("Initializing Blueprint");
106 pb.enable_steady_tick(Duration::from_millis(100));
107
108 let mut handle =
109 run_blueprint_manager(blueprint_manager_config, gadget_config, shutdown_signal).await?;
110
111 pb.finish_with_message("Blueprint initialized successfully!");
112
113 println!(
114 "{}",
115 style("Starting blueprint execution...").green().bold()
116 );
117 handle.start()?;
118
119 println!(
120 "{}",
121 style("Blueprint is running. Press Ctrl+C to stop.").cyan()
122 );
123 handle.await?;
124
125 println!("{}", style("Blueprint manager has stopped").green());
126 Ok(())
127}