1use std::sync::{Arc, Mutex};
2
3use lwk_wollet::clients::blocking::BlockchainBackend;
4
5use crate::{BlockHeader, LwkError, Transaction, Txid, Update, Wollet};
6
7#[derive(uniffi::Object, Debug)]
9pub struct ElectrumClient {
10 inner: Arc<Mutex<lwk_wollet::ElectrumClient>>,
11
12 url: lwk_wollet::ElectrumUrl,
13}
14
15#[uniffi::export]
16impl ElectrumClient {
17 #[uniffi::constructor]
19 pub fn new(
20 electrum_url: &str,
21 tls: bool,
22 validate_domain: bool,
23 ) -> Result<Arc<Self>, LwkError> {
24 let url = lwk_wollet::ElectrumUrl::new(electrum_url, tls, validate_domain)
25 .map_err(lwk_wollet::Error::Url)?;
26 let client = lwk_wollet::ElectrumClient::new(&url)?;
27 Ok(Arc::new(Self {
28 inner: Arc::new(Mutex::new(client)),
29 url,
30 }))
31 }
32
33 #[uniffi::constructor]
34 pub fn from_url(electrum_url: &str) -> Result<Arc<Self>, LwkError> {
36 let url = electrum_url
37 .parse::<lwk_wollet::ElectrumUrl>()
38 .map_err(|e| LwkError::Generic { msg: e.to_string() })?;
39 let client = lwk_wollet::ElectrumClient::new(&url)?;
40 Ok(Arc::new(Self {
41 inner: Arc::new(Mutex::new(client)),
42 url,
43 }))
44 }
45
46 pub fn ping(&self) -> Result<(), LwkError> {
48 Ok(self.inner.lock()?.ping()?)
49 }
50
51 pub fn broadcast(&self, tx: &Transaction) -> Result<Arc<Txid>, LwkError> {
53 Ok(Arc::new(self.inner.lock()?.broadcast(tx.as_ref())?.into()))
54 }
55
56 pub fn full_scan(&self, wollet: &Wollet) -> Result<Option<Arc<Update>>, LwkError> {
67 self.full_scan_to_index(wollet, 0)
68 }
69
70 pub fn full_scan_to_index(
83 &self,
84 wollet: &Wollet,
85 index: u32,
86 ) -> Result<Option<Arc<Update>>, LwkError> {
87 let wollet = wollet.inner_wollet()?;
88 let update: Option<lwk_wollet::Update> = self
89 .inner
90 .lock()?
91 .full_scan_to_index(&wollet.state(), index)?;
92 Ok(update.map(Into::into).map(Arc::new))
93 }
94
95 pub fn get_tx(&self, txid: &Txid) -> Result<Arc<Transaction>, LwkError> {
97 let err = || LwkError::Generic {
98 msg: "tx not found".to_string(),
99 };
100 let mut tx = self.inner.lock()?.get_transactions(&[txid.into()])?;
101 Ok(Arc::new(Transaction::from(tx.pop().ok_or_else(err)?)))
102 }
103
104 pub fn tip(&self) -> Result<Arc<BlockHeader>, LwkError> {
106 let tip = self.inner.lock()?.tip()?;
107 Ok(Arc::new(tip.into()))
108 }
109}
110
111impl ElectrumClient {
112 #[allow(unused)] pub(crate) fn clone_client(&self) -> Result<lwk_wollet::ElectrumClient, LwkError> {
115 Ok(lwk_wollet::ElectrumClient::new(&self.url)?)
116 }
117}