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

payjoin / rust-payjoin / 17558272527

08 Sep 2025 04:58PM UTC coverage: 85.899% (-0.03%) from 85.926%
17558272527

Pull #950

github

web-flow
Merge de1336211 into ca35bacb3
Pull Request #950: Sanitize sensitive data from log messages to prevent privacy leaks

7 of 11 new or added lines in 6 files covered. (63.64%)

5 existing lines in 1 file now uncovered.

8224 of 9574 relevant lines covered (85.9%)

488.45 hits per line

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

87.8
/payjoin-cli/src/app/mod.rs
1
use std::collections::HashMap;
2

3
use anyhow::Result;
4
use payjoin::bitcoin::psbt::Psbt;
5
use payjoin::bitcoin::{self, Address, Amount, FeeRate};
6
use tokio::signal;
7
use tokio::sync::watch;
8

9
pub mod config;
10
pub mod rpc;
11
pub mod wallet;
12
use crate::app::config::Config;
13
use crate::app::wallet::BitcoindWallet;
14

15
#[cfg(feature = "v1")]
16
pub(crate) mod v1;
17
#[cfg(feature = "v2")]
18
pub(crate) mod v2;
19

20
#[async_trait::async_trait]
21
pub trait App: Send + Sync {
22
    async fn new(config: Config) -> Result<Self>
23
    where
24
        Self: Sized;
25
    fn wallet(&self) -> BitcoindWallet;
26
    async fn send_payjoin(&self, bip21: &str, fee_rate: FeeRate) -> Result<()>;
27
    async fn receive_payjoin(&self, amount: Amount) -> Result<()>;
28
    #[cfg(feature = "v2")]
29
    async fn resume_payjoins(&self) -> Result<()>;
30

31
    fn create_original_psbt(
4✔
32
        &self,
4✔
33
        address: &Address,
4✔
34
        amount: Amount,
4✔
35
        fee_rate: FeeRate,
4✔
36
    ) -> Result<Psbt> {
4✔
37
        // wallet_create_funded_psbt requires a HashMap<address: String, Amount>
38
        let mut outputs = HashMap::with_capacity(1);
4✔
39
        outputs.insert(address.to_string(), amount);
4✔
40

41
        self.wallet().create_psbt(outputs, fee_rate, true)
4✔
42
    }
4✔
43

44
    fn process_pj_response(&self, psbt: Psbt) -> Result<bitcoin::Txid> {
4✔
45
        log::trace!(
4✔
NEW
UNCOV
46
            "Processing payjoin response with {} inputs and {} outputs",
×
NEW
UNCOV
47
            psbt.inputs.len(),
×
NEW
UNCOV
48
            psbt.unsigned_tx.output.len()
×
49
        );
50

51
        let signed = self.wallet().process_psbt(&psbt)?;
4✔
52
        let tx = self.wallet().finalize_psbt(&signed)?;
4✔
53

54
        let txid = self.wallet().broadcast_tx(&tx)?;
4✔
55

56
        println!("Payjoin sent. TXID: {txid}");
4✔
57
        Ok(txid)
4✔
58
    }
4✔
59
}
60

61
#[cfg(feature = "_manual-tls")]
62
fn http_agent(config: &Config) -> Result<reqwest::Client> {
10✔
63
    Ok(http_agent_builder(config.root_certificate.as_ref())?.build()?)
10✔
64
}
10✔
65

66
#[cfg(not(feature = "_manual-tls"))]
67
fn http_agent(_config: &Config) -> Result<reqwest::Client> { Ok(reqwest::Client::new()) }
68

69
#[cfg(feature = "_manual-tls")]
70
fn http_agent_builder(
10✔
71
    root_cert_path: Option<&std::path::PathBuf>,
10✔
72
) -> Result<reqwest::ClientBuilder> {
10✔
73
    let mut builder = reqwest::ClientBuilder::new().use_rustls_tls();
10✔
74

75
    if let Some(root_cert_path) = root_cert_path {
10✔
76
        let cert_der = std::fs::read(root_cert_path)?;
10✔
77
        builder =
10✔
78
            builder.add_root_certificate(reqwest::tls::Certificate::from_der(cert_der.as_slice())?)
10✔
UNCOV
79
    }
×
80
    Ok(builder)
10✔
81
}
10✔
82

83
async fn handle_interrupt(tx: watch::Sender<()>) {
12✔
84
    if let Err(e) = signal::ctrl_c().await {
12✔
UNCOV
85
        eprintln!("Error setting up Ctrl-C handler: {e}");
×
86
    }
9✔
87
    let _ = tx.send(());
9✔
88
}
9✔
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