Skip to content

Commit 02ed687

Browse files
committed
Add onchain_payment_required method
We previously had no way to reject requests in case the LSP requires onchain payment while the client not providing `refund_onchain_address`. Here we add a method allowing to do so.
1 parent 6b3554b commit 02ed687

3 files changed

Lines changed: 59 additions & 6 deletions

File tree

lightning-liquidity/src/lsps1/event.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,11 @@ pub enum LSPS1ServiceEvent {
170170
order: LSPS1OrderParams,
171171
/// The address we need to send onchain refunds to in case channel opening fails.
172172
///
173-
/// Please note that you can't offer onchain payments if this was not provided by the
174-
/// client.
173+
/// In case this is `None` you might just provide Lightning payments options to the client.
174+
/// If you *require* onchain payment, you should call
175+
/// [`LSPS1ServiceHandler::onchain_payments_required`] to reject the request.
176+
///
177+
/// [`LSPS1ServiceHandler::onchain_payments_required`]: crate::lsps1::service::LSPS1ServiceHandler::onchain_payments_required
175178
refund_onchain_address: Option<Address>,
176179
},
177180
}

lightning-liquidity/src/lsps1/msgs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub(crate) const LSPS1_CREATE_ORDER_METHOD_NAME: &str = "lsps1.create_order";
3131
pub(crate) const LSPS1_GET_ORDER_METHOD_NAME: &str = "lsps1.get_order";
3232

3333
pub(crate) const _LSPS1_CREATE_ORDER_REQUEST_INVALID_PARAMS_ERROR_CODE: i32 = -32602;
34-
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_ORDER_MISMATCH_ERROR_CODE: i32 = 100;
34+
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_OPTION_MISMATCH_ERROR_CODE: i32 = 100;
3535
pub(crate) const LSPS1_GET_ORDER_REQUEST_ORDER_NOT_FOUND_ERROR_CODE: i32 = 101;
3636
pub(crate) const LSPS1_CREATE_ORDER_REQUEST_UNRECOGNIZED_OR_STALE_TOKEN_ERROR_CODE: i32 = 102;
3737

lightning-liquidity/src/lsps1/service.rs

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::msgs::{
2323
LSPS1ChannelInfo, LSPS1CreateOrderRequest, LSPS1CreateOrderResponse, LSPS1GetInfoResponse,
2424
LSPS1GetOrderRequest, LSPS1Message, LSPS1Options, LSPS1OrderId, LSPS1OrderParams,
2525
LSPS1PaymentInfo, LSPS1Request, LSPS1Response,
26-
LSPS1_CREATE_ORDER_REQUEST_ORDER_MISMATCH_ERROR_CODE,
26+
LSPS1_CREATE_ORDER_REQUEST_OPTION_MISMATCH_ERROR_CODE,
2727
LSPS1_CREATE_ORDER_REQUEST_UNRECOGNIZED_OR_STALE_TOKEN_ERROR_CODE,
2828
LSPS1_GET_ORDER_REQUEST_ORDER_NOT_FOUND_ERROR_CODE,
2929
};
@@ -291,7 +291,7 @@ where
291291

292292
if !is_valid(&params.order, &self.config.supported_options) {
293293
let response = LSPS1Response::CreateOrderError(LSPSResponseError {
294-
code: LSPS1_CREATE_ORDER_REQUEST_ORDER_MISMATCH_ERROR_CODE,
294+
code: LSPS1_CREATE_ORDER_REQUEST_OPTION_MISMATCH_ERROR_CODE,
295295
message: "Order does not match options supported by LSP server".to_string(),
296296
data: Some(format!("Supported options are {:?}", &self.config.supported_options)),
297297
});
@@ -337,7 +337,8 @@ where
337337
/// Should be called in response to receiving a [`LSPS1ServiceEvent::RequestForPaymentDetails`] event.
338338
///
339339
/// Note that the provided `payment_details` can't include the onchain payment variant if the
340-
/// user didn't provide a `refund_onchain_address`.
340+
/// user didn't provide a `refund_onchain_address`. If you *require* onchain payments, you need
341+
/// to call [`Self::onchain_payments_required`] to reject the request.
341342
///
342343
/// [`LSPS1ServiceEvent::RequestForPaymentDetails`]: crate::lsps1::event::LSPS1ServiceEvent::RequestForPaymentDetails
343344
pub async fn send_payment_details(
@@ -469,6 +470,45 @@ where
469470
}
470471
}
471472

473+
/// Used by LSP to inform a client that an order was rejected because they require onchain
474+
/// payments and the client didn't provided a `refund_onchain_address`.
475+
///
476+
/// Should be called in response to receiving a [`LSPS1ServiceEvent::RequestForPaymentDetails`]
477+
/// event if the LSP requires onchain payments and `refund_onchain_address` is `None`.
478+
///
479+
/// [`LSPS1ServiceEvent::RequestForPaymentDetails`]: crate::lsps1::event::LSPS1ServiceEvent::RequestForPaymentDetails
480+
pub fn onchain_payments_required(
481+
&self, counterparty_node_id: PublicKey, request_id: LSPSRequestId,
482+
) -> Result<(), APIError> {
483+
let mut message_queue_notifier = self.pending_messages.notifier();
484+
485+
match self.per_peer_state.read().unwrap().get(&counterparty_node_id) {
486+
Some(inner_state_lock) => {
487+
let mut peer_state_lock = inner_state_lock.lock().unwrap();
488+
peer_state_lock.remove_request(&request_id).map_err(|e| {
489+
debug_assert!(false, "Failed to send response due to: {}", e);
490+
let err = format!("Failed to send response due to: {}", e);
491+
APIError::APIMisuseError { err }
492+
})?;
493+
494+
let response = LSPS1Response::CreateOrderError(LSPSResponseError {
495+
code: LSPS1_CREATE_ORDER_REQUEST_OPTION_MISMATCH_ERROR_CODE,
496+
message:
497+
"We require onchain payment but no `refund_onchain_address` was provided"
498+
.to_string(),
499+
data: None,
500+
});
501+
502+
let msg = LSPS1Message::Response(request_id, response).into();
503+
message_queue_notifier.enqueue(&counterparty_node_id, msg);
504+
Ok(())
505+
},
506+
None => Err(APIError::APIMisuseError {
507+
err: format!("No state for the counterparty exists: {}", counterparty_node_id),
508+
}),
509+
}
510+
}
511+
472512
fn handle_get_order_request(
473513
&self, request_id: LSPSRequestId, counterparty_node_id: &PublicKey,
474514
params: LSPS1GetOrderRequest,
@@ -755,6 +795,16 @@ where
755795
self.inner.invalid_token_provided(counterparty_node_id, request_id)
756796
}
757797

798+
/// Used by LSP to inform a client that an order was rejected because they require onchain
799+
/// payments and the client didn't provided a `refund_onchain_address`.
800+
///
801+
/// Wraps [`LSPS1ServiceHandler::onchain_payments_required`].
802+
pub fn onchain_payments_required(
803+
&self, counterparty_node_id: PublicKey, request_id: LSPSRequestId,
804+
) -> Result<(), APIError> {
805+
self.inner.onchain_payments_required(counterparty_node_id, request_id)
806+
}
807+
758808
/// Marks an order as paid after payment has been received.
759809
///
760810
/// Wraps [`LSPS1ServiceHandler::order_payment_received`].

0 commit comments

Comments
 (0)