breez_sdk_liquid/wallet/
persister.rs

1use anyhow::Result;
2use log::debug;
3use lwk_wollet::{PersistError, Update, WolletDescriptor};
4use std::sync::{Arc, Mutex};
5
6pub use lwk_wollet;
7
8use crate::persist::Persister;
9
10pub type LwkPersister = Arc<dyn lwk_wollet::Persister + Send + Sync>;
11
12#[sdk_macros::async_trait]
13pub trait WalletCachePersister: Send + Sync {
14    fn get_lwk_persister(&self) -> Result<LwkPersister>;
15
16    async fn clear_cache(&self) -> Result<()>;
17}
18
19#[derive(Clone)]
20pub struct SqliteWalletCachePersister {
21    persister: Arc<Persister>,
22    descriptor: WolletDescriptor,
23}
24
25impl SqliteWalletCachePersister {
26    pub fn new(persister: Arc<Persister>, descriptor: WolletDescriptor) -> Result<Self> {
27        Ok(Self {
28            persister,
29            descriptor,
30        })
31    }
32}
33
34#[sdk_macros::async_trait]
35impl WalletCachePersister for SqliteWalletCachePersister {
36    fn get_lwk_persister(&self) -> Result<LwkPersister> {
37        SqliteLwkPersister::new(Arc::clone(&self.persister), self.descriptor.clone())
38    }
39
40    async fn clear_cache(&self) -> Result<()> {
41        self.persister.clear_wallet_updates()
42    }
43}
44
45pub(crate) struct SqliteLwkPersister {
46    persister: Arc<Persister>,
47    descriptor: WolletDescriptor,
48    next: Mutex<u64>,
49}
50
51impl SqliteLwkPersister {
52    #[allow(clippy::new_ret_no_self)]
53    pub(crate) fn new(
54        persister: Arc<Persister>,
55        descriptor: WolletDescriptor,
56    ) -> Result<LwkPersister> {
57        let next = persister.get_next_wallet_update_index()?;
58        Ok(Arc::new(Self {
59            persister,
60            descriptor,
61            next: Mutex::new(next),
62        }))
63    }
64}
65
66impl lwk_wollet::Persister for SqliteLwkPersister {
67    fn get(&self, index: usize) -> std::result::Result<Option<Update>, PersistError> {
68        let maybe_update_bytes = self
69            .persister
70            .get_wallet_update(index as u64)
71            .map_err(|e| PersistError::Other(e.to_string()))?;
72        maybe_update_bytes
73            .map(|update_bytes| {
74                Update::deserialize_decrypted(&update_bytes, &self.descriptor)
75                    .map_err(|e| PersistError::Other(e.to_string()))
76            })
77            .transpose()
78    }
79
80    fn push(&self, update: Update) -> std::result::Result<(), PersistError> {
81        debug!(
82            "LwkPersister starting push update with status {}",
83            update.wollet_status
84        );
85
86        let mut next = self.next.lock().unwrap();
87
88        let ciphertext = update
89            .serialize_encrypted(&self.descriptor)
90            .map_err(|e| PersistError::Other(e.to_string()))?;
91
92        self.persister
93            .insert_wallet_update(*next, &ciphertext)
94            .map_err(|e| PersistError::Other(e.to_string()))?;
95
96        *next += 1;
97
98        Ok(())
99    }
100}