eth_tx_manager/
config.rs

1use clap::Parser;
2use std::fmt::Debug;
3
4use crate::Chain;
5
6#[derive(Clone, Parser)]
7#[command(name = "tx_config")]
8#[command(about = "Configuration for transaction manager")]
9pub struct TxEnvCLIConfig {
10    /// Blockchain provider http endpoint url
11    #[arg(long, env)]
12    pub tx_provider_http_endpoint: Option<String>,
13
14    /// Chain ID
15    #[arg(long, env)]
16    pub tx_chain_id: Option<u64>,
17
18    /// EIP1559 flag
19    #[arg(long, env)]
20    pub tx_chain_is_legacy: Option<bool>,
21
22    /// Path to tx-manager database file
23    #[arg(long, env)]
24    pub tx_database_path: Option<String>,
25
26    /// Ethereum gas station oracle api key
27    #[arg(long, env)]
28    pub tx_gas_oracle_api_key: Option<String>,
29
30    /// Default confirmations
31    #[arg(long, env)]
32    pub tx_default_confirmations: Option<usize>,
33}
34
35#[derive(Clone)]
36pub struct TxManagerConfig {
37    pub default_confirmations: usize,
38    pub provider_http_endpoint: String,
39    pub chain_id: u64,
40    pub chain_is_legacy: bool,
41    pub database_path: String,
42    pub gas_oracle_api_key: String,
43}
44
45impl Debug for TxManagerConfig {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        f.debug_struct("TxManagerConfig")
48            .field("default_confirmations", &self.default_confirmations)
49            .field("provider_http_endpoint", &self.provider_http_endpoint)
50            .field("chain_id", &self.chain_id)
51            .field("chain_is_legacy", &self.chain_is_legacy)
52            .field("database_path", &self.database_path)
53            .field("gas_oracle_api_key", &self.gas_oracle_api_key)
54            .finish()
55    }
56}
57
58#[derive(Debug, thiserror::Error)]
59pub enum Error {
60    #[error("Configuration missing chain_id")]
61    MissingChainId,
62}
63
64pub type Result<T> = std::result::Result<T, Error>;
65
66const DEFAULT_DEFAULT_CONFIRMATIONS: usize = 7;
67const DEFAULT_HTTP_ENDPOINT: &str = "http://localhost:8545";
68const DEFAULT_DATABASE_PATH: &str = "./default_tx_database";
69const DEFAULT_GAS_ORACLE_API_KEY: &str = "";
70
71impl TxManagerConfig {
72    pub fn initialize_from_args() -> Result<Self> {
73        let env_cli_config = TxEnvCLIConfig::parse();
74        Self::initialize(env_cli_config)
75    }
76
77    pub fn initialize(env_cli_config: TxEnvCLIConfig) -> Result<Self> {
78        let default_confirmations = env_cli_config
79            .tx_default_confirmations
80            .unwrap_or(DEFAULT_DEFAULT_CONFIRMATIONS);
81
82        let provider_http_endpoint = env_cli_config
83            .tx_provider_http_endpoint
84            .unwrap_or_else(|| DEFAULT_HTTP_ENDPOINT.to_string());
85
86        let chain_id = env_cli_config.tx_chain_id.ok_or(Error::MissingChainId)?;
87        let chain_is_legacy = env_cli_config.tx_chain_is_legacy.unwrap_or(false);
88
89        let database_path = env_cli_config
90            .tx_database_path
91            .unwrap_or_else(|| DEFAULT_DATABASE_PATH.to_string());
92
93        let gas_oracle_api_key = env_cli_config
94            .tx_gas_oracle_api_key
95            .unwrap_or_else(|| DEFAULT_GAS_ORACLE_API_KEY.to_string());
96
97        Ok(Self {
98            default_confirmations,
99            provider_http_endpoint,
100            chain_id,
101            chain_is_legacy,
102            database_path,
103            gas_oracle_api_key,
104        })
105    }
106}
107
108impl From<&TxManagerConfig> for Chain {
109    fn from(config: &TxManagerConfig) -> Self {
110        Self {
111            id: config.chain_id,
112            is_legacy: config.chain_is_legacy,
113        }
114    }
115}