11use crate :: domain:: primitives:: Address ;
22use crate :: presentation:: server;
3- use clap:: Parser ;
3+ use clap:: { Parser , ValueEnum } ;
4+ use figment:: providers:: { Env , Serialized } ;
5+ use figment:: Figment ;
6+ use serde:: { Deserialize , Serialize } ;
47use tracing_subscriber:: EnvFilter ;
58use url:: Url ;
69
10+ const DEFAULT_PORT : u16 = 8456 ;
11+
712pub fn init_tracing_subscriber ( ) {
813 tracing_subscriber:: fmt ( )
914 . with_env_filter ( EnvFilter :: from_default_env ( ) )
@@ -12,7 +17,7 @@ pub fn init_tracing_subscriber() {
1217}
1318
1419pub async fn run ( ) -> anyhow:: Result < ( ) > {
15- let args = Args :: parse ( ) ;
20+ let args = parse_args ( ) ? ;
1621 let ( addr, handle) = server:: run (
1722 args. port ,
1823 args. chain_contract_address ,
@@ -28,11 +33,53 @@ pub async fn run() -> anyhow::Result<()> {
2833 Ok ( ( ) )
2934}
3035
36+ fn parse_args ( ) -> anyhow:: Result < Args > {
37+ let args = ProfileArgs :: parse ( ) ;
38+
39+ let _ = dotenv:: dotenv ( ) ;
40+
41+ if let Some ( profile) = args. profile {
42+ dotenv:: from_filename ( match profile {
43+ Profile :: Mainnet => "mainnet.env" ,
44+ Profile :: Testnet => "testnet.env" ,
45+ Profile :: Devnet => "devnet.env" ,
46+ } ) ?;
47+ }
48+
49+ let args = Figment :: new ( )
50+ . merge ( Serialized :: default ( "port" , DEFAULT_PORT ) )
51+ . merge ( Env :: prefixed ( "METABASED_" ) ) ;
52+
53+ let result = CliArgs :: try_parse ( ) ;
54+
55+ let args: CliArgs = match result {
56+ Ok ( cli_args) => args. merge ( Serialized :: defaults ( cli_args) ) . extract ( ) ?,
57+ Err ( e) => args. extract ( ) . unwrap_or_else ( |_| e. exit ( ) ) ,
58+ } ;
59+
60+ Ok ( args. into ( ) )
61+ }
62+
63+ #[ derive( ValueEnum , Debug , Clone , Serialize , Deserialize ) ]
64+ enum Profile {
65+ Mainnet ,
66+ Testnet ,
67+ Devnet ,
68+ }
69+
70+ #[ derive( Parser , Debug , Serialize , Deserialize ) ]
71+ #[ command( version, about, long_about = None ) ]
72+ struct ProfileArgs {
73+ /// Profile that chooses which .env file to load
74+ #[ arg( short = 'o' , long) ]
75+ profile : Option < Profile > ,
76+ }
77+
3178/// The Metabased sequencer is a server that exposes a JSON-RPC API that accepts incoming
3279/// transactions to be run on a layer-3 blockchain.
33- #[ derive( Parser , Debug ) ]
80+ #[ derive( Parser , Debug , Serialize , Deserialize ) ]
3481#[ command( version, about, long_about = None ) ]
35- struct Args {
82+ struct CliArgs {
3683 /// Address of the layer-2 Ethereum smart contract that processes the layer-3 transactions
3784 #[ arg( short = 'c' , long) ]
3885 chain_contract_address : Address ,
@@ -42,6 +89,26 @@ struct Args {
4289 chain_rpc_address : Url ,
4390
4491 /// Port to listen on
45- #[ arg( short = 'p' , long, default_value_t = 8456 ) ]
92+ #[ arg( short = 'p' , long) ]
93+ port : Option < u16 > ,
94+
95+ /// Profile that chooses which .env file to load
96+ #[ arg( short = 'o' , long) ]
97+ profile : Option < Profile > ,
98+ }
99+
100+ struct Args {
101+ chain_contract_address : Address ,
102+ chain_rpc_address : Url ,
46103 port : u16 ,
47104}
105+
106+ impl From < CliArgs > for Args {
107+ fn from ( value : CliArgs ) -> Self {
108+ Self {
109+ chain_contract_address : value. chain_contract_address ,
110+ chain_rpc_address : value. chain_rpc_address ,
111+ port : value. port . expect ( "port should be set by a default value" ) ,
112+ }
113+ }
114+ }
0 commit comments