Skip to content

Commit 4ce348c

Browse files
committed
Add LSPS5 (bLIP-55) webhook notification support
Implement the bLIP-55 / LSPS5 webhook registration protocol on top of the multi-LSP liquidity module (src/liquidity/{client,service}). Client side, exposed via Node::liquidity().lsps5(): - set_webhook / list_webhooks / remove_webhook to manage webhook registrations with an LSP. - When no node_id is given, set_webhook and remove_webhook fan out to every LSPS5-capable LSP so a webhook can be configured once across all configured LSPs; set_webhook returns one result per LSP that accepted the registration and remove_webhook returns the LSPs it was removed from. Service side, enabled via Builder::enable_liquidity_provider_lsps5(): - Deliver outgoing webhook notifications over HTTP in response to LSPS5ServiceEvent::SendWebhookNotification. - Automatically send an onion-message-incoming notification when an intercepted onion message targets a client that is currently offline (wired from LdkEvent::OnionMessageIntercepted, gated on peer connectivity). Wires the feature through the UniFFI bindings and adds LSPS5-specific Error variants.
1 parent 056447c commit 4ce348c

11 files changed

Lines changed: 1095 additions & 15 deletions

File tree

bindings/ldk_node.udl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ interface Node {
113113
OnchainPayment onchain_payment();
114114
UnifiedPayment unified_payment();
115115
Liquidity liquidity();
116+
LSPS5Liquidity lsps5_liquidity();
116117
[Throws=NodeError]
117118
void lnurl_auth(string lnurl);
118119
[Throws=NodeError]
@@ -184,6 +185,8 @@ typedef interface UnifiedPayment;
184185

185186
typedef interface Liquidity;
186187

188+
typedef interface LSPS5Liquidity;
189+
187190
[Error]
188191
enum NodeError {
189192
"AlreadyRunning",
@@ -247,6 +250,9 @@ enum NodeError {
247250
"LnurlAuthTimeout",
248251
"InvalidLnurl",
249252
"ChainSourceNotSupported",
253+
"LiquiditySetWebhookFailed",
254+
"LiquidityRemoveWebhookFailed",
255+
"LiquidityListWebhooksFailed"
250256
};
251257

252258
typedef dictionary NodeStatus;

src/builder.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ use crate::runtime::{Runtime, RuntimeSpawner};
8383
use crate::tx_broadcaster::TransactionBroadcaster;
8484
use crate::types::{
8585
AsyncPersister, ChainMonitor, ChannelManager, DynStore, DynStoreRef, DynStoreWrapper,
86-
GossipSync, Graph, HRNResolver, KeysManager, MessageRouter, OnionMessenger, PaymentStore,
87-
PeerManager, PendingPaymentStore,
86+
GossipSync, Graph, HRNResolver, KeysManager, LSPS5ServiceConfig, MessageRouter, OnionMessenger,
87+
PaymentStore, PeerManager, PendingPaymentStore,
8888
};
8989
use crate::wallet::persist::KVStoreWalletPersister;
9090
use crate::wallet::Wallet;
@@ -127,10 +127,12 @@ struct PathfindingScoresSyncConfig {
127127

128128
#[derive(Debug, Clone, Default)]
129129
struct LiquiditySourceConfig {
130-
// Acts for both LSPS1 and LSPS2 clients connecting to the given service.
130+
// Acts for LSPS1, LSPS2 and LSPS5 clients connecting to the given service.
131131
lsp_nodes: Vec<LspConfig>,
132132
// Act as an LSPS2 service.
133133
lsps2_service: Option<LSPS2ServiceConfig>,
134+
// Act as an LSPS5 service.
135+
lsps5_service: Option<LSPS5ServiceConfig>,
134136
}
135137

136138
#[derive(Clone)]
@@ -522,6 +524,21 @@ impl NodeBuilder {
522524
self
523525
}
524526

527+
/// Configures the [`Node`] instance to provide an [bLIP-55 / LSPS5] service, enabling clients
528+
/// to register webhooks for push notifications.
529+
///
530+
/// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
531+
///
532+
/// [bLIP-55 / LSPS5]: https://github.com/lightning/blips/blob/master/blip-0055.md
533+
pub fn enable_liquidity_provider_lsps5(
534+
&mut self, lsps5_service_config: LSPS5ServiceConfig,
535+
) -> &mut Self {
536+
let liquidity_source_config =
537+
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
538+
liquidity_source_config.lsps5_service = Some(lsps5_service_config);
539+
self
540+
}
541+
525542
/// Sets the used storage directory path.
526543
pub fn set_storage_dir_path(&mut self, storage_dir_path: String) -> &mut Self {
527544
self.config.storage_dir_path = storage_dir_path;
@@ -1114,6 +1131,16 @@ impl ArcedNodeBuilder {
11141131
self.inner.write().expect("lock").enable_liquidity_provider(lsps2_service_config);
11151132
}
11161133

1134+
/// Configures the [`Node`] instance to provide an [bLIP-55 / LSPS5] service, enabling clients
1135+
/// to register webhooks for push notifications.
1136+
///
1137+
/// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
1138+
///
1139+
/// [bLIP-55 / LSPS5]: https://github.com/lightning/blips/blob/master/blip-0055.md
1140+
pub fn enable_liquidity_provider_lsps5(&self, lsps5_service_config: LSPS5ServiceConfig) {
1141+
self.inner.write().expect("lock").enable_liquidity_provider_lsps5(lsps5_service_config);
1142+
}
1143+
11171144
/// Sets the used storage directory path.
11181145
pub fn set_storage_dir_path(&self, storage_dir_path: String) {
11191146
self.inner.write().expect("lock").set_storage_dir_path(storage_dir_path);
@@ -2124,6 +2151,10 @@ fn build_with_store_internal(
21242151
lsc.lsps2_service.as_ref().map(|config| {
21252152
liquidity_source_builder.lsps2_service(promise_secret, config.clone())
21262153
});
2154+
2155+
lsc.lsps5_service
2156+
.as_ref()
2157+
.map(|config| liquidity_source_builder.lsps5_service(config.clone()));
21272158
}
21282159

21292160
let liquidity_source = runtime
@@ -2183,6 +2214,8 @@ fn build_with_store_internal(
21832214

21842215
liquidity_source.lsps2_service().set_peer_manager(Arc::downgrade(&peer_manager));
21852216

2217+
liquidity_source.lsps5_service().set_peer_manager(Arc::downgrade(&peer_manager));
2218+
21862219
let connection_manager = Arc::new(ConnectionManager::new(
21872220
Arc::clone(&peer_manager),
21882221
config.tor_config.clone(),

src/error.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,12 @@ pub enum Error {
139139
InvalidLnurl,
140140
/// The configured chain source is not supported.
141141
ChainSourceNotSupported,
142+
/// Failed to set a webhook with the LSP.
143+
LiquiditySetWebhookFailed,
144+
/// Failed to remove a webhook with the LSP.
145+
LiquidityRemoveWebhookFailed,
146+
/// Failed to list webhooks with the LSP.
147+
LiquidityListWebhooksFailed,
142148
}
143149

144150
impl fmt::Display for Error {
@@ -227,6 +233,15 @@ impl fmt::Display for Error {
227233
Self::ChainSourceNotSupported => {
228234
write!(f, "The configured chain source is not supported.")
229235
},
236+
Self::LiquiditySetWebhookFailed => {
237+
write!(f, "Failed to set a webhook with the LSP.")
238+
},
239+
Self::LiquidityRemoveWebhookFailed => {
240+
write!(f, "Failed to remove a webhook with the LSP.")
241+
},
242+
Self::LiquidityListWebhooksFailed => {
243+
write!(f, "Failed to list webhooks with the LSP.")
244+
},
230245
}
231246
}
232247
}

src/event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,6 +1835,8 @@ where
18351835
} else {
18361836
log_error!(self.logger, "Onion message intercepted for unknown SCID");
18371837
}
1838+
1839+
self.liquidity_source.lsps5_service().notify_onion_message_incoming(peer_node_id);
18381840
},
18391841
LdkEvent::OnionMessagePeerConnected { peer_node_id } => {
18401842
if let Some(om_mailbox) = self.om_mailbox.as_ref() {

0 commit comments

Comments
 (0)