Skip to content

Commit fc1d440

Browse files
committed
Recover cashu wallets on init
1 parent cb0a8ac commit fc1d440

2 files changed

Lines changed: 48 additions & 2 deletions

File tree

orange-sdk/src/trusted_wallet/cashu/cashu_store.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ use cdk::wallet::{
2121
use std::collections::hash_map::DefaultHasher;
2222
use std::hash::{Hash, Hasher};
2323

24+
use crate::trusted_wallet::TrustedError;
25+
2426
// Constants for organizing data in the KV store
2527
const CASHU_PRIMARY_KEY: &str = "cashu_wallet";
2628

@@ -35,6 +37,7 @@ const KEYSET_COUNTERS_KEY: &str = "keyset_counters";
3537
const TRANSACTIONS_KEY: &str = "transactions";
3638
const KEYSETS_TABLE_KEY: &str = "keysets_table";
3739
const KEYSET_U32_MAPPING_KEY: &str = "keyset_u32_mapping";
40+
const HAS_RECOVERED_KEY: &str = "has_recovered";
3841

3942
/// Error type for database operations
4043
#[derive(Debug)]
@@ -866,3 +869,26 @@ impl WalletDatabase for CashuKvDatabase {
866869
Ok(())
867870
}
868871
}
872+
873+
pub(super) fn read_has_recovered(
874+
store: &Arc<dyn KVStore + Send + Sync>,
875+
) -> Result<bool, TrustedError> {
876+
match store.read(CASHU_PRIMARY_KEY, "", HAS_RECOVERED_KEY) {
877+
Ok(data) => {
878+
if data.is_empty() {
879+
return Ok(false);
880+
}
881+
Ok(data[0] != 0)
882+
},
883+
Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(false),
884+
Err(e) => Err(TrustedError::IOError(e)),
885+
}
886+
}
887+
888+
pub(super) fn write_has_recovered(
889+
store: &Arc<dyn KVStore + Send + Sync>, has_recovered: bool,
890+
) -> Result<(), TrustedError> {
891+
let data = vec![if has_recovered { 1 } else { 0 }];
892+
893+
store.write(CASHU_PRIMARY_KEY, "", HAS_RECOVERED_KEY, &data).map_err(TrustedError::IOError)
894+
}

orange-sdk/src/trusted_wallet/cashu/mod.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use tokio::runtime::Runtime;
3838
/// Cashu KV store implementation
3939
pub mod cashu_store;
4040

41-
use cashu_store::CashuKvDatabase;
41+
use cashu_store::{CashuKvDatabase, read_has_recovered, write_has_recovered};
4242

4343
/// Configuration for the Cashu wallet
4444
#[derive(Debug, Clone)]
@@ -448,7 +448,7 @@ impl Cashu {
448448
},
449449
};
450450

451-
let db = Arc::new(CashuKvDatabase::new(store).map_err(|e| {
451+
let db = Arc::new(CashuKvDatabase::new(Arc::clone(&store)).map_err(|e| {
452452
InitFailure::TrustedFailure(TrustedError::Other(format!(
453453
"Failed to create Cashu database: {e}"
454454
)))
@@ -520,6 +520,26 @@ impl Cashu {
520520
}
521521
}
522522

523+
// spawn background task to recover funds if first time initializing
524+
let has_recovered = read_has_recovered(&store)?;
525+
if !has_recovered {
526+
let w = Arc::clone(&cashu_wallet);
527+
let l = Arc::clone(&logger);
528+
runtime.spawn(async move {
529+
match w.restore().await {
530+
Err(e) => log_error!(l, "Failed to restore cashu mint: {e}"),
531+
Ok(amt) => {
532+
if amt > cdk::Amount::ZERO {
533+
log_info!(l, "Restored cashu mint: {}, amt: {amt}", w.mint_url);
534+
}
535+
if let Err(e) = write_has_recovered(&store, true) {
536+
log_error!(l, "Failed to write has_recovered flag: {e:?}");
537+
}
538+
},
539+
}
540+
});
541+
}
542+
523543
Ok(Cashu {
524544
cashu_wallet,
525545
unit: cashu_config.unit,

0 commit comments

Comments
 (0)