spark_rust/
lib.rs

1//! # Spark Wallet SDK
2//!
3//! This crate forms a complete wallet with all necessary Spark utilities.
4
5use core::fmt;
6use std::str::FromStr;
7pub(crate) mod constants;
8pub mod error;
9pub(crate) mod wallet;
10
11pub mod signer;
12
13// pub use wallet::utils;
14pub use wallet::handlers::cooperative_exit::{CompleteCoopExitInput, RequestCoopExitInput};
15pub use wallet::SparkSdk;
16
17pub(crate) mod common_types;
18
19#[cfg(any(test, feature = "integration-tests"))]
20pub mod spark_test_utils;
21
22pub mod rpc;
23
24/// Spark Network. This is the network of the Spark Operators that the user chooses to connect to.
25///
26/// - `Mainnet` is the Bitcoin network, and all operations involve real money.
27/// - `Regtest` is Lightspark's Regtest network for testing purposes.
28#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
29#[non_exhaustive]
30pub enum SparkNetwork {
31    /// Mainnet Bitcoin network. Use this for real transactions with actual value.
32    Mainnet,
33
34    /// Lightspark's Regtest network for testing and development.
35    /// No real value is transferred when using this network.
36    Regtest,
37}
38
39impl SparkNetwork {
40    /// Converts a Spark network to its corresponding Bitcoin network.
41    ///
42    /// # Returns
43    /// The equivalent Bitcoin network type from the `bitcoin` crate:
44    /// - `SparkNetwork::Mainnet` returns `bitcoin::Network::Bitcoin`
45    /// - `SparkNetwork::Regtest` returns `bitcoin::Network::Regtest`
46    pub fn to_bitcoin_network(&self) -> ::bitcoin::Network {
47        match self {
48            SparkNetwork::Mainnet => ::bitcoin::Network::Bitcoin,
49            SparkNetwork::Regtest => ::bitcoin::Network::Regtest,
50        }
51    }
52
53    /// Marshals the network type to its protocol buffer representation. For most use cases, you don't need to use this method.
54    ///
55    /// # Returns
56    /// An integer representing the network in the protocol buffer format.
57    pub fn marshal_proto(&self) -> i32 {
58        match self {
59            SparkNetwork::Mainnet => spark_protos::spark::Network::Mainnet as i32,
60            SparkNetwork::Regtest => spark_protos::spark::Network::Regtest as i32,
61        }
62    }
63}
64
65impl FromStr for SparkNetwork {
66    type Err = String;
67
68    /// Creates a `SparkNetwork` from a string representation.
69    ///
70    /// The string comparison is case-insensitive, so both "mainnet" and "Mainnet"
71    /// will return `SparkNetwork::Mainnet`.
72    ///
73    /// # Arguments
74    /// * `s` - A string slice representing the network ("mainnet" or "regtest")
75    ///
76    /// # Returns
77    /// * `Ok(SparkNetwork)` if the string matches a known network
78    /// * `Err(String)` with an error message if the string does not match
79    ///
80    /// # Examples
81    /// ```
82    /// use std::str::FromStr;
83    /// use spark_rust::SparkNetwork;
84    ///
85    /// let mainnet = SparkNetwork::from_str("mainnet").unwrap();
86    /// assert_eq!(mainnet, SparkNetwork::Mainnet);
87    ///
88    /// let regtest = SparkNetwork::from_str("Regtest").unwrap();
89    /// assert_eq!(regtest, SparkNetwork::Regtest);
90    ///
91    /// let err = SparkNetwork::from_str("testnet");
92    /// assert!(err.is_err());
93    /// ```
94    fn from_str(s: &str) -> Result<Self, String> {
95        match s.to_lowercase().as_str() {
96            "mainnet" => Ok(SparkNetwork::Mainnet),
97            "regtest" => Ok(SparkNetwork::Regtest),
98            _ => Err(format!("Invalid network: {}", s)),
99        }
100    }
101}
102
103impl fmt::Display for SparkNetwork {
104    /// Formats the network as a lowercase string.
105    ///
106    /// # Returns
107    /// - `"mainnet"` for `SparkNetwork::Mainnet`
108    /// - `"regtest"` for `SparkNetwork::Regtest`
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        match self {
111            SparkNetwork::Mainnet => write!(f, "mainnet"),
112            SparkNetwork::Regtest => write!(f, "regtest"),
113        }
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use std::str::FromStr as _;
120
121    use crate::SparkNetwork;
122
123    #[test]
124    fn test_spark_network_display() {
125        let network = SparkNetwork::Mainnet;
126        assert_eq!(network.to_string(), "mainnet");
127
128        let network = SparkNetwork::Regtest;
129        assert_eq!(network.to_string(), "regtest");
130    }
131
132    #[test]
133    fn test_spark_network_from_str() {
134        let network = SparkNetwork::from_str("mainnet").unwrap();
135        assert_eq!(network, SparkNetwork::Mainnet);
136        let network = SparkNetwork::from_str("Mainnet").unwrap();
137        assert_eq!(network, SparkNetwork::Mainnet);
138
139        let network = SparkNetwork::from_str("regtest").unwrap();
140        assert_eq!(network, SparkNetwork::Regtest);
141        let network = SparkNetwork::from_str("Regtest").unwrap();
142        assert_eq!(network, SparkNetwork::Regtest);
143
144        let network = SparkNetwork::from_str("testnet");
145        assert!(network.is_err());
146    }
147}