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

payjoin / rust-payjoin / 17008544555

16 Aug 2025 12:45PM UTC coverage: 86.257% (-0.06%) from 86.314%
17008544555

Pull #950

github

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

8 of 16 new or added lines in 7 files covered. (50.0%)

1 existing line in 1 file now uncovered.

7726 of 8957 relevant lines covered (86.26%)

520.54 hits per line

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

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

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

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

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

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

32
    fn create_original_psbt(&self, uri: &PjUri, fee_rate: FeeRate) -> Result<Psbt> {
3✔
33
        let amount = uri.amount.ok_or_else(|| anyhow!("please specify the amount in the Uri"))?;
3✔
34

35
        // wallet_create_funded_psbt requires a HashMap<address: String, Amount>
36
        let mut outputs = HashMap::with_capacity(1);
3✔
37
        outputs.insert(uri.address.to_string(), amount);
3✔
38

39
        self.wallet().create_psbt(outputs, fee_rate, true)
3✔
40
    }
3✔
41

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

49
        let signed = self.wallet().process_psbt(&psbt)?;
3✔
50
        let tx = self.wallet().finalize_psbt(&signed)?;
3✔
51

52
        let txid = self.wallet().broadcast_tx(&tx)?;
3✔
53

54
        println!("Payjoin sent. TXID: {txid}");
3✔
55
        Ok(txid)
3✔
56
    }
3✔
57
}
58

59
#[cfg(feature = "_danger-local-https")]
60
fn http_agent(config: &Config) -> Result<reqwest::Client> {
9✔
61
    Ok(http_agent_builder(config.root_certificate.as_ref())?.build()?)
9✔
62
}
9✔
63

64
#[cfg(not(feature = "_danger-local-https"))]
65
fn http_agent(_config: &Config) -> Result<reqwest::Client> { Ok(reqwest::Client::new()) }
66

67
#[cfg(feature = "_danger-local-https")]
68
fn http_agent_builder(
9✔
69
    root_cert_path: Option<&std::path::PathBuf>,
9✔
70
) -> Result<reqwest::ClientBuilder> {
9✔
71
    let mut builder = reqwest::ClientBuilder::new().use_rustls_tls();
9✔
72

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

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