@@ -12,7 +12,8 @@ const CREATE_ACTIVITIES_TABLE: &str = "
1212 tx_type TEXT NOT NULL CHECK (tx_type IN ('sent', 'received')),
1313 timestamp INTEGER NOT NULL CHECK (timestamp > 0),
1414 created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
15- updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now'))
15+ updated_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')),
16+ seen_at INTEGER CHECK (seen_at IS NULL OR seen_at > 0)
1617 )" ;
1718
1819const CREATE_ONCHAIN_TABLE : & str = "
@@ -641,6 +642,7 @@ impl ActivityDB {
641642 a.timestamp,
642643 a.created_at,
643644 a.updated_at,
645+ a.seen_at,
644646
645647 -- Onchain columns
646648 o.tx_id AS onchain_tx_id,
@@ -688,11 +690,12 @@ impl ActivityDB {
688690 let timestamp: i64 = row. get ( 3 ) ?;
689691 let created_at: Option < i64 > = row. get ( 4 ) ?;
690692 let updated_at: Option < i64 > = row. get ( 5 ) ?;
691- let value: i64 = row. get ( 7 ) ?;
692- let fee: i64 = row. get ( 8 ) ?;
693- let fee_rate: i64 = row. get ( 9 ) ?;
694- let confirm_timestamp: Option < i64 > = row. get ( 16 ) ?;
695- let boost_tx_ids_str: String = row. get ( 13 ) ?;
693+ let seen_at: Option < i64 > = row. get ( 6 ) ?;
694+ let value: i64 = row. get ( 8 ) ?;
695+ let fee: i64 = row. get ( 9 ) ?;
696+ let fee_rate: i64 = row. get ( 10 ) ?;
697+ let confirm_timestamp: Option < i64 > = row. get ( 17 ) ?;
698+ let boost_tx_ids_str: String = row. get ( 14 ) ?;
696699 let boost_tx_ids: Vec < String > = if boost_tx_ids_str. is_empty ( ) {
697700 Vec :: new ( )
698701 } else {
@@ -705,40 +708,43 @@ impl ActivityDB {
705708 timestamp : timestamp as u64 ,
706709 created_at : created_at. map ( |t| t as u64 ) ,
707710 updated_at : updated_at. map ( |t| t as u64 ) ,
708- tx_id : row. get ( 6 ) ?,
711+ seen_at : seen_at. map ( |t| t as u64 ) ,
712+ tx_id : row. get ( 7 ) ?,
709713 value : value as u64 ,
710714 fee : fee as u64 ,
711715 fee_rate : fee_rate as u64 ,
712- address : row. get ( 10 ) ?,
713- confirmed : row. get ( 11 ) ?,
714- is_boosted : row. get ( 12 ) ?,
716+ address : row. get ( 11 ) ?,
717+ confirmed : row. get ( 12 ) ?,
718+ is_boosted : row. get ( 13 ) ?,
715719 boost_tx_ids,
716- is_transfer : row. get ( 14 ) ?,
717- does_exist : row. get ( 15 ) ?,
720+ is_transfer : row. get ( 15 ) ?,
721+ does_exist : row. get ( 16 ) ?,
718722 confirm_timestamp : confirm_timestamp. map ( |t| t as u64 ) ,
719- channel_id : row. get ( 17 ) ?,
720- transfer_tx_id : row. get ( 18 ) ?,
723+ channel_id : row. get ( 18 ) ?,
724+ transfer_tx_id : row. get ( 19 ) ?,
721725 } ) )
722726 }
723727 "lightning" => {
724728 let timestamp: i64 = row. get ( 3 ) ?;
725729 let created_at: Option < i64 > = row. get ( 4 ) ?;
726730 let updated_at: Option < i64 > = row. get ( 5 ) ?;
727- let value: i64 = row. get ( 20 ) ?;
728- let fee: Option < i64 > = row. get ( 22 ) ?;
731+ let seen_at: Option < i64 > = row. get ( 6 ) ?;
732+ let value: i64 = row. get ( 21 ) ?;
733+ let fee: Option < i64 > = row. get ( 23 ) ?;
729734
730735 Ok ( Activity :: Lightning ( LightningActivity {
731736 id : row. get ( 0 ) ?,
732737 tx_type : Self :: parse_payment_type ( row, 2 ) ?,
733738 timestamp : timestamp as u64 ,
734739 created_at : created_at. map ( |t| t as u64 ) ,
735740 updated_at : updated_at. map ( |t| t as u64 ) ,
736- invoice : row. get ( 19 ) ?,
741+ seen_at : seen_at. map ( |t| t as u64 ) ,
742+ invoice : row. get ( 20 ) ?,
737743 value : value as u64 ,
738- status : Self :: parse_payment_state ( row, 21 ) ?,
744+ status : Self :: parse_payment_state ( row, 22 ) ?,
739745 fee : fee. map ( |f| f as u64 ) ,
740- message : row. get ( 23 ) ?,
741- preimage : row. get ( 24 ) ?,
746+ message : row. get ( 24 ) ?,
747+ preimage : row. get ( 25 ) ?,
742748 } ) )
743749 }
744750 _ => Err ( rusqlite:: Error :: InvalidColumnType (
@@ -783,7 +789,7 @@ impl ActivityDB {
783789 a.id, a.tx_type, o.tx_id, o.value, o.fee, o.fee_rate,
784790 o.address, o.confirmed, a.timestamp, o.is_boosted,
785791 o.boost_tx_ids, o.is_transfer, o.does_exist, o.confirm_timestamp,
786- o.channel_id, o.transfer_tx_id, a.created_at, a.updated_at
792+ o.channel_id, o.transfer_tx_id, a.created_at, a.updated_at, a.seen_at
787793 FROM activities a
788794 JOIN onchain_activity o ON a.id = o.id
789795 WHERE a.id = ?1" ;
@@ -800,6 +806,7 @@ impl ActivityDB {
800806 let confirm_timestamp: Option < i64 > = row. get ( 13 ) ?;
801807 let created_at: Option < i64 > = row. get ( 16 ) ?;
802808 let updated_at: Option < i64 > = row. get ( 17 ) ?;
809+ let seen_at: Option < i64 > = row. get ( 18 ) ?;
803810 let boost_tx_ids_str: String = row. get ( 10 ) ?;
804811 let boost_tx_ids: Vec < String > = if boost_tx_ids_str. is_empty ( ) {
805812 Vec :: new ( )
@@ -826,6 +833,7 @@ impl ActivityDB {
826833 transfer_tx_id : row. get ( 15 ) ?,
827834 created_at : created_at. map ( |t| t as u64 ) ,
828835 updated_at : updated_at. map ( |t| t as u64 ) ,
836+ seen_at : seen_at. map ( |t| t as u64 ) ,
829837 } ) )
830838 } ) {
831839 Ok ( activity) => Ok ( Some ( activity) ) ,
@@ -841,7 +849,7 @@ impl ActivityDB {
841849 SELECT
842850 a.id, a.tx_type, l.status, l.value, l.fee,
843851 l.invoice, l.message, a.timestamp,
844- l.preimage, a.created_at, a.updated_at
852+ l.preimage, a.created_at, a.updated_at, a.seen_at
845853 FROM activities a
846854 JOIN lightning_activity l ON a.id = l.id
847855 WHERE a.id = ?1" ;
@@ -856,6 +864,7 @@ impl ActivityDB {
856864 let timestamp: i64 = row. get ( 7 ) ?;
857865 let created_at: Option < i64 > = row. get ( 9 ) ?;
858866 let updated_at: Option < i64 > = row. get ( 10 ) ?;
867+ let seen_at: Option < i64 > = row. get ( 11 ) ?;
859868
860869 Ok ( Activity :: Lightning ( LightningActivity {
861870 id : row. get ( 0 ) ?,
@@ -869,6 +878,7 @@ impl ActivityDB {
869878 preimage : row. get ( 8 ) ?,
870879 created_at : created_at. map ( |t| t as u64 ) ,
871880 updated_at : updated_at. map ( |t| t as u64 ) ,
881+ seen_at : seen_at. map ( |t| t as u64 ) ,
872882 } ) )
873883 } ) . map_err ( |e| ActivityError :: RetrievalError {
874884 error_details : format ! ( "Failed to get lightning activity: {}" , e) ,
@@ -887,7 +897,7 @@ impl ActivityDB {
887897 a.id, a.tx_type, o.tx_id, o.value, o.fee, o.fee_rate,
888898 o.address, o.confirmed, a.timestamp, o.is_boosted,
889899 o.boost_tx_ids, o.is_transfer, o.does_exist, o.confirm_timestamp,
890- o.channel_id, o.transfer_tx_id, a.created_at, a.updated_at
900+ o.channel_id, o.transfer_tx_id, a.created_at, a.updated_at, a.seen_at
891901 FROM activities a
892902 JOIN onchain_activity o ON a.id = o.id
893903 WHERE o.tx_id = ?1 AND a.activity_type = 'onchain'
@@ -905,6 +915,7 @@ impl ActivityDB {
905915 let confirm_timestamp: Option < i64 > = row. get ( 13 ) ?;
906916 let created_at: Option < i64 > = row. get ( 16 ) ?;
907917 let updated_at: Option < i64 > = row. get ( 17 ) ?;
918+ let seen_at: Option < i64 > = row. get ( 18 ) ?;
908919 let boost_tx_ids_str: String = row. get ( 10 ) ?;
909920 let boost_tx_ids: Vec < String > = if boost_tx_ids_str. is_empty ( ) {
910921 Vec :: new ( )
@@ -931,6 +942,7 @@ impl ActivityDB {
931942 transfer_tx_id : row. get ( 15 ) ?,
932943 created_at : created_at. map ( |t| t as u64 ) ,
933944 updated_at : updated_at. map ( |t| t as u64 ) ,
945+ seen_at : seen_at. map ( |t| t as u64 ) ,
934946 } )
935947 } ) {
936948 Ok ( activity) => Ok ( Some ( activity) ) ,
@@ -1081,6 +1093,24 @@ impl ActivityDB {
10811093 Ok ( ( ) )
10821094 }
10831095
1096+ /// Marks an activity as seen by setting the seen_at timestamp.
1097+ pub fn mark_activity_as_seen ( & mut self , activity_id : & str , seen_at : u64 ) -> Result < ( ) , ActivityError > {
1098+ let rows = self . conn . execute (
1099+ "UPDATE activities SET seen_at = ?1 WHERE id = ?2" ,
1100+ rusqlite:: params![ seen_at as i64 , activity_id] ,
1101+ ) . map_err ( |e| ActivityError :: DataError {
1102+ error_details : format ! ( "Failed to mark activity as seen: {}" , e) ,
1103+ } ) ?;
1104+
1105+ if rows == 0 {
1106+ return Err ( ActivityError :: DataError {
1107+ error_details : "No activity found with given ID" . to_string ( ) ,
1108+ } ) ;
1109+ }
1110+
1111+ Ok ( ( ) )
1112+ }
1113+
10841114 /// Deletes an activity and associated data.
10851115 pub fn delete_activity_by_id ( & mut self , activity_id : & str ) -> Result < bool , ActivityError > {
10861116 let tx = self . conn . transaction ( ) . map_err ( |e| ActivityError :: DataError {
0 commit comments