Skip to main content

silent_payments/
lib.rs

1//! # silent-payments
2//!
3//! High-level [BIP 352](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki)
4//! Silent Payments library for Rust wallets.
5//!
6//! This is a facade crate that re-exports all sub-crate public APIs.
7//! Like tokio's facade pattern, users depend on `silent-payments` and
8//! get access to all functionality through a single dependency.
9//!
10//! ## Crate graph
11//!
12//! ```text
13//! silent-payments (facade)
14//! +-- silent-payments-core     (address, keys, inputs, crypto)
15//! +-- silent-payments-send     (sender builder, output scripts)
16//! +-- silent-payments-receive  (scanner, labels, detected outputs)
17//! +-- silent-payments-psbt     (BIP 375 fields, roles, DLEQ proofs)
18//! +-- silent-payments-scan     (ScanBackend trait, electrum, index-server)
19//! +-- silent-payments-descriptor (BIP 392 sp() descriptors)
20//! ```
21//!
22//! # Quick start
23//!
24//! ```rust
25//! use silent_payments::prelude::*;
26//! ```
27//!
28//! The prelude provides:
29//! - **Address types:** [`SpAddress`] with bech32m parsing and encoding
30//! - **Key newtypes:** [`ScanPublicKey`], [`SpendPublicKey`], [`ScanSecretKey`], [`SpendSecretKey`]
31//! - **Input classification:** [`classify_input`], [`collect_eligible_inputs`], [`ClassifiedInput`], [`SpInputType`]
32//! - **Crypto wrappers:** [`compute_shared_secret`], [`compute_output_pubkey`], [`compute_input_hash`], [`get_label_tweak`]
33//! - **Error types:** [`AddressError`], [`InputError`], [`CryptoError`]
34//! - **PSBT types:** [`SpPsbtConstructor`], [`SpPsbtUpdater`], [`SpPsbtSigner`], [`SpPsbtExtractor`], [`DleqProof`]
35//! - **Scan types:** [`ScanBackend`], [`ScanError`], [`OnMatch`], [`OnProgress`]
36//!
37//! # Feature Flags
38//!
39//! - `bip392` -- Enables `SpDescriptor` for BIP 392 descriptor parsing and generation
40//! - `electrum` -- Enables `ElectrumBackend` for Electrum server scanning
41//! - `index-server` -- Enables `IndexServerBackend` for BIP0352 index server scanning
42//! - `experimental-dleq` -- Enables DLEQ proof generation in PSBT signing
43//!
44//! # Complete Send + Receive Roundtrip
45//!
46//! ```no_run
47//! use std::str::FromStr;
48//! use silent_payments::prelude::*;
49//! # use bitcoin::secp256k1::{Secp256k1, SecretKey};
50//! # use bitcoin::{Amount, EcdsaSighashType, Network, OutPoint, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, WPubkeyHash};
51//! # use bitcoin::hashes::{Hash, hash160};
52//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
53//! let secp = Secp256k1::new();
54//! // Receiver: create keys + address
55//! let scan_sk = ScanSecretKey::from_slice(&[0xea; 32])?;
56//! let spend_sk = SpendSecretKey::from_slice(&[0x93; 32])?;
57//! let (scan_pk, spend_pk) = (scan_sk.public_key(&secp), spend_sk.public_key(&secp));
58//! let sp_addr = SpAddress::new(scan_pk.clone(), spend_pk.clone(), Network::Bitcoin);
59//! // Sender: build inputs, create outputs
60//! # let input_sk = SecretKey::from_slice(&[0x01; 32])?;
61//! # let pk = input_sk.public_key(&secp);
62//! # let wpkh = WPubkeyHash::from_raw_hash(hash160::Hash::hash(&pk.serialize()));
63//! # let spk = ScriptBuf::new_p2wpkh(&wpkh);
64//! # let sig = vec![0x30,0x06,0x02,0x01,0x01,0x02,0x01,0x01,0x01];
65//! # let w = Witness::from_slice(&[&sig, &pk.serialize().to_vec()]);
66//! # let txin = TxIn { previous_output: "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16:0".parse()?, script_sig: ScriptBuf::new(), witness: w, sequence: Sequence::default() };
67//! # let prev = TxOut { value: Amount::from_sat(100_000), script_pubkey: spk.clone() };
68//! let sender = SilentPaymentSender::new(&[(txin.clone(), prev.clone(), input_sk)], EcdsaSighashType::All)?;
69//! let outputs = sender.create_output_scripts(&sp_addr, &secp)?;
70//! // Receiver: scan transaction, derive spend key
71//! # let tx = Transaction { version: bitcoin::transaction::Version::TWO, lock_time: bitcoin::absolute::LockTime::ZERO, input: vec![txin], output: vec![TxOut { value: Amount::from_sat(50_000), script_pubkey: outputs[0].script_pubkey().clone() }] };
72//! let scanner = BlockScanner::new(scan_sk, spend_pk, LabelManager::new());
73//! let detected = scanner.scan_transaction(&tx, &[prev], &secp)?;
74//! for d in &detected { let _key = d.derive_spend_key(&spend_sk, &secp)?; }
75//! # Ok(())
76//! # }
77//! ```
78
79pub use silent_payments_core;
80pub use silent_payments_core::*;
81
82pub use silent_payments_send;
83pub use silent_payments_send::{SendError, SilentPaymentOutput, SilentPaymentSender};
84
85pub use silent_payments_receive;
86pub use silent_payments_receive::{BlockScanner, DetectedOutput, LabelManager, ReceiveError};
87
88pub use silent_payments_psbt;
89pub use silent_payments_psbt::{
90    DleqError, DleqProof, ExtractedSpOutput, PsbtError, SpPsbtConstructor, SpPsbtExtractor,
91    SpPsbtSigner, SpPsbtUpdater,
92};
93
94pub use silent_payments_scan;
95pub use silent_payments_scan::{OnMatch, OnProgress, ScanBackend, ScanError};
96
97#[cfg(feature = "electrum")]
98pub use silent_payments_scan::ElectrumBackend;
99
100#[cfg(feature = "index-server")]
101pub use silent_payments_scan::IndexServerBackend;
102
103#[cfg(feature = "bip392")]
104pub use silent_payments_descriptor;
105#[cfg(feature = "bip392")]
106pub use silent_payments_descriptor::{DescriptorError, SpDescriptor};
107
108/// Common types and traits for convenient glob imports.
109///
110/// ```
111/// use silent_payments::prelude::*;
112/// ```
113pub mod prelude {
114    pub use silent_payments_core::prelude::*;
115    pub use silent_payments_psbt::{
116        DleqError, DleqProof, ExtractedSpOutput, PsbtError, SpPsbtConstructor, SpPsbtExtractor,
117        SpPsbtSigner, SpPsbtUpdater,
118    };
119    pub use silent_payments_receive::{BlockScanner, DetectedOutput, LabelManager, ReceiveError};
120    pub use silent_payments_scan::{OnMatch, OnProgress, ScanBackend, ScanError};
121    pub use silent_payments_send::{SendError, SilentPaymentOutput, SilentPaymentSender};
122
123    #[cfg(feature = "electrum")]
124    pub use silent_payments_scan::ElectrumBackend;
125
126    #[cfg(feature = "index-server")]
127    pub use silent_payments_scan::IndexServerBackend;
128
129    #[cfg(feature = "bip392")]
130    pub use silent_payments_descriptor::{DescriptorError, SpDescriptor};
131}