1use clap::CommandFactory;
2use dotenvy::dotenv;
3use tracing_subscriber::{fmt, EnvFilter};
4
5use crate::commands::contract::arg_parsing::Error::HelpMessage;
6use crate::commands::contract::deploy::wasm::Error::ArgParse;
7use crate::commands::contract::invoke::Error::ArgParsing;
8use crate::commands::contract::Error::{Deploy, Invoke};
9use crate::commands::Error::Contract;
10use crate::config::Config;
11use crate::print::Print;
12use crate::upgrade_check::upgrade_check;
13use crate::{commands, env_vars, Root};
14use std::error::Error;
15
16#[tokio::main]
17pub async fn main() {
18 let _ = dotenv().unwrap_or_default();
19
20 let mut vars = env_vars::unprefixed();
24
25 vars.push("SECRET_KEY");
27
28 for var in vars {
29 let soroban_key = format!("SOROBAN_{var}");
30 let stellar_key = format!("STELLAR_{var}");
31 if let Ok(val) = std::env::var(soroban_key) {
32 std::env::set_var(stellar_key, val);
33 }
34 }
35
36 set_env_from_config();
37
38 let mut root = Root::new().unwrap_or_else(|e| match e {
39 commands::Error::Clap(e) => {
40 let mut cmd = Root::command();
41 e.format(&mut cmd).exit();
42 }
43 e => {
44 eprintln!("{e}");
45 std::process::exit(1);
46 }
47 });
48
49 if let Some(level) = root.global_args.log_level() {
51 let mut e_filter = EnvFilter::from_default_env()
52 .add_directive("hyper=off".parse().unwrap())
53 .add_directive(format!("stellar_cli={level}").parse().unwrap())
54 .add_directive("stellar_rpc_client=off".parse().unwrap())
55 .add_directive(format!("soroban_cli={level}").parse().unwrap());
56
57 for filter in &root.global_args.filter_logs {
58 e_filter = e_filter.add_directive(
59 filter
60 .parse()
61 .map_err(|e| {
62 eprintln!("{e}: {filter}");
63 std::process::exit(1);
64 })
65 .unwrap(),
66 );
67 }
68
69 let builder = fmt::Subscriber::builder()
70 .with_env_filter(e_filter)
71 .with_ansi(false)
72 .with_writer(std::io::stderr);
73
74 let subscriber = builder.finish();
75 tracing::subscriber::set_global_default(subscriber)
76 .expect("Failed to set the global tracing subscriber");
77 }
78
79 tokio::spawn(async move {
83 upgrade_check(root.global_args.quiet).await;
84 });
85
86 let printer = Print::new(root.global_args.quiet);
87 if let Err(e) = root.run().await {
88 let _source = commands::Error::source(&e);
90 if let Contract(Invoke(ArgParsing(HelpMessage(help)))) = e {
92 println!("{help}");
93 std::process::exit(1);
94 }
95 if let Contract(Deploy(ArgParse(HelpMessage(help)))) = e {
96 println!("{help}");
97 std::process::exit(1);
98 }
99 printer.errorln(format!("error: {e}"));
100 std::process::exit(1);
101 }
102}
103
104fn set_env_from_config() {
106 if let Ok(config) = Config::new() {
107 set_env_value_from_config("STELLAR_ACCOUNT", config.defaults.identity);
108 set_env_value_from_config("STELLAR_NETWORK", config.defaults.network);
109 }
110}
111
112fn set_env_value_from_config(name: &str, value: Option<String>) {
116 let Some(value) = value else {
117 return;
118 };
119
120 std::env::remove_var(format!("{name}_SOURCE"));
121
122 if std::env::var(name).is_err() {
123 std::env::set_var(name, value);
124 std::env::set_var(format!("{name}_SOURCE"), "use");
125 }
126}