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}