@@ -966,6 +966,35 @@ impl<S: MutinyStorage> NostrManager<S> {
966966 Ok ( event_id)
967967 }
968968
969+ /// Removes an invoice from the pending list
970+ pub ( crate ) async fn remove_pending_nwc_invoice (
971+ & self ,
972+ hash : & sha256:: Hash ,
973+ ) -> Result < ( ) , MutinyError > {
974+ // get lock for writing
975+ self . pending_nwc_lock . lock ( ) . await ;
976+
977+ let mut pending: Vec < PendingNwcInvoice > = self
978+ . storage
979+ . get_data ( PENDING_NWC_EVENTS_KEY ) ?
980+ . unwrap_or_default ( ) ;
981+
982+ let original_len = pending. len ( ) ;
983+
984+ // remove from storage
985+ pending. retain ( |x| x. invoice . payment_hash ( ) != hash) ;
986+
987+ // if we didn't remove anything, we don't need to save
988+ if original_len == pending. len ( ) {
989+ return Ok ( ( ) ) ;
990+ }
991+
992+ self . storage
993+ . set_data ( PENDING_NWC_EVENTS_KEY . to_string ( ) , pending, None ) ?;
994+
995+ Ok ( ( ) )
996+ }
997+
969998 /// Approves an invoice and sends the payment
970999 pub async fn approve_invoice (
9711000 & self ,
@@ -998,19 +1027,8 @@ impl<S: MutinyStorage> NostrManager<S> {
9981027 }
9991028 } ;
10001029
1001- // get lock for writing
1002- self . pending_nwc_lock . lock ( ) . await ;
1003-
1004- // get from storage again, in case it was updated
1005- let mut pending: Vec < PendingNwcInvoice > = self
1006- . storage
1007- . get_data ( PENDING_NWC_EVENTS_KEY ) ?
1008- . unwrap_or_default ( ) ;
1009-
1010- // remove from storage
1011- pending. retain ( |x| x. invoice . payment_hash ( ) != & hash) ;
1012- self . storage
1013- . set_data ( PENDING_NWC_EVENTS_KEY . to_string ( ) , pending, None ) ?;
1030+ // remove from our pending list
1031+ self . remove_pending_nwc_invoice ( & hash) . await ?;
10141032
10151033 Ok ( event_id)
10161034 }
@@ -1112,23 +1130,45 @@ impl<S: MutinyStorage> NostrManager<S> {
11121130 Ok ( ( ) )
11131131 }
11141132
1115- /// Goes through all pending NWC invoices and removes the expired ones
1116- pub async fn clear_expired_nwc_invoices ( & self ) -> Result < ( ) , MutinyError > {
1133+ /// Goes through all pending NWC invoices and removes invoices that are
1134+ /// expired or have been paid
1135+ pub async fn clear_invalid_nwc_invoices (
1136+ & self ,
1137+ invoice_handler : & impl InvoiceHandler ,
1138+ ) -> Result < ( ) , MutinyError > {
11171139 self . pending_nwc_lock . lock ( ) . await ;
1118- let mut invoices: Vec < PendingNwcInvoice > = self
1140+ let invoices: Vec < PendingNwcInvoice > = self
11191141 . storage
11201142 . get_data ( PENDING_NWC_EVENTS_KEY ) ?
11211143 . unwrap_or_default ( ) ;
11221144
1123- // remove expired invoices
1124- invoices. retain ( |x| !x. is_expired ( ) ) ;
1145+ let mut new_invoices = Vec :: with_capacity ( invoices. len ( ) ) ;
1146+
1147+ for inv in invoices {
1148+ // remove expired invoices
1149+ if inv. is_expired ( ) {
1150+ continue ;
1151+ }
1152+
1153+ // remove paid invoices
1154+ if invoice_handler
1155+ . lookup_payment ( & inv. invoice . payment_hash ( ) . into_32 ( ) )
1156+ . await
1157+ . is_some_and ( |p| p. status == HTLCStatus :: Succeeded )
1158+ {
1159+ continue ;
1160+ }
1161+
1162+ // keep the invoice if it is still valid
1163+ new_invoices. push ( inv) ;
1164+ }
11251165
11261166 // sort and dedup
1127- invoices . sort ( ) ;
1128- invoices . dedup ( ) ;
1167+ new_invoices . sort ( ) ;
1168+ new_invoices . dedup ( ) ;
11291169
11301170 self . storage
1131- . set_data ( PENDING_NWC_EVENTS_KEY . to_string ( ) , invoices , None ) ?;
1171+ . set_data ( PENDING_NWC_EVENTS_KEY . to_string ( ) , new_invoices , None ) ?;
11321172
11331173 Ok ( ( ) )
11341174 }
0 commit comments