11use bitcoin:: address:: NetworkChecked ;
2+ use bitcoin:: block:: Header ;
23use bitcoin:: psbt:: Psbt ;
3- use bitcoin:: { Script , Transaction , Txid } ;
4+ use bitcoin:: { BlockHash , Script , Transaction , Txid } ;
5+ use lightning:: chain:: transaction:: TransactionData ;
46
57use crate :: config:: PAYJOIN_REQUEST_TIMEOUT ;
68use crate :: error:: Error ;
@@ -13,7 +15,7 @@ use crate::types::{ChainSource, EventQueue, PaymentStore, Wallet};
1315use crate :: Event ;
1416use crate :: PaymentDetails ;
1517
16- use lightning:: chain:: Filter ;
18+ use lightning:: chain:: { BestBlock , Confirm , Filter } ;
1719use lightning:: ln:: channelmanager:: PaymentId ;
1820use lightning:: log_error;
1921use lightning:: util:: logger:: Logger ;
@@ -165,4 +167,99 @@ impl PayjoinHandler {
165167 Err ( Error :: PayjoinRequestSendingFailed )
166168 }
167169 }
170+
171+ fn internal_transactions_confirmed (
172+ & self , header : & Header , txdata : & TransactionData , height : u32 ,
173+ ) {
174+ for ( _, tx) in txdata {
175+ let confirmed_tx_txid = tx. txid ( ) ;
176+ let payment_store = self . payment_store . clone ( ) ;
177+ let payment_id = self . payment_id ( & confirmed_tx_txid) ;
178+ let payjoin_tx_filter = |payment_details : & & PaymentDetails | {
179+ payment_details. txid == Some ( confirmed_tx_txid)
180+ && payment_details. amount_msat . is_some ( )
181+ } ;
182+ let payjoin_tx_details = payment_store. list_filter ( payjoin_tx_filter) ;
183+ if let Some ( payjoin_tx_details) = payjoin_tx_details. get ( 0 ) {
184+ let mut payment_update = PaymentDetailsUpdate :: new ( payjoin_tx_details. id ) ;
185+ payment_update. status = Some ( PaymentStatus :: Succeeded ) ;
186+ payment_update. best_block = Some ( BestBlock :: new ( header. block_hash ( ) , height) ) ;
187+ let _ = payment_store. update ( & payment_update) ;
188+ let _ = self . event_queue . add_event ( Event :: PayjoinPaymentSuccessful {
189+ txid : confirmed_tx_txid,
190+ amount_sats : payjoin_tx_details
191+ . amount_msat
192+ . expect ( "Unreachable, asserted in `payjoin_tx_filter`" ) ,
193+ is_original_psbt_modified : if payment_id == payjoin_tx_details. id {
194+ false
195+ } else {
196+ true
197+ } ,
198+ } ) ;
199+ // check if this is the original psbt transaction
200+ } else if let Some ( payment_details) = payment_store. get ( & payment_id) {
201+ let mut payment_update = PaymentDetailsUpdate :: new ( payment_id) ;
202+ payment_update. status = Some ( PaymentStatus :: Succeeded ) ;
203+ let _ = payment_store. update ( & payment_update) ;
204+ payment_update. best_block = Some ( BestBlock :: new ( header. block_hash ( ) , height) ) ;
205+ payment_update. txid = Some ( confirmed_tx_txid) ;
206+ let _ = self . event_queue . add_event ( Event :: PayjoinPaymentSuccessful {
207+ txid : confirmed_tx_txid,
208+ amount_sats : payment_details
209+ . amount_msat
210+ . expect ( "Unreachable, payjoin transactions must have amount" ) ,
211+ is_original_psbt_modified : false ,
212+ } ) ;
213+ }
214+ }
215+ }
216+
217+ fn internal_get_relevant_txids ( & self ) -> Vec < ( Txid , u32 , Option < BlockHash > ) > {
218+ let payjoin_tx_filter = |payment_details : & & PaymentDetails | {
219+ payment_details. txid . is_some ( )
220+ && payment_details. status == PaymentStatus :: Succeeded
221+ && payment_details. kind == PaymentKind :: Payjoin
222+ } ;
223+ let payjoin_tx_details = self . payment_store . list_filter ( payjoin_tx_filter) ;
224+ let mut ret = Vec :: new ( ) ;
225+ for payjoin_tx_details in payjoin_tx_details {
226+ if let ( Some ( txid) , Some ( best_block) ) =
227+ ( payjoin_tx_details. txid , payjoin_tx_details. best_block )
228+ {
229+ ret. push ( ( txid, best_block. height , Some ( best_block. block_hash ) ) ) ;
230+ }
231+ }
232+ ret
233+ }
234+
235+ fn internal_best_block_updated ( & self , height : u32 , block_hash : BlockHash ) {
236+ let payment_store = self . payment_store . clone ( ) ;
237+ let payjoin_tx_filter = |payment_details : & & PaymentDetails | {
238+ payment_details. kind == PaymentKind :: Payjoin
239+ && payment_details. status == PaymentStatus :: Succeeded
240+ } ;
241+ let payjoin_tx_details = payment_store. list_filter ( payjoin_tx_filter) ;
242+ for payjoin_tx_details in payjoin_tx_details {
243+ let mut payment_update = PaymentDetailsUpdate :: new ( payjoin_tx_details. id ) ;
244+ payment_update. best_block = Some ( BestBlock :: new ( block_hash, height) ) ;
245+ let _ = payment_store. update ( & payment_update) ;
246+ }
247+ }
248+ }
249+
250+ impl Confirm for PayjoinHandler {
251+ fn transactions_confirmed ( & self , header : & Header , txdata : & TransactionData , height : u32 ) {
252+ self . internal_transactions_confirmed ( header, txdata, height) ;
253+ }
254+
255+ fn get_relevant_txids ( & self ) -> Vec < ( Txid , u32 , Option < BlockHash > ) > {
256+ self . internal_get_relevant_txids ( )
257+ }
258+
259+ fn best_block_updated ( & self , header : & Header , height : u32 ) {
260+ let block_hash = header. block_hash ( ) ;
261+ self . internal_best_block_updated ( height, block_hash) ;
262+ }
263+
264+ fn transaction_unconfirmed ( & self , _txid : & Txid ) { }
168265}
0 commit comments