Skip to content

Commit 611d514

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 f2e44fd commit 611d514

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
@@ -98,6 +98,7 @@ interface Node {
9898
OnchainPayment onchain_payment();
9999
UnifiedPayment unified_payment();
100100
Liquidity liquidity();
101+
LSPS5Liquidity lsps5_liquidity();
101102
[Throws=NodeError]
102103
void lnurl_auth(string lnurl);
103104
[Throws=NodeError]
@@ -169,6 +170,8 @@ typedef interface UnifiedPayment;
169170

170171
typedef interface Liquidity;
171172

173+
typedef interface LSPS5Liquidity;
174+
172175
[Error]
173176
enum NodeError {
174177
"AlreadyRunning",
@@ -231,6 +234,9 @@ enum NodeError {
231234
"LnurlAuthFailed",
232235
"LnurlAuthTimeout",
233236
"InvalidLnurl",
237+
"LiquiditySetWebhookFailed",
238+
"LiquidityRemoveWebhookFailed",
239+
"LiquidityListWebhooksFailed"
234240
};
235241

236242
typedef dictionary NodeStatus;

src/builder.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ use crate::runtime::{Runtime, RuntimeSpawner};
7878
use crate::tx_broadcaster::TransactionBroadcaster;
7979
use crate::types::{
8080
AsyncPersister, ChainMonitor, ChannelManager, DynStore, DynStoreRef, DynStoreWrapper,
81-
GossipSync, Graph, HRNResolver, KeysManager, MessageRouter, OnionMessenger, PaymentStore,
82-
PeerManager, PendingPaymentStore,
81+
GossipSync, Graph, HRNResolver, KeysManager, LSPS5ServiceConfig, MessageRouter, OnionMessenger,
82+
PaymentStore, PeerManager, PendingPaymentStore,
8383
};
8484
use crate::wallet::persist::KVStoreWalletPersister;
8585
use crate::wallet::Wallet;
@@ -122,10 +122,12 @@ struct PathfindingScoresSyncConfig {
122122

123123
#[derive(Debug, Clone, Default)]
124124
struct LiquiditySourceConfig {
125-
// Acts for both LSPS1 and LSPS2 clients connecting to the given service.
125+
// Acts for LSPS1, LSPS2 and LSPS5 clients connecting to the given service.
126126
lsp_nodes: Vec<LspConfig>,
127127
// Act as an LSPS2 service.
128128
lsps2_service: Option<LSPS2ServiceConfig>,
129+
// Act as an LSPS5 service.
130+
lsps5_service: Option<LSPS5ServiceConfig>,
129131
}
130132

131133
#[derive(Clone)]
@@ -514,6 +516,21 @@ impl NodeBuilder {
514516
self
515517
}
516518

519+
/// Configures the [`Node`] instance to provide an [bLIP-55 / LSPS5] service, enabling clients
520+
/// to register webhooks for push notifications.
521+
///
522+
/// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
523+
///
524+
/// [bLIP-55 / LSPS5]: https://github.com/lightning/blips/blob/master/blip-0055.md
525+
pub fn enable_liquidity_provider_lsps5(
526+
&mut self, lsps5_service_config: LSPS5ServiceConfig,
527+
) -> &mut Self {
528+
let liquidity_source_config =
529+
self.liquidity_source_config.get_or_insert(LiquiditySourceConfig::default());
530+
liquidity_source_config.lsps5_service = Some(lsps5_service_config);
531+
self
532+
}
533+
517534
/// Sets the used storage directory path.
518535
pub fn set_storage_dir_path(&mut self, storage_dir_path: String) -> &mut Self {
519536
self.config.storage_dir_path = storage_dir_path;
@@ -1081,6 +1098,16 @@ impl ArcedNodeBuilder {
10811098
self.inner.write().expect("lock").enable_liquidity_provider(lsps2_service_config);
10821099
}
10831100

1101+
/// Configures the [`Node`] instance to provide an [bLIP-55 / LSPS5] service, enabling clients
1102+
/// to register webhooks for push notifications.
1103+
///
1104+
/// **Caution**: LSP service support is in **alpha** and is considered an experimental feature.
1105+
///
1106+
/// [bLIP-55 / LSPS5]: https://github.com/lightning/blips/blob/master/blip-0055.md
1107+
pub fn enable_liquidity_provider_lsps5(&self, lsps5_service_config: LSPS5ServiceConfig) {
1108+
self.inner.write().expect("lock").enable_liquidity_provider_lsps5(lsps5_service_config);
1109+
}
1110+
10841111
/// Sets the used storage directory path.
10851112
pub fn set_storage_dir_path(&self, storage_dir_path: String) {
10861113
self.inner.write().expect("lock").set_storage_dir_path(storage_dir_path);
@@ -2081,6 +2108,10 @@ fn build_with_store_internal(
20812108
lsc.lsps2_service.as_ref().map(|config| {
20822109
liquidity_source_builder.lsps2_service(promise_secret, config.clone())
20832110
});
2111+
2112+
lsc.lsps5_service
2113+
.as_ref()
2114+
.map(|config| liquidity_source_builder.lsps5_service(config.clone()));
20842115
}
20852116

20862117
let liquidity_source = runtime
@@ -2140,6 +2171,8 @@ fn build_with_store_internal(
21402171

21412172
liquidity_source.lsps2_service().set_peer_manager(Arc::downgrade(&peer_manager));
21422173

2174+
liquidity_source.lsps5_service().set_peer_manager(Arc::downgrade(&peer_manager));
2175+
21432176
let connection_manager = Arc::new(ConnectionManager::new(
21442177
Arc::clone(&peer_manager),
21452178
config.tor_config.clone(),

src/error.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ pub enum Error {
137137
LnurlAuthTimeout,
138138
/// The provided lnurl is invalid.
139139
InvalidLnurl,
140+
/// Failed to set a webhook with the LSP.
141+
LiquiditySetWebhookFailed,
142+
/// Failed to remove a webhook with the LSP.
143+
LiquidityRemoveWebhookFailed,
144+
/// Failed to list webhooks with the LSP.
145+
LiquidityListWebhooksFailed,
140146
}
141147

142148
impl fmt::Display for Error {
@@ -222,6 +228,15 @@ impl fmt::Display for Error {
222228
Self::LnurlAuthFailed => write!(f, "LNURL-auth authentication failed."),
223229
Self::LnurlAuthTimeout => write!(f, "LNURL-auth authentication timed out."),
224230
Self::InvalidLnurl => write!(f, "The provided lnurl is invalid."),
231+
Self::LiquiditySetWebhookFailed => {
232+
write!(f, "Failed to set a webhook with the LSP.")
233+
},
234+
Self::LiquidityRemoveWebhookFailed => {
235+
write!(f, "Failed to remove a webhook with the LSP.")
236+
},
237+
Self::LiquidityListWebhooksFailed => {
238+
write!(f, "Failed to list webhooks with the LSP.")
239+
},
225240
}
226241
}
227242
}

src/event.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1734,6 +1734,8 @@ where
17341734
"Onion message intercepted, but no onion message mailbox available"
17351735
);
17361736
}
1737+
1738+
self.liquidity_source.lsps5_service().notify_onion_message_incoming(peer_node_id);
17371739
},
17381740
LdkEvent::OnionMessagePeerConnected { peer_node_id } => {
17391741
if let Some(om_mailbox) = self.om_mailbox.as_ref() {

0 commit comments

Comments
 (0)