tauri_plugin_matrix_svelte/stronghold/
client.rs

1use iota_stronghold::{KeyProvider, SnapshotPath};
2use std::{ops::Deref, path::PathBuf};
3
4use iota_stronghold::Client;
5use tauri::State;
6use zeroize::Zeroizing;
7
8use super::error::{Error, Result};
9use std::path::Path;
10
11use super::{utils::BytesDto, StrongholdCollection};
12
13pub struct Stronghold {
14    inner: iota_stronghold::Stronghold,
15    path: SnapshotPath,
16    keyprovider: KeyProvider,
17}
18
19impl Stronghold {
20    pub fn new<P: AsRef<Path>>(path: P, password: Vec<u8>) -> Result<Self> {
21        let path = SnapshotPath::from_path(path);
22        let stronghold = iota_stronghold::Stronghold::default();
23        let keyprovider = KeyProvider::try_from(Zeroizing::new(password))?;
24        if path.exists() {
25            stronghold.load_snapshot(&keyprovider, &path)?;
26        }
27        Ok(Self {
28            inner: stronghold,
29            path,
30            keyprovider,
31        })
32    }
33
34    pub fn save(&self) -> Result<()> {
35        self.inner
36            .commit_with_keyprovider(&self.path, &self.keyprovider)?;
37        Ok(())
38    }
39
40    pub fn inner(&self) -> &iota_stronghold::Stronghold {
41        &self.inner
42    }
43}
44
45impl Deref for Stronghold {
46    type Target = iota_stronghold::Stronghold;
47    fn deref(&self) -> &Self::Target {
48        &self.inner
49    }
50}
51
52pub async fn destroy(
53    collection: State<'_, StrongholdCollection>,
54    snapshot_path: PathBuf,
55) -> Result<()> {
56    let mut collection = collection.0.lock().unwrap();
57    if let Some(stronghold) = collection.remove(&snapshot_path) {
58        if let Err(e) = stronghold.save() {
59            collection.insert(snapshot_path, stronghold);
60            return Err(e);
61        }
62    }
63    Ok(())
64}
65
66pub async fn save(
67    collection: State<'_, StrongholdCollection>,
68    snapshot_path: PathBuf,
69) -> Result<()> {
70    let collection = collection.0.lock().unwrap();
71    if let Some(stronghold) = collection.get(&snapshot_path) {
72        stronghold.save()?;
73    }
74    Ok(())
75}
76
77pub async fn create_client(
78    collection: State<'_, StrongholdCollection>,
79    snapshot_path: PathBuf,
80    client: BytesDto,
81) -> Result<()> {
82    let stronghold = get_stronghold(collection, snapshot_path)?;
83    stronghold.create_client(client)?;
84    Ok(())
85}
86
87pub async fn load_client(
88    collection: State<'_, StrongholdCollection>,
89    snapshot_path: PathBuf,
90    client: BytesDto,
91) -> Result<()> {
92    let stronghold = get_stronghold(collection, snapshot_path)?;
93    stronghold.load_client(client)?;
94    Ok(())
95}
96
97pub async fn load_stronghold_client_or_create_it(
98    collection: State<'_, StrongholdCollection>,
99    snapshot_path: PathBuf,
100    client_id: BytesDto,
101) -> Result<()> {
102    match load_client(collection.clone(), snapshot_path.clone(), client_id.clone()).await {
103        Ok(()) => return Ok(()),
104        Err(_) => create_client(collection, snapshot_path, client_id).await,
105    }
106}
107
108fn get_stronghold(
109    collection: State<'_, StrongholdCollection>,
110    snapshot_path: PathBuf,
111) -> Result<iota_stronghold::Stronghold> {
112    let collection = collection.0.lock().unwrap();
113    if let Some(stronghold) = collection.get(&snapshot_path) {
114        Ok(stronghold.inner().clone())
115    } else {
116        Err(Error::StrongholdNotInitialized)
117    }
118}
119
120pub fn get_client(
121    collection: State<'_, StrongholdCollection>,
122    snapshot_path: PathBuf,
123    client: BytesDto,
124) -> Result<Client> {
125    let collection = collection.0.lock().unwrap();
126    if let Some(stronghold) = collection.get(&snapshot_path) {
127        stronghold.get_client(client).map_err(Into::into)
128    } else {
129        Err(Error::StrongholdNotInitialized)
130    }
131}