Skip to content

Commit 43a2d2f

Browse files
Add LSPS5 event enums for webhook operations
- Introduce LSPS5ServiceEvent for LSPS-side webhook events including registration, listing, removal, and notification. - Define LSPS5ClientEvent for handling webhook outcomes on the client (Lightning node) side. - Outline WebhookNotificationParams enum to support notification-specific parameters. - Improve LSPS5 event documentation and field naming - Rename client/lsp fields to counterparty_node_id for consistent terminology - Replace generic String types with more specific Lsps5AppName and Lsps5WebhookUrl - Add comprehensive documentation for all events and fields - Include format specifications (UTF-8, ISO8601) and size constraints - Add request_id field to all relevant events for consistent request tracking - Provide detailed descriptions of error codes and their meanings - Use complete sentences in documentation comments
1 parent aa83f9f commit 43a2d2f

File tree

1 file changed

+283
-0
lines changed

1 file changed

+283
-0
lines changed
Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
// This file is Copyright its original authors, visible in version control
2+
// history.
3+
//
4+
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
5+
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
7+
// You may not use this file except in accordance with one or both of these
8+
// licenses.
9+
10+
//! Contains bLIP-55 / LSPS5 event types
11+
12+
use crate::lsps0::ser::LSPSRequestId;
13+
use alloc::string::String;
14+
use alloc::vec::Vec;
15+
use bitcoin::secp256k1::PublicKey;
16+
use lightning::util::hash_tables::HashMap;
17+
18+
use super::msgs::LSPS5AppName;
19+
use super::msgs::LSPS5Error;
20+
use super::msgs::LSPS5WebhookUrl;
21+
use super::msgs::WebhookNotification;
22+
23+
/// An event which an bLIP-55 / LSPS5 server should take some action in response to.
24+
#[derive(Debug, Clone, PartialEq, Eq)]
25+
pub enum LSPS5ServiceEvent {
26+
/// A notification needs to be sent to a client's webhook.
27+
///
28+
/// This event is triggered when the LSP needs to notify a client about an event
29+
/// via their registered webhook. The LSP must make an HTTP POST request to the
30+
/// provided URL with the specified headers and notification content.
31+
///
32+
/// When this event occurs, the LSP should:
33+
/// 1. Send an HTTP POST request to the specified webhook URL
34+
/// 2. Include all provided headers in the request
35+
/// 3. Send the JSON-serialized notification as the request body
36+
/// 4. Handle any HTTP errors according to the LSP's retry policy
37+
///
38+
/// The notification is signed using the LSP's node ID to ensure authenticity
39+
/// when received by the client. The client verifies this signature using
40+
/// [`parse_webhook_notification`], which guards against replay attacks and tampering.
41+
///
42+
/// If the HTTP request fails, the LSP may implement a retry policy according to its
43+
/// implementation preferences, but must respect rate-limiting as defined in
44+
/// [`notification_cooldown_hours`].
45+
///
46+
/// [`parse_webhook_notification`]: super::client::LSPS5ClientHandler::parse_webhook_notification
47+
/// [`notification_cooldown_hours`]: super::service::LSPS5ServiceConfig::notification_cooldown_hours
48+
SendWebhookNotification {
49+
/// Client node ID to be notified.
50+
counterparty_node_id: PublicKey,
51+
/// App name to be notified.
52+
///
53+
/// This identifies which webhook registration should be notified.
54+
///
55+
/// **Note**: The [`app_name`] must have been previously registered via [`lsps5.set_webhook`].
56+
///
57+
/// [`app_name`]: super::msgs::LSPS5AppName
58+
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
59+
app_name: LSPS5AppName,
60+
/// URL that to be contacted.
61+
///
62+
/// This is the webhook URL (HTTPS) provided by the client during registration.
63+
///
64+
/// **Note**: The URL must be a valid HTTPS URL that points to a public host.
65+
///
66+
/// [`url`]: super::msgs::LSPS5WebhookUrl
67+
url: LSPS5WebhookUrl,
68+
/// Notification method with its parameters.
69+
///
70+
/// This contains the type of notification and any associated data to be sent to the client.
71+
notification: WebhookNotification,
72+
/// Headers to be included in the HTTP POST request.
73+
///
74+
/// This is a map of HTTP header key-value pairs. It will include:
75+
/// - `"Content-Type"`: with a value like `"application/json"`.
76+
/// - `"x-lsps5-timestamp"`: with the timestamp in RFC3339 format (`"YYYY-MM-DDThh:mm:ss.uuuZ"`).
77+
/// - `"x-lsps5-signature"`: with the signature of the notification payload, signed using the LSP's node ID.
78+
/// Other custom headers may also be included as needed.
79+
headers: HashMap<String, String>,
80+
},
81+
}
82+
83+
/// An event which an LSPS5 client should take some action in response to.
84+
#[derive(Debug, Clone, PartialEq, Eq)]
85+
pub enum LSPS5ClientEvent {
86+
/// A webhook was successfully registered with the LSP.
87+
///
88+
/// This event is triggered when the LSP confirms successful registration
89+
/// of a webhook via [`lsps5.set_webhook`]. The client has received a successful
90+
/// response with information about the total number of webhooks registered and limits.
91+
///
92+
/// When this event occurs, the client should:
93+
/// 1. Update any UI to reflect the successful registration
94+
/// 2. Store the webhook registration details if needed locally
95+
/// 3. Prepare to receive notifications at the registered webhook URL
96+
/// 4. Note that if `no_change` is `true`, the LSP did not send a test notification
97+
///
98+
/// The [`app_name`] and [`url`] both must respect maximum lengths of
99+
/// [`MAX_APP_NAME_LENGTH`] and [`MAX_WEBHOOK_URL_LENGTH`] respectively, and the
100+
/// [`url`] must use HTTPS.
101+
///
102+
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
103+
/// [`app_name`]: super::msgs::LSPS5AppName
104+
/// [`url`]: super::msgs::LSPS5WebhookUrl
105+
/// [`MAX_APP_NAME_LENGTH`]: super::msgs::MAX_APP_NAME_LENGTH
106+
/// [`MAX_WEBHOOK_URL_LENGTH`]: super::msgs::MAX_WEBHOOK_URL_LENGTH
107+
WebhookRegistered {
108+
/// The node id of the LSP that confirmed the registration.
109+
counterparty_node_id: PublicKey,
110+
/// Current number of webhooks registered for this client.
111+
num_webhooks: u32,
112+
/// Maximum number of webhooks allowed by LSP.
113+
max_webhooks: u32,
114+
/// Whether this was an unchanged registration (same app_name and URL).
115+
/// If true, the LSP didn't send a webhook notification for this registration.
116+
no_change: bool,
117+
/// The app name that was registered.
118+
app_name: LSPS5AppName,
119+
/// The webhook URL that was registered.
120+
url: LSPS5WebhookUrl,
121+
/// The identifier of the issued bLIP-55 / LSPS5 webhook registration request.
122+
///
123+
/// This can be used to track which request this event corresponds to.
124+
request_id: LSPSRequestId,
125+
},
126+
127+
/// A webhook registration attempt failed.
128+
///
129+
/// This event is triggered when the LSP rejects a webhook registration
130+
/// via [`lsps5.set_webhook`]. This failure can occur for several reasons:
131+
///
132+
/// When this event occurs, the client should:
133+
/// 1. Present an appropriate error message to the user
134+
/// 2. Consider retry strategies based on the specific error
135+
/// 3. If the error is due to reaching webhook limits, prompt the user to remove
136+
/// unused webhooks before trying again
137+
///
138+
/// Common error cases include:
139+
/// - The [`app_name`] exceeds [`MAX_APP_NAME_LENGTH`] (error [`AppNameTooLong`])
140+
/// - The [`url`] exceeds [`MAX_WEBHOOK_URL_LENGTH`] (error [`WebhookUrlTooLong`])
141+
/// - The [`url`] uses an unsupported protocol; HTTPS is required (error [`UnsupportedProtocol`])
142+
/// - Maximum number of webhooks per client has been reached (error [`TooManyWebhooks`])
143+
///
144+
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
145+
/// [`app_name`]: super::msgs::LSPS5AppName
146+
/// [`url`]: super::msgs::LSPS5WebhookUrl
147+
/// [`MAX_APP_NAME_LENGTH`]: super::msgs::MAX_APP_NAME_LENGTH
148+
/// [`MAX_WEBHOOK_URL_LENGTH`]: super::msgs::MAX_WEBHOOK_URL_LENGTH
149+
/// [`AppNameTooLong`]: super::msgs::LSPS5ProtocolError::AppNameTooLong
150+
/// [`WebhookUrlTooLong`]: super::msgs::LSPS5ProtocolError::WebhookUrlTooLong
151+
/// [`UnsupportedProtocol`]: super::msgs::LSPS5ProtocolError::UnsupportedProtocol
152+
/// [`TooManyWebhooks`]: super::msgs::LSPS5ProtocolError::TooManyWebhooks
153+
WebhookRegistrationFailed {
154+
/// The node id of the LSP that rejected the registration.
155+
counterparty_node_id: PublicKey,
156+
/// Error from the LSP.
157+
error: LSPS5Error,
158+
/// The app name that was attempted.
159+
app_name: LSPS5AppName,
160+
/// The webhook URL that was attempted.
161+
url: LSPS5WebhookUrl,
162+
/// The identifier of the issued bLIP-55 / LSPS5 webhook registration request.
163+
///
164+
/// This can be used to track which request this event corresponds to.
165+
request_id: LSPSRequestId,
166+
},
167+
168+
/// The list of registered webhooks was successfully retrieved.
169+
///
170+
/// This event is triggered when the LSP responds to a
171+
/// [`lsps5.list_webhooks`] request. The client now has an up-to-date
172+
/// list of all registered webhook app names.
173+
///
174+
/// When this event occurs, the client should:
175+
/// 1. Update any UI to display the list of registered webhooks
176+
/// 2. Update any local cache or state about registered webhooks
177+
/// 3. Check if the number of webhooks approaches the maximum allowed limit
178+
///
179+
/// This listing only provides the app names; to get the URLs, the client would
180+
/// need to maintain its own records from registration events.
181+
///
182+
/// [`lsps5.list_webhooks`]: super::msgs::LSPS5Request::ListWebhooks
183+
WebhooksListed {
184+
/// The node id of the LSP that provided the list.
185+
counterparty_node_id: PublicKey,
186+
/// List of app names with registered webhooks.
187+
app_names: Vec<LSPS5AppName>,
188+
/// Maximum number of webhooks allowed by LSP.
189+
max_webhooks: u32,
190+
/// The identifier of the issued bLIP-55 / LSPS5 list webhooks request.
191+
///
192+
/// This can be used to track which request this event corresponds to.
193+
request_id: LSPSRequestId,
194+
},
195+
196+
/// The attempt to list webhooks failed.
197+
///
198+
/// This event is triggered when the LSP rejects a
199+
/// [`lsps5.list_webhooks`] request. This is uncommon but might occur
200+
/// due to temporary server issues or authentication problems.
201+
///
202+
/// When this event occurs, the client should:
203+
/// 1. Present an appropriate error message to the user
204+
/// 2. Consider implementing a retry mechanism with backoff
205+
/// 3. If persistent, check connectivity to the LSP node
206+
///
207+
/// The error details provided can help diagnose the specific issue.
208+
///
209+
/// [`lsps5.list_webhooks`]: super::msgs::LSPS5Request::ListWebhooks
210+
WebhooksListFailed {
211+
/// The node id of the LSP that rejected the request.
212+
counterparty_node_id: PublicKey,
213+
/// Error from the LSP.
214+
error: LSPS5Error,
215+
/// The identifier of the issued bLIP-55 / LSPS5 list webhooks request.
216+
///
217+
/// This can be used to track which request this event corresponds to.
218+
request_id: LSPSRequestId,
219+
},
220+
221+
/// A webhook was successfully removed.
222+
///
223+
/// This event is triggered when the LSP confirms successful removal
224+
/// of a webhook via [`lsps5.remove_webhook`]. The webhook registration
225+
/// has been deleted from the LSP's system and will no longer receive
226+
/// notifications.
227+
///
228+
/// When this event occurs, the client should:
229+
/// 1. Update any UI to reflect the webhook removal
230+
/// 2. Remove the webhook from any local storage or cache
231+
/// 3. Update counters or indicators showing the number of registered webhooks
232+
/// 4. Take any application-specific cleanup actions for the removed webhook
233+
///
234+
/// After this event, the app_name is free to be reused for a new webhook
235+
/// registration if desired.
236+
///
237+
/// [`lsps5.remove_webhook`]: super::msgs::LSPS5Request::RemoveWebhook
238+
WebhookRemoved {
239+
/// The node id of the LSP that confirmed the removal.
240+
counterparty_node_id: PublicKey,
241+
/// The app name that was removed.
242+
app_name: LSPS5AppName,
243+
/// The identifier of the issued bLIP-55 / LSPS5 remove webhook request.
244+
///
245+
/// This can be used to track which request this event corresponds to.
246+
request_id: LSPSRequestId,
247+
},
248+
249+
/// A webhook removal attempt failed.
250+
///
251+
/// This event is triggered when the LSP rejects a webhook removal
252+
/// via [`lsps5.remove_webhook`]. The most common scenario is attempting
253+
/// to remove a webhook that doesn't exist or was already removed.
254+
///
255+
/// When this event occurs, the client should:
256+
/// 1. Present an appropriate error message to the user
257+
/// 2. If the error is [`AppNameNotFound`], update any local state to
258+
/// reflect that the webhook does not exist on the server
259+
/// 3. Consider refreshing the webhook list to ensure local state
260+
/// matches server state
261+
///
262+
/// The most common error is [`LSPS5ProtocolError::AppNameNotFound`]
263+
/// (error code [`LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE`]), which indicates
264+
/// the given [`app_name`] was not found in the LSP's registration database.
265+
///
266+
/// [`lsps5.remove_webhook`]: super::msgs::LSPS5Request::RemoveWebhook
267+
/// [`AppNameNotFound`]: super::msgs::LSPS5ProtocolError::AppNameNotFound
268+
/// [`LSPS5ProtocolError::AppNameNotFound`]: super::msgs::LSPS5ProtocolError::AppNameNotFound
269+
/// [`LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE`]: super::msgs::LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE
270+
/// [`app_name`]: super::msgs::LSPS5AppName
271+
WebhookRemovalFailed {
272+
/// The node id of the LSP that rejected the removal.
273+
counterparty_node_id: PublicKey,
274+
/// Error from the LSP.
275+
error: LSPS5Error,
276+
/// The app name that was attempted to be removed.
277+
app_name: LSPS5AppName,
278+
/// The identifier of the issued bLIP-55 / LSPS5 remove webhook request.
279+
///
280+
/// This can be used to track which request this event corresponds to.
281+
request_id: LSPSRequestId,
282+
},
283+
}

0 commit comments

Comments
 (0)