• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

payjoin / rust-payjoin / 16441397548

22 Jul 2025 10:15AM UTC coverage: 85.727% (-0.07%) from 85.8%
16441397548

Pull #874

github

web-flow
Merge de2a271bd into 0c1b93103
Pull Request #874: Add default directory to payjoin-cli

28 of 30 new or added lines in 2 files covered. (93.33%)

44 existing lines in 4 files now uncovered.

7766 of 9059 relevant lines covered (85.73%)

517.15 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.37
/payjoin-cli/src/main.rs
1
use std::path::PathBuf;
2

3
use anyhow::Result;
4
use app::config::Config;
5
use app::App as AppTrait;
6
use clap::Parser;
7
use cli::{Cli, Commands};
8

9
mod app;
10
mod cli;
11
mod db;
12

13
const PAYJOIN_CONFIG_DIR: &str = "payjoin-cli";
14

15
#[cfg(not(any(feature = "v1", feature = "v2")))]
16
compile_error!("At least one of the features ['v1', 'v2'] must be enabled");
17

18
fn ensure_config_dirs() -> std::io::Result<PathBuf> {
10✔
19
    let config_dir = dirs::config_dir().expect("Could not determine config directory");
10✔
20
    let payjoin_dir = config_dir.join(PAYJOIN_CONFIG_DIR);
10✔
21
    std::fs::create_dir_all(&payjoin_dir)?;
10✔
22
    // Set permissions to 0o700 on Unix systems
23
    #[cfg(unix)]
24
    {
25
        use std::os::unix::fs::PermissionsExt;
26
        std::fs::set_permissions(&payjoin_dir, std::fs::Permissions::from_mode(0o700)).ok();
10✔
27
    }
28
    Ok(payjoin_dir)
10✔
29
}
10✔
30

31
fn find_config_path() -> Option<PathBuf> {
10✔
32
    // Look for a config.toml in the current working directory first
33
    //if not found, look for a config.toml in .config/payjoin-cli directory
34
    let cwd = std::env::current_dir().ok()?;
10✔
35
    let local_config = cwd.join("config.toml");
10✔
36
    if local_config.exists() {
10✔
NEW
37
        return Some(local_config);
×
38
    }
10✔
39
    let config_dir = dirs::config_dir()?;
10✔
40
    let payjoin_config = config_dir.join(PAYJOIN_CONFIG_DIR).join("config.toml");
10✔
41
    if payjoin_config.exists() {
10✔
NEW
42
        Some(payjoin_config)
×
43
    } else {
44
        None
10✔
45
    }
46
}
10✔
47

48
#[tokio::main]
49
async fn main() -> Result<()> {
10✔
50
    env_logger::init();
10✔
51

52
    ensure_config_dirs().expect("Failed to create payjoin-cli configuration directory");
10✔
53

54
    let cli = Cli::parse();
10✔
55
    let config_path = find_config_path();
10✔
56
    let config = Config::new(&cli, config_path)?;
10✔
57

58
    #[allow(clippy::if_same_then_else)]
59
    let app: Box<dyn AppTrait> = if cli.flags.bip78.unwrap_or(false) {
10✔
60
        #[cfg(feature = "v1")]
61
        {
62
            Box::new(crate::app::v1::App::new(config)?)
4✔
63
        }
64
        #[cfg(not(feature = "v1"))]
65
        {
66
            anyhow::bail!(
67
                "BIP78 (v1) support is not enabled in this build. Recompile with --features v1"
68
            )
69
        }
70
    } else if cli.flags.bip77.unwrap_or(false) {
6✔
71
        #[cfg(feature = "v2")]
72
        {
73
            Box::new(crate::app::v2::App::new(config)?)
×
74
        }
75
        #[cfg(not(feature = "v2"))]
76
        {
77
            anyhow::bail!(
×
78
                "BIP77 (v2) support is not enabled in this build. Recompile with --features v2"
×
79
            )
80
        }
81
    } else {
82
        #[cfg(feature = "v2")]
83
        {
84
            Box::new(crate::app::v2::App::new(config)?)
6✔
85
        }
86
        #[cfg(all(feature = "v1", not(feature = "v2")))]
87
        {
88
            Box::new(crate::app::v1::App::new(config)?)
×
89
        }
90
        #[cfg(not(any(feature = "v1", feature = "v2")))]
91
        {
92
            anyhow::bail!("No valid version available - must compile with v1 or v2 feature")
93
        }
94
    };
95

96
    match &cli.command {
10✔
97
        Commands::Send { bip21, fee_rate } => {
4✔
98
            app.send_payjoin(bip21, *fee_rate).await?;
4✔
99
        }
100
        Commands::Receive { amount, .. } => {
3✔
101
            app.receive_payjoin(*amount).await?;
3✔
102
        }
103
        #[cfg(feature = "v2")]
104
        Commands::Resume => {
105
            app.resume_payjoins().await?;
3✔
106
        }
107
    };
108

109
    Ok(())
18✔
110
}
10✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc