Skip to main content

smplx_test/
context.rs

1use std::path::PathBuf;
2
3use electrsd::bitcoind::bitcoincore_rpc::Auth;
4
5use smplx_regtest::Regtest;
6use smplx_regtest::client::RegtestClient;
7
8use smplx_sdk::provider::{EsploraProvider, ProviderInfo, ProviderTrait, SimplexProvider, SimplicityNetwork};
9use smplx_sdk::signer::Signer;
10
11use crate::config::TestConfig;
12use crate::error::TestError;
13
14#[allow(dead_code)]
15pub struct TestContext {
16    _client: Option<RegtestClient>,
17    // since providers can't be cloned, we need this variable to create new signers
18    _provider_info: ProviderInfo,
19    config: TestConfig,
20    signer: Signer,
21}
22
23impl TestContext {
24    pub fn new(config_path: PathBuf) -> Result<Self, TestError> {
25        let config = TestConfig::from_file(&config_path)?;
26
27        let (signer, provider_info, client) = Self::setup(&config)?;
28
29        Ok(Self {
30            _client: client,
31            _provider_info: provider_info,
32            config,
33            signer,
34        })
35    }
36
37    pub fn create_signer(&self, mnemonic: &str) -> Signer {
38        let provider: Box<dyn ProviderTrait> = if self._provider_info.elements_url.is_some() {
39            // local regtest or external regtest
40            Box::new(SimplexProvider::new(
41                self._provider_info.esplora_url.clone(),
42                self._provider_info.elements_url.clone().unwrap(),
43                self._provider_info.auth.clone().unwrap(),
44                *self.get_network(),
45            ))
46        } else {
47            // external esplora
48            Box::new(EsploraProvider::new(
49                self._provider_info.esplora_url.clone(),
50                *self.get_network(),
51            ))
52        };
53
54        Signer::new(mnemonic, provider)
55    }
56
57    pub fn get_default_signer(&self) -> &Signer {
58        &self.signer
59    }
60
61    pub fn get_default_provider(&self) -> &dyn ProviderTrait {
62        self.signer.get_provider()
63    }
64
65    pub fn get_config(&self) -> &TestConfig {
66        &self.config
67    }
68
69    pub fn get_network(&self) -> &SimplicityNetwork {
70        self.signer.get_provider().get_network()
71    }
72
73    fn setup(config: &TestConfig) -> Result<(Signer, ProviderInfo, Option<RegtestClient>), TestError> {
74        let client: Option<RegtestClient>;
75        let provider_info: ProviderInfo;
76        let signer: Signer;
77
78        match config.esplora.clone() {
79            Some(esplora) => match config.rpc.clone() {
80                Some(rpc) => {
81                    // custom regtest case
82                    let auth = Auth::UserPass(rpc.username, rpc.password);
83                    let provider = Box::new(SimplexProvider::new(
84                        esplora.url.clone(),
85                        rpc.url.clone(),
86                        auth.clone(),
87                        SimplicityNetwork::default_regtest(),
88                    ));
89
90                    provider_info = ProviderInfo {
91                        esplora_url: esplora.url,
92                        elements_url: Some(rpc.url),
93                        auth: Some(auth),
94                    };
95                    signer = Signer::new(config.mnemonic.as_str(), provider);
96                    client = None;
97                }
98                None => {
99                    // external esplora network
100                    let network = match esplora.network.as_str() {
101                        "Liquid" => SimplicityNetwork::Liquid,
102                        "LiquidTestnet" => SimplicityNetwork::LiquidTestnet,
103                        "ElementsRegtest" => SimplicityNetwork::default_regtest(),
104                        other => return Err(TestError::BadNetworkName(other.to_string())),
105                    };
106                    let provider = Box::new(EsploraProvider::new(esplora.url.clone(), network));
107
108                    provider_info = ProviderInfo {
109                        esplora_url: esplora.url,
110                        elements_url: None,
111                        auth: None,
112                    };
113                    signer = Signer::new(config.mnemonic.as_str(), provider);
114                    client = None;
115                }
116            },
117            None => {
118                // simplex inner network
119                let (regtest_client, regtest_signer) = Regtest::from_config(config.to_regtest_config())?;
120
121                provider_info = ProviderInfo {
122                    esplora_url: regtest_client.esplora_url(),
123                    elements_url: Some(regtest_client.rpc_url()),
124                    auth: Some(regtest_client.auth()),
125                };
126                signer = regtest_signer;
127                client = Some(regtest_client);
128            }
129        }
130
131        Ok((signer, provider_info, client))
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use std::fs;
138
139    use super::*;
140
141    #[test]
142    fn invalid_network_returns_error() {
143        let config = r#"
144            mnemonic = "exist carry drive collect lend cereal occur much tiger just involve mean"
145            bitcoins = 10000
146
147            [esplora]
148            url = "http://localhost:3000"
149            network = "InvalidNetwork"
150        "#;
151
152        let path = std::env::temp_dir().join("smplx_test_invalid_network.toml");
153        fs::write(&path, config).unwrap();
154
155        let result = TestContext::new(path);
156        let Err(e) = result else {
157            panic!("expected BadNetworkName error")
158        };
159        assert!(
160            matches!(e, TestError::BadNetworkName(ref s) if s == "InvalidNetwork"),
161            "expected BadNetworkName, got: {e}"
162        );
163    }
164}