Skip to main content

ark_client/swap_storage/
memory.rs

1use super::SwapStorage;
2use crate::boltz::ChainSwapData;
3use crate::boltz::ReverseSwapData;
4use crate::boltz::SubmarineSwapData;
5use crate::boltz::SwapStatus;
6use crate::Error;
7use async_trait::async_trait;
8use std::collections::HashMap;
9use std::sync::Arc;
10use std::sync::Mutex;
11
12/// In-memory implementation of [`SwapStorage`].
13///
14/// This implementation stores swap data in memory using a [`HashMap`] protected by a [`Mutex`].
15/// Data is lost when the application restarts, making this suitable for development, testing,
16/// and scenarios where persistence is not required.
17pub struct InMemorySwapStorage {
18    submarine_swaps: Arc<Mutex<HashMap<String, SubmarineSwapData>>>,
19    reverse_swaps: Arc<Mutex<HashMap<String, ReverseSwapData>>>,
20    chain_swaps: Arc<Mutex<HashMap<String, ChainSwapData>>>,
21}
22
23impl InMemorySwapStorage {
24    /// Create a new in-memory swap storage.
25    ///
26    /// # Examples
27    ///
28    /// ```rust
29    /// use ark_client::InMemorySwapStorage;
30    ///
31    /// let storage = InMemorySwapStorage::new();
32    /// ```
33    pub fn new() -> Self {
34        Self {
35            submarine_swaps: Arc::new(Mutex::new(HashMap::new())),
36            reverse_swaps: Arc::new(Mutex::new(HashMap::new())),
37            chain_swaps: Arc::new(Mutex::new(HashMap::new())),
38        }
39    }
40}
41
42impl Default for InMemorySwapStorage {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48#[async_trait]
49impl SwapStorage for InMemorySwapStorage {
50    async fn insert_submarine(&self, id: String, data: SubmarineSwapData) -> Result<(), Error> {
51        let mut swaps = self.submarine_swaps.lock().expect("lock");
52        swaps.insert(id, data);
53        Ok(())
54    }
55
56    async fn insert_reverse(&self, id: String, data: ReverseSwapData) -> Result<(), Error> {
57        let mut swaps = self.reverse_swaps.lock().expect("lock");
58        swaps.insert(id, data);
59        Ok(())
60    }
61
62    async fn get_submarine(&self, id: &str) -> Result<Option<SubmarineSwapData>, Error> {
63        let swaps = self.submarine_swaps.lock().expect("lock");
64        Ok(swaps.get(id).cloned())
65    }
66
67    async fn get_reverse(&self, id: &str) -> Result<Option<ReverseSwapData>, Error> {
68        let swaps = self.reverse_swaps.lock().expect("lock");
69        Ok(swaps.get(id).cloned())
70    }
71
72    async fn update_status_submarine(&self, id: &str, status: SwapStatus) -> Result<(), Error> {
73        let mut swaps = self.submarine_swaps.lock().expect("lock");
74        if let Some(swap) = swaps.get_mut(id) {
75            swap.status = status;
76            Ok(())
77        } else {
78            Err(Error::consumer(format!("swap not found: {id}")))
79        }
80    }
81
82    async fn update_status_reverse(&self, id: &str, status: SwapStatus) -> Result<(), Error> {
83        let mut swaps = self.reverse_swaps.lock().expect("lock");
84        if let Some(swap) = swaps.get_mut(id) {
85            swap.status = status;
86            Ok(())
87        } else {
88            Err(Error::consumer(format!("swap not found: {id}")))
89        }
90    }
91
92    async fn update_submarine(&self, id: &str, data: SubmarineSwapData) -> Result<(), Error> {
93        let mut swaps = self.submarine_swaps.lock().expect("lock");
94        match swaps.get_mut(id) {
95            Some(entry) => {
96                *entry = data;
97                Ok(())
98            }
99            None => Err(Error::consumer(format!("submarine swap not found: {id}"))),
100        }
101    }
102
103    async fn update_reverse(&self, id: &str, data: ReverseSwapData) -> Result<(), Error> {
104        let mut swaps = self.reverse_swaps.lock().expect("lock");
105        match swaps.get_mut(id) {
106            Some(entry) => {
107                *entry = data;
108                Ok(())
109            }
110            None => Err(Error::consumer(format!("reverse swap not found: {id}"))),
111        }
112    }
113
114    async fn list_all_submarine(&self) -> Result<Vec<SubmarineSwapData>, Error> {
115        let swaps = self.submarine_swaps.lock().expect("lock");
116        Ok(swaps.values().cloned().collect())
117    }
118
119    async fn list_all_reverse(&self) -> Result<Vec<ReverseSwapData>, Error> {
120        let swaps = self.reverse_swaps.lock().expect("lock");
121
122        Ok(swaps.values().cloned().collect())
123    }
124
125    async fn remove_submarine(&self, id: &str) -> Result<Option<SubmarineSwapData>, Error> {
126        let mut swaps = self.submarine_swaps.lock().expect("lock");
127        Ok(swaps.remove(id))
128    }
129
130    async fn remove_reverse(&self, id: &str) -> Result<Option<ReverseSwapData>, Error> {
131        let mut swaps = self.reverse_swaps.lock().expect("lock");
132        Ok(swaps.remove(id))
133    }
134
135    async fn insert_chain(&self, id: String, data: ChainSwapData) -> Result<(), Error> {
136        let mut swaps = self.chain_swaps.lock().expect("lock");
137        swaps.insert(id, data);
138        Ok(())
139    }
140
141    async fn get_chain(&self, id: &str) -> Result<Option<ChainSwapData>, Error> {
142        let swaps = self.chain_swaps.lock().expect("lock");
143        Ok(swaps.get(id).cloned())
144    }
145
146    async fn update_status_chain(&self, id: &str, status: SwapStatus) -> Result<(), Error> {
147        let mut swaps = self.chain_swaps.lock().expect("lock");
148        if let Some(swap) = swaps.get_mut(id) {
149            swap.status = status;
150            Ok(())
151        } else {
152            Err(Error::consumer(format!("chain swap not found: {id}")))
153        }
154    }
155
156    async fn update_chain(&self, id: &str, data: ChainSwapData) -> Result<(), Error> {
157        let mut swaps = self.chain_swaps.lock().expect("lock");
158        match swaps.get_mut(id) {
159            Some(entry) => {
160                *entry = data;
161                Ok(())
162            }
163            None => Err(Error::consumer(format!("chain swap not found: {id}"))),
164        }
165    }
166
167    async fn list_all_chain(&self) -> Result<Vec<ChainSwapData>, Error> {
168        let swaps = self.chain_swaps.lock().expect("lock");
169        Ok(swaps.values().cloned().collect())
170    }
171
172    async fn remove_chain(&self, id: &str) -> Result<Option<ChainSwapData>, Error> {
173        let mut swaps = self.chain_swaps.lock().expect("lock");
174        Ok(swaps.remove(id))
175    }
176}