diff --git a/.gitignore b/.gitignore index 41d487b15..1c59d5302 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ debug/ target/ .vim/ .direnv +.idea # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock index cde3ff9c7..e79410426 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2567,6 +2567,7 @@ dependencies = [ "bincode", "bip39", "bitcoin 0.30.2", + "bitcoin-waila", "cbc", "cfg-if", "chrono", diff --git a/mutiny-core/Cargo.toml b/mutiny-core/Cargo.toml index c6a606790..e4c0f1a9e 100644 --- a/mutiny-core/Cargo.toml +++ b/mutiny-core/Cargo.toml @@ -48,6 +48,7 @@ payjoin = { version = "0.13.0", features = ["send", "base64"] } bincode = "1.3.3" hex-conservative = "0.1.1" async-lock = "3.2.0" +bitcoin-waila = { git = "https://github.com/mutinywallet/bitcoin-waila", rev = "1d6c416fc0abaa2efa78e3dcf28450975d8f7bfe" } fedimint-client = "0.3.0" fedimint-core = "0.3.0" diff --git a/mutiny-core/src/nostr/mod.rs b/mutiny-core/src/nostr/mod.rs index 12878900c..bf47aef46 100644 --- a/mutiny-core/src/nostr/mod.rs +++ b/mutiny-core/src/nostr/mod.rs @@ -1404,8 +1404,8 @@ impl NostrManager { Ok(()) } - /// Handles an encrypted direct message. If it is an invoice we add it to our pending - /// invoice storage. + /// Handles an encrypted direct message. If it finds an invoice in the dm, we add it + /// to our pending invoice storage. pub async fn handle_direct_message( &self, event: Event, @@ -1443,23 +1443,39 @@ impl NostrManager { } } - // handle it like a pay invoice NWC request, to see if it is valid - let params = PayInvoiceRequestParams { - id: None, - invoice: decrypted, - amount: None, - }; - let invoice: Bolt11Invoice = match check_valid_nwc_invoice(¶ms, invoice_handler).await { - Ok(Some(invoice)) => invoice, - Ok(None) => return Ok(()), - Err(msg) => { - log_debug!(self.logger, "Not adding DM'd invoice: {msg}"); + // loop through dm to check for invoice + for word in decrypted.split_whitespace() { + // ignore word if too short + if word.len() > 15 { + let invoice_request_param = match bitcoin_waila::PaymentParams::from_str(word) { + // if not an invoice, go to next word in dm + Ok(param) => match param.invoice() { + Some(invoice) => PayInvoiceRequestParams { + id: None, + invoice: invoice.to_string(), + amount: None, + }, + None => continue, + }, + Err(_) => continue, + }; + + // handle it like a pay invoice NWC request, to see if it is valid + let invoice: Bolt11Invoice = + match check_valid_nwc_invoice(&invoice_request_param, invoice_handler).await { + Ok(Some(invoice)) => invoice, + Ok(None) => return Ok(()), + Err(msg) => { + log_debug!(self.logger, "Not adding DM'd invoice: {msg}"); + return Ok(()); + } + }; + self.save_pending_nwc_invoice(None, event.id, event.pubkey, invoice, None) + .await?; + return Ok(()); } - }; - - self.save_pending_nwc_invoice(None, event.id, event.pubkey, invoice, None) - .await?; + } Ok(()) } @@ -2322,9 +2338,9 @@ mod test { .unwrap() .to_event(&user) .unwrap(); + block_on(nostr_manager.handle_direct_message(dm, &inv_handler)).unwrap(); let pending = nostr_manager.get_pending_nwc_invoices().unwrap(); assert!(pending.is_empty()); - block_on(nostr_manager.handle_direct_message(dm, &inv_handler)).unwrap(); // create invoice let secp = Secp256k1::new(); @@ -2371,6 +2387,20 @@ mod test { .unwrap(); block_on(nostr_manager.handle_direct_message(dm, &inv_handler)).unwrap(); let pending = nostr_manager.get_pending_nwc_invoices().unwrap(); + assert!(!pending.is_empty()); + + // valid invoice in dm along with message should be added + let dm = EventBuilder::encrypted_direct_msg( + &user, + nostr_keys.public_key(), + format!("invoice for you to pay {}", invoice), + None, + ) + .unwrap() + .to_event(&user) + .unwrap(); + block_on(nostr_manager.handle_direct_message(dm, &inv_handler)).unwrap(); + let pending = nostr_manager.get_pending_nwc_invoices().unwrap(); assert!(!pending.is_empty()) }