1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use anyhow::Result;
use clap::Parser;
use ethers::providers::{Provider, Ws};
use lib_xps::run;
use tracing_subscriber::{
    filter::LevelFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry,
};

#[derive(Parser, Debug)]
#[command(name = "xps", version = "0.1.0", about = "XMTP Postal Service")]
struct Args {
    #[arg(short = 'p', long = "port", default_value_t = 0)]
    port: u16,
    #[arg(short = 's', long = "host", default_value = "127.0.0.1")]
    host: String,
    #[arg(
        short = 'e',
        long = "endpoint",
        default_value = "wss://ethereum-sepolia.publicnode.com"
    )]
    endpoint: String,
}

#[tokio::main]
async fn main() -> Result<()> {
    init_logging();
    let args = Args::parse();
    let provider = Provider::<Ws>::connect(&args.endpoint).await?;
    crate::run(args.host, args.port, provider).await?;
    Ok(())
}

fn init_logging() {
    let fmt = fmt::layer().compact();
    let env = EnvFilter::builder()
        .with_default_directive(LevelFilter::INFO.into())
        .from_env_lossy();
    Registry::default().with(env).with(fmt).init()
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_port_0() -> Result<()> {
        let arg_list = vec!["xps", "-p", "0"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.port, 0);
        Ok(())
    }

    #[test]
    fn test_port_25() -> Result<()> {
        let arg_list = vec!["xps", "--port", "25"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.port, 25);
        Ok(())
    }

    #[test]
    fn test_host_test_net() -> Result<()> {
        let arg_list = vec!["xps", "-s", "test.net"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.host, "test.net");
        Ok(())
    }

    #[test]
    fn test_host_test_0000() -> Result<()> {
        let arg_list = vec!["xps", "--host", "0.0.0.0"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.host, "0.0.0.0");
        Ok(())
    }

    #[test]
    fn test_default() -> Result<()> {
        let arg_list = vec!["xps"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.port, 0);
        assert_eq!(args.host, "127.0.0.1");
        assert_eq!(args.endpoint, "wss://ethereum-sepolia.publicnode.com");
        Ok(())
    }

    #[test]
    fn test_endpoint() -> Result<()> {
        let arg_list = vec!["xps", "--endpoint", "http://localhost:8545"];
        let args = Args::parse_from(arg_list);
        assert_eq!(args.endpoint, "http://localhost:8545");
        Ok(())
    }
}