Skip to content

Commit 229dfb0

Browse files
Add LSPS5 service and client events
Introduce SendWebhookNotification event for LSPS5/service, and also WebhookRegistered, WebhookRegistrationFailed, WebhooksListed, WebhookRemoved and WebhookRemovalFailed events for LSPS5/client.
1 parent 82ae710 commit 229dfb0

File tree

1 file changed

+213
-0
lines changed

1 file changed

+213
-0
lines changed
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
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.
27+
///
28+
/// This event is triggered when the LSP needs to notify a client about an event
29+
/// via their registered webhook.
30+
///
31+
/// The LSP should send an HTTP POST to the [`url`], using the
32+
/// JSON-serialized [`notification`] as the body and including the `headers`.
33+
/// If the HTTP request fails, the LSP may implement a retry policy according to its
34+
/// implementation preferences, but must respect rate-limiting as defined in
35+
/// [`notification_cooldown_hours`].
36+
///
37+
/// The notification is signed using the LSP's node ID to ensure authenticity
38+
/// when received by the client. The client verifies this signature using
39+
/// [`validate`], which guards against replay attacks and tampering.
40+
///
41+
/// [`validate`]: super::validator::LSPS5Validator::validate
42+
/// [`notification_cooldown_hours`]: super::service::LSPS5ServiceConfig::notification_cooldown_hours
43+
/// [`url`]: super::msgs::LSPS5WebhookUrl
44+
/// [`notification`]: super::msgs::WebhookNotification
45+
SendWebhookNotification {
46+
/// Client node ID to be notified.
47+
counterparty_node_id: PublicKey,
48+
/// [`App name`] to be notified.
49+
///
50+
/// This identifies which webhook registration should be notified.
51+
///
52+
/// [`App name`]: super::msgs::LSPS5AppName
53+
app_name: LSPS5AppName,
54+
/// URL to be called.
55+
///
56+
/// This is the [`webhook URL`] provided by the client during registration.
57+
///
58+
/// [`webhook URL`]: super::msgs::LSPS5WebhookUrl
59+
url: LSPS5WebhookUrl,
60+
/// Notification method with its parameters.
61+
///
62+
/// This contains the type of notification and any associated data to be sent to the client.
63+
notification: WebhookNotification,
64+
/// Headers to be included in the HTTP POST request.
65+
///
66+
/// This is a map of HTTP header key-value pairs. It will include:
67+
/// - `"Content-Type"`: with a value like `"application/json"`.
68+
/// - `"x-lsps5-timestamp"`: with the timestamp in RFC3339 format (`"YYYY-MM-DDThh:mm:ss.uuuZ"`).
69+
/// - `"x-lsps5-signature"`: with the signature of the notification payload, signed using the LSP's node ID.
70+
/// Other custom headers may also be included as needed.
71+
headers: HashMap<String, String>,
72+
},
73+
}
74+
75+
/// An event which an LSPS5 client should take some action in response to.
76+
#[derive(Debug, Clone, PartialEq, Eq)]
77+
pub enum LSPS5ClientEvent {
78+
/// A webhook was successfully registered with the LSP.
79+
///
80+
/// This event is triggered when the LSP confirms successful registration
81+
/// of a webhook via [`lsps5.set_webhook`].
82+
///
83+
/// If `no_change` is `false` (indicating the registered webhook is a new registration),
84+
/// the LSP will also emit a [`SendWebhookNotification`] event with a [`webhook_registered`] notification
85+
/// to notify the client about this registration.
86+
///
87+
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
88+
/// [`SendWebhookNotification`]: super::event::LSPS5ServiceEvent::SendWebhookNotification
89+
/// [`webhook_registered`]: super::msgs::WebhookNotificationMethod::LSPS5WebhookRegistered
90+
WebhookRegistered {
91+
/// The node id of the LSP that confirmed the registration.
92+
counterparty_node_id: PublicKey,
93+
/// Current number of webhooks registered for this client.
94+
num_webhooks: u32,
95+
/// Maximum number of webhooks allowed by LSP.
96+
max_webhooks: u32,
97+
/// Whether this was an unchanged registration (same app_name and URL).
98+
/// If true, the LSP didn't send a webhook notification for this registration.
99+
no_change: bool,
100+
/// The app name that was registered.
101+
app_name: LSPS5AppName,
102+
/// The webhook URL that was registered.
103+
url: LSPS5WebhookUrl,
104+
/// The identifier of the issued bLIP-55 / LSPS5 webhook registration request.
105+
///
106+
/// This can be used to track which request this event corresponds to.
107+
request_id: LSPSRequestId,
108+
},
109+
110+
/// A webhook registration attempt failed.
111+
///
112+
/// This event is triggered when the LSP rejects a webhook registration
113+
/// via [`lsps5.set_webhook`].
114+
///
115+
/// Possible errors:
116+
/// - The [`app_name`] exceeds [`MAX_APP_NAME_LENGTH`] (error [`AppNameTooLong`]).
117+
/// - The [`url`] exceeds [`MAX_WEBHOOK_URL_LENGTH`] (error [`WebhookUrlTooLong`]).
118+
/// - The [`url`] uses an unsupported protocol. HTTPS is required (error [`UnsupportedProtocol`]).
119+
/// - Maximum number of webhooks per client has been reached (error [`TooManyWebhooks`]). Remove a webhook before
120+
/// registering a new one.
121+
///
122+
/// [`lsps5.set_webhook`]: super::msgs::LSPS5Request::SetWebhook
123+
/// [`app_name`]: super::msgs::LSPS5AppName
124+
/// [`url`]: super::msgs::LSPS5WebhookUrl
125+
/// [`MAX_APP_NAME_LENGTH`]: super::msgs::MAX_APP_NAME_LENGTH
126+
/// [`MAX_WEBHOOK_URL_LENGTH`]: super::msgs::MAX_WEBHOOK_URL_LENGTH
127+
/// [`AppNameTooLong`]: super::msgs::LSPS5ProtocolError::AppNameTooLong
128+
/// [`WebhookUrlTooLong`]: super::msgs::LSPS5ProtocolError::WebhookUrlTooLong
129+
/// [`UnsupportedProtocol`]: super::msgs::LSPS5ProtocolError::UnsupportedProtocol
130+
/// [`TooManyWebhooks`]: super::msgs::LSPS5ProtocolError::TooManyWebhooks
131+
WebhookRegistrationFailed {
132+
/// The node id of the LSP that rejected the registration.
133+
counterparty_node_id: PublicKey,
134+
/// Error from the LSP.
135+
error: LSPS5Error,
136+
/// The app name that was attempted.
137+
app_name: LSPS5AppName,
138+
/// The webhook URL that was attempted.
139+
url: LSPS5WebhookUrl,
140+
/// The identifier of the issued bLIP-55 / LSPS5 webhook registration request.
141+
///
142+
/// This can be used to track which request this event corresponds to.
143+
request_id: LSPSRequestId,
144+
},
145+
146+
/// The list of registered webhooks was successfully retrieved.
147+
///
148+
/// This event is triggered when the LSP responds to a
149+
/// [`lsps5.list_webhooks`] request.
150+
///
151+
/// [`lsps5.list_webhooks`]: super::msgs::LSPS5Request::ListWebhooks
152+
WebhooksListed {
153+
/// The node id of the LSP that provided the list.
154+
counterparty_node_id: PublicKey,
155+
/// List of app names with registered webhooks.
156+
app_names: Vec<LSPS5AppName>,
157+
/// Maximum number of webhooks allowed by LSP.
158+
max_webhooks: u32,
159+
/// The identifier of the issued bLIP-55 / LSPS5 list webhooks request.
160+
///
161+
/// This can be used to track which request this event corresponds to.
162+
request_id: LSPSRequestId,
163+
},
164+
165+
/// A webhook was successfully removed.
166+
///
167+
/// This event is triggered when the LSP confirms successful removal
168+
/// of a webhook via [`lsps5.remove_webhook`]. The webhook registration
169+
/// has been deleted from the LSP's system and will no longer receive
170+
/// notifications.
171+
///
172+
/// After this event, the app_name is free to be reused for a new webhook
173+
/// registration if desired.
174+
///
175+
/// [`lsps5.remove_webhook`]: super::msgs::LSPS5Request::RemoveWebhook
176+
WebhookRemoved {
177+
/// The node id of the LSP that confirmed the removal.
178+
counterparty_node_id: PublicKey,
179+
/// The app name that was removed.
180+
app_name: LSPS5AppName,
181+
/// The identifier of the issued bLIP-55 / LSPS5 remove webhook request.
182+
///
183+
/// This can be used to track which request this event corresponds to.
184+
request_id: LSPSRequestId,
185+
},
186+
187+
/// A webhook removal attempt failed.
188+
///
189+
/// This event is triggered when the LSP rejects a webhook removal
190+
/// via [`lsps5.remove_webhook`].
191+
///
192+
/// The most common error is [`LSPS5ProtocolError::AppNameNotFound`]
193+
/// (error code [`LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE`]), which indicates
194+
/// the given [`app_name`] was not found in the LSP's registration database.
195+
///
196+
/// [`lsps5.remove_webhook`]: super::msgs::LSPS5Request::RemoveWebhook
197+
/// [`AppNameNotFound`]: super::msgs::LSPS5ProtocolError::AppNameNotFound
198+
/// [`LSPS5ProtocolError::AppNameNotFound`]: super::msgs::LSPS5ProtocolError::AppNameNotFound
199+
/// [`LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE`]: super::msgs::LSPS5_APP_NAME_NOT_FOUND_ERROR_CODE
200+
/// [`app_name`]: super::msgs::LSPS5AppName
201+
WebhookRemovalFailed {
202+
/// The node id of the LSP that rejected the removal.
203+
counterparty_node_id: PublicKey,
204+
/// Error from the LSP.
205+
error: LSPS5Error,
206+
/// The app name that was attempted to be removed.
207+
app_name: LSPS5AppName,
208+
/// The identifier of the issued bLIP-55 / LSPS5 remove webhook request.
209+
///
210+
/// This can be used to track which request this event corresponds to.
211+
request_id: LSPSRequestId,
212+
},
213+
}

0 commit comments

Comments
 (0)