Skip to content
This repository was archived by the owner on Feb 3, 2025. It is now read-only.

Commit 26c0b11

Browse files
committed
Persist payjoin sessions
1 parent c6317d9 commit 26c0b11

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

mutiny-core/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ mod test_utils;
4848
pub use crate::gossip::{GOSSIP_SYNC_TIME_KEY, NETWORK_GRAPH_KEY, PROB_SCORER_KEY};
4949
pub use crate::keymanager::generate_seed;
5050
pub use crate::ldkstorage::{CHANNEL_CLOSURE_PREFIX, CHANNEL_MANAGER_KEY, MONITORS_PREFIX_KEY};
51+
use crate::payjoin::PayjoinStorage;
5152
use crate::storage::{
5253
list_payment_info, persist_payment_info, update_nostr_contact_list, IndexItem, MutinyStorage,
5354
DEVICE_ID_KEY, EXPECTED_NETWORK_KEY, NEED_FULL_SYNC_KEY, ONCHAIN_PREFIX,
@@ -1119,6 +1120,7 @@ impl<S: MutinyStorage> MutinyWallet<S> {
11191120
// when we restart, gen a new session id
11201121
self.node_manager = Arc::new(nm_builder.build().await?);
11211122
NodeManager::start_sync(self.node_manager.clone());
1123+
NodeManager::resume_payjoins(self.node_manager.clone());
11221124

11231125
Ok(())
11241126
}
@@ -1537,6 +1539,9 @@ impl<S: MutinyStorage> MutinyWallet<S> {
15371539
let enrolled = enroller
15381540
.process_res(ohttp_response.as_ref(), context)
15391541
.map_err(|_| MutinyError::PayjoinCreateRequest)?;
1542+
self.node_manager
1543+
.storage
1544+
.persist_payjoin(enrolled.clone())?;
15401545
let pj_uri = enrolled.fallback_target();
15411546
log_debug!(self.logger, "{pj_uri}");
15421547
let wallet = self.node_manager.wallet.clone();

mutiny-core/src/nodemanager.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::event::HTLCStatus;
33
use crate::labels::LabelStorage;
44
use crate::ldkstorage::CHANNEL_CLOSURE_PREFIX;
55
use crate::logging::LOGGING_KEY;
6+
use crate::payjoin::PayjoinStorage;
67
use crate::utils::{sleep, spawn};
78
use crate::ActivityItem;
89
use crate::MutinyInvoice;
@@ -628,6 +629,19 @@ impl<S: MutinyStorage> NodeManager<S> {
628629
Ok(())
629630
}
630631

632+
/// Starts a background task to poll payjoin sessions to attempt receiving.
633+
pub(crate) fn resume_payjoins(nm: Arc<NodeManager<S>>) {
634+
let all = nm.storage.get_payjoins().unwrap_or_default();
635+
for payjoin in all {
636+
let wallet = nm.wallet.clone();
637+
let stop = nm.stop.clone();
638+
utils::spawn(async move {
639+
let pj_txid = Self::receive_payjoin(wallet, stop, payjoin).await.unwrap();
640+
log::info!("Received payjoin txid: {}", pj_txid);
641+
});
642+
}
643+
}
644+
631645
/// Creates a background process that will sync the wallet with the blockchain.
632646
/// This will also update the fee estimates every 10 minutes.
633647
pub fn start_sync(nm: Arc<NodeManager<S>>) {

mutiny-core/src/payjoin.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1+
use std::collections::HashMap;
2+
3+
use crate::error::MutinyError;
4+
use crate::storage::MutinyStorage;
5+
use hex_conservative::DisplayHex;
16
use once_cell::sync::Lazy;
7+
use payjoin::receive::v2::Enrolled;
28
use payjoin::OhttpKeys;
39
use url::Url;
410

@@ -11,6 +17,34 @@ pub(crate) static OHTTP_RELAYS: [Lazy<Url>; 3] = [
1117
pub(crate) static PAYJOIN_DIR: Lazy<Url> =
1218
Lazy::new(|| Url::parse("https://payjo.in").expect("Invalid URL"));
1319

20+
pub trait PayjoinStorage {
21+
fn get_payjoin(&self, id: &[u8; 33]) -> Result<Option<Enrolled>, MutinyError>;
22+
fn get_payjoins(&self) -> Result<Vec<Enrolled>, MutinyError>;
23+
fn persist_payjoin(&self, session: Enrolled) -> Result<(), MutinyError>;
24+
}
25+
26+
const PAYJOIN_KEY_PREFIX: &str = "payjoin/";
27+
28+
fn get_payjoin_key(id: &[u8; 33]) -> String {
29+
format!("{PAYJOIN_KEY_PREFIX}{}", id.as_hex())
30+
}
31+
32+
impl<S: MutinyStorage> PayjoinStorage for S {
33+
fn get_payjoin(&self, id: &[u8; 33]) -> Result<Option<Enrolled>, MutinyError> {
34+
let sessions = self.get_data(get_payjoin_key(id))?;
35+
Ok(sessions)
36+
}
37+
38+
fn get_payjoins(&self) -> Result<Vec<Enrolled>, MutinyError> {
39+
let map: HashMap<String, Enrolled> = self.scan(PAYJOIN_KEY_PREFIX, None)?;
40+
Ok(map.values().map(|v| v.to_owned()).collect())
41+
}
42+
43+
fn persist_payjoin(&self, session: Enrolled) -> Result<(), MutinyError> {
44+
self.set_data(get_payjoin_key(&session.pubkey()), session, None)
45+
}
46+
}
47+
1448
pub async fn fetch_ohttp_keys(
1549
_ohttp_relay: Url,
1650
directory: Url,

0 commit comments

Comments
 (0)