@@ -5,7 +5,7 @@ use common::{create_service_and_client_nodes, get_lsps_message};
5
5
6
6
use lightning:: util:: hash_tables:: HashSet ;
7
7
use lightning_liquidity:: events:: LiquidityEvent ;
8
- use lightning_liquidity:: lsps0:: ser:: LSPSRequestId ;
8
+ use lightning_liquidity:: lsps0:: ser:: { LSPSDateTime , LSPSRequestId } ;
9
9
use lightning_liquidity:: lsps5:: client:: LSPS5ClientConfig ;
10
10
use lightning_liquidity:: lsps5:: event:: { LSPS5ClientEvent , LSPS5ServiceEvent } ;
11
11
use lightning_liquidity:: lsps5:: msgs:: WebhookNotificationMethod ;
@@ -14,7 +14,7 @@ use lightning_liquidity::lsps5::utils::sign_notification;
14
14
use lightning_liquidity:: { LiquidityClientConfig , LiquidityServiceConfig } ;
15
15
16
16
use bitcoin:: secp256k1:: SecretKey ;
17
- use chrono:: { Duration , Utc } ;
17
+ use chrono:: Duration ;
18
18
use lightning:: ln:: peer_handler:: CustomMessageHandler ;
19
19
use serde_json:: json;
20
20
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
@@ -70,7 +70,10 @@ impl HttpClient for MockHttpClientWrapper {
70
70
71
71
#[ test]
72
72
fn webhook_registration_flow ( ) {
73
- let lsps5_service_config: LSPS5ServiceConfig = LSPS5ServiceConfig :: default ( ) ;
73
+ let mock_client = Arc :: new ( MockHttpClient :: new ( true ) ) ;
74
+ let mut lsps5_service_config: LSPS5ServiceConfig = LSPS5ServiceConfig :: default ( ) ;
75
+ lsps5_service_config =
76
+ lsps5_service_config. with_http_client ( MockHttpClientWrapper ( mock_client) ) ;
74
77
let service_config = LiquidityServiceConfig {
75
78
#[ cfg( lsps1_service) ]
76
79
lsps1_service_config : None ,
@@ -154,6 +157,8 @@ fn webhook_registration_flow() {
154
157
_ => panic ! ( "Unexpected event" ) ,
155
158
}
156
159
160
+ service_node. liquidity_manager . next_event ( ) . unwrap ( ) ; // Skip the WebhookNotificationSent event
161
+
157
162
// Test list_webhooks - now capture the request ID
158
163
let list_request_id = client_handler
159
164
. list_webhooks ( service_node_id)
@@ -256,6 +261,8 @@ fn webhook_registration_flow() {
256
261
_ => panic ! ( "Unexpected event" ) ,
257
262
}
258
263
264
+ service_node. liquidity_manager . next_event ( ) . unwrap ( ) ; // Skip the WebhookNotificationSent event
265
+
259
266
// Test remove_webhook - now capture the request ID
260
267
let remove_request_id = client_handler
261
268
. remove_webhook ( service_node_id, app_name. to_string ( ) )
@@ -300,7 +307,10 @@ fn webhook_registration_flow() {
300
307
301
308
#[ test]
302
309
fn webhook_error_handling_test ( ) {
303
- let lsps5_service_config: LSPS5ServiceConfig = LSPS5ServiceConfig :: default ( ) ;
310
+ let mock_client = Arc :: new ( MockHttpClient :: new ( true ) ) ;
311
+ let mut lsps5_service_config: LSPS5ServiceConfig = LSPS5ServiceConfig :: default ( ) ;
312
+ lsps5_service_config =
313
+ lsps5_service_config. with_http_client ( MockHttpClientWrapper ( mock_client) ) ;
304
314
let service_config = LiquidityServiceConfig {
305
315
#[ cfg( lsps1_service) ]
306
316
lsps1_service_config : None ,
@@ -987,7 +997,7 @@ fn unknown_method_and_malformed_notification_test() {
987
997
988
998
// Test Case 1: Unknown notification method
989
999
// Spec: "Notification delivery services MUST ignore any notification method it does not recognize."
990
- let timestamp1 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1000
+ let timestamp1 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
991
1001
let unknown_notification = create_notification ( "lsps5.unknown_method" , json ! ( { "some" : "data" } ) ) ;
992
1002
let body1 = unknown_notification. to_string ( ) ;
993
1003
let signature1 = sign_notification_with_key ( & body1, & timestamp1) ;
@@ -1008,7 +1018,7 @@ fn unknown_method_and_malformed_notification_test() {
1008
1018
} )
1009
1019
. to_string ( ) ;
1010
1020
1011
- let timestamp2 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1021
+ let timestamp2 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1012
1022
let signature2 = sign_notification_with_key ( & invalid_jsonrpc, & timestamp2) ;
1013
1023
1014
1024
let invalid_jsonrpc_result = client_handler. parse_webhook_notification (
@@ -1030,7 +1040,7 @@ fn unknown_method_and_malformed_notification_test() {
1030
1040
} )
1031
1041
. to_string ( ) ;
1032
1042
1033
- let timestamp3 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1043
+ let timestamp3 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1034
1044
let signature3 = sign_notification_with_key ( & missing_params, & timestamp3) ;
1035
1045
1036
1046
let missing_params_result = client_handler. parse_webhook_notification (
@@ -1045,7 +1055,7 @@ fn unknown_method_and_malformed_notification_test() {
1045
1055
1046
1056
// Test Case 4: Extra unrecognized parameters in notification
1047
1057
// Spec: "Notification delivery services MUST ignore any parameters it does not recognize."
1048
- let timestamp4 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1058
+ let timestamp4 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1049
1059
let extra_params_notification = create_notification (
1050
1060
"lsps5.expiry_soon" ,
1051
1061
json ! ( {
@@ -1068,7 +1078,7 @@ fn unknown_method_and_malformed_notification_test() {
1068
1078
1069
1079
// Test Case 5: Valid signature verification
1070
1080
// Spec requires validating the signature against the timestamp and notification body
1071
- let timestamp5 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1081
+ let timestamp5 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1072
1082
let valid_notification = create_notification ( "lsps5.payment_incoming" , json ! ( { } ) ) ;
1073
1083
let body5 = valid_notification. to_string ( ) ;
1074
1084
let signature5 = sign_notification_with_key ( & body5, & timestamp5) ;
@@ -1081,7 +1091,7 @@ fn unknown_method_and_malformed_notification_test() {
1081
1091
1082
1092
// Test Case 6: Invalid signature
1083
1093
// Spec: The notification delivery service "MUST validate the signature against the message template"
1084
- let timestamp6 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1094
+ let timestamp6 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1085
1095
let notification6 = create_notification ( "lsps5.payment_incoming" , json ! ( { } ) ) ;
1086
1096
let body6 = notification6. to_string ( ) ;
1087
1097
let invalid_signature = "lspsig:abcdef1234567890" ; // Invalid signature
@@ -1098,7 +1108,7 @@ fn unknown_method_and_malformed_notification_test() {
1098
1108
1099
1109
// Test Case 7: Invalid JSON
1100
1110
// Spec requires the body to be a valid JSON-RPC 2.0 Notification Object
1101
- let timestamp7 = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1111
+ let timestamp7 = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1102
1112
let invalid_json = "{not valid json" ;
1103
1113
let signature7 = sign_notification_with_key ( invalid_json, & timestamp7) ;
1104
1114
@@ -1123,7 +1133,7 @@ fn unknown_method_and_malformed_notification_test() {
1123
1133
] ;
1124
1134
1125
1135
for ( method, params) in standard_methods. iter ( ) {
1126
- let timestamp = Utc :: now ( ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1136
+ let timestamp = LSPSDateTime :: now ( ) . to_rfc3339 ( ) ;
1127
1137
let notification = create_notification ( method, params. clone ( ) ) ;
1128
1138
let body = notification. to_string ( ) ;
1129
1139
let signature = sign_notification_with_key ( & body, & timestamp) ;
@@ -1139,9 +1149,10 @@ fn unknown_method_and_malformed_notification_test() {
1139
1149
// Spec requires timestamp to be within 10 minutes of local time
1140
1150
1141
1151
let generate_timestamp_with_offset = |offset_minutes : i64 | -> String {
1142
- let now = Utc :: now ( ) ;
1143
- let adjusted_time = now + chrono:: Duration :: minutes ( offset_minutes) ;
1144
- adjusted_time. format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( )
1152
+ LSPSDateTime :: now ( )
1153
+ . checked_add_signed ( Duration :: minutes ( offset_minutes) )
1154
+ . unwrap ( )
1155
+ . to_rfc3339 ( )
1145
1156
} ;
1146
1157
1147
1158
// Test with timestamp too old (more than 10 minutes in the past)
@@ -1646,11 +1657,11 @@ fn out_of_window_timestamp_test() {
1646
1657
// Create timestamps outside the 10-minute window
1647
1658
// Past timestamp (20 minutes ago)
1648
1659
let past_timestamp =
1649
- ( Utc :: now ( ) - Duration :: minutes ( 20 ) ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1660
+ LSPSDateTime :: now ( ) . checked_sub_signed ( Duration :: minutes ( 20 ) ) . unwrap ( ) . to_rfc3339 ( ) ;
1650
1661
1651
1662
// Future timestamp (15 minutes in future)
1652
1663
let future_timestamp =
1653
- ( Utc :: now ( ) + Duration :: minutes ( 15 ) ) . format ( "%Y-%m-%dT%H:%M:%S%.3fZ" ) . to_string ( ) ;
1664
+ LSPSDateTime :: now ( ) . checked_add_signed ( Duration :: minutes ( 15 ) ) . unwrap ( ) . to_rfc3339 ( ) ;
1654
1665
1655
1666
// Try past timestamp
1656
1667
let past_result = client_handler. parse_webhook_notification (
0 commit comments