Skip to main content

silent_payments_receive/
error.rs

1//! Error types for the Silent Payments receive crate.
2//!
3//! [`ReceiveError`] covers all failure modes during transaction scanning
4//! and spend key derivation. Wraps [`CryptoError`] and [`InputError`]
5//! from `silent-payments-core` for seamless error propagation.
6
7use silent_payments_core::error::{CryptoError, InputError};
8use thiserror::Error;
9
10/// Errors from receiving/scanning Silent Payment transactions.
11#[derive(Debug, Error)]
12pub enum ReceiveError {
13    /// Failed to compute tweak data from transaction inputs.
14    #[error("failed to compute tweak data from transaction: {0}")]
15    TweakData(String),
16
17    /// Failed to scan transaction outputs for SP matches.
18    #[error("failed to scan transaction outputs: {0}")]
19    Scanning(String),
20
21    /// Failed to derive the tweaked spend key for a detected output.
22    #[error("failed to derive spend key: {0}")]
23    SpendKeyDerivation(String),
24
25    /// Cryptographic operation error from sp-core.
26    #[error(transparent)]
27    Crypto(#[from] CryptoError),
28
29    /// Input classification error from sp-core.
30    #[error(transparent)]
31    Input(#[from] InputError),
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn tweak_data_error_displays_message() {
40        let err = ReceiveError::TweakData("no eligible inputs".into());
41        assert_eq!(
42            err.to_string(),
43            "failed to compute tweak data from transaction: no eligible inputs"
44        );
45    }
46
47    #[test]
48    fn scanning_error_displays_message() {
49        let err = ReceiveError::Scanning("output mismatch".into());
50        assert_eq!(
51            err.to_string(),
52            "failed to scan transaction outputs: output mismatch"
53        );
54    }
55
56    #[test]
57    fn spend_key_derivation_error_displays_message() {
58        let err = ReceiveError::SpendKeyDerivation("tweak overflow".into());
59        assert_eq!(
60            err.to_string(),
61            "failed to derive spend key: tweak overflow"
62        );
63    }
64
65    #[test]
66    fn crypto_error_wraps_transparently() {
67        let crypto_err = CryptoError::InvalidSecretKey;
68        let err = ReceiveError::from(crypto_err);
69        assert!(
70            matches!(err, ReceiveError::Crypto(CryptoError::InvalidSecretKey)),
71            "should wrap CryptoError"
72        );
73    }
74
75    #[test]
76    fn input_error_wraps_transparently() {
77        let input_err = InputError::NoEligibleInputs;
78        let err = ReceiveError::from(input_err);
79        assert!(
80            matches!(err, ReceiveError::Input(InputError::NoEligibleInputs)),
81            "should wrap InputError"
82        );
83    }
84}