breez_sdk_liquid/wallet/
persister.rs

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