Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit d29d75f

Browse files
committed
Update message types to include payment options
.. as of LSPS#101.
1 parent 6ce2675 commit d29d75f

File tree

3 files changed

+122
-70
lines changed

3 files changed

+122
-70
lines changed

src/lsps1/client.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,12 @@ where
447447
return Err(e);
448448
}
449449

450-
let total_fees = response.payment.fee_total_sat + response.order.client_balance_sat;
450+
// FIXME: Account for the individual payment types properly.
451+
let total_fees = response.payment.bolt11.as_ref().map_or(0, |p| p.fee_total_sat)
452+
+ response.order.client_balance_sat;
451453
let max_channel_fees_msat = self.config.max_channel_fees_msat.unwrap_or(u64::MAX);
452454

453-
if total_fees == response.payment.order_total_sat
455+
if total_fees == response.payment.bolt11.as_ref().map_or(0, |p| p.order_total_sat)
454456
&& total_fees < max_channel_fees_msat
455457
{
456458
self.pending_events.enqueue(Event::LSPS1Client(

src/lsps1/msgs.rs

+114-60
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,8 @@ pub struct OptionsSupported {
4444
pub min_required_channel_confirmations: u16,
4545
/// The smallest number of blocks in which the LSP can confirm the funding transaction.
4646
pub min_funding_confirms_within_blocks: u16,
47-
/// The minimum number of block confirmations before the LSP accepts an on-chain payment as confirmed.
48-
pub min_onchain_payment_confirmations: Option<u16>,
4947
/// Indicates if the LSP supports zero reserve.
5048
pub supports_zero_channel_reserve: bool,
51-
/// Indicates the minimum amount of satoshi that is required for the LSP to accept a payment
52-
/// on-chain.
53-
#[serde(with = "string_amount_option")]
54-
pub min_onchain_payment_size_sat: Option<u64>,
5549
/// The maximum number of blocks a channel can be leased for.
5650
pub max_channel_expiry_blocks: u32,
5751
/// The minimum number of satoshi that the client MUST request.
@@ -78,6 +72,7 @@ pub struct OptionsSupported {
7872
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
7973
pub struct GetInfoResponse {
8074
/// All options supported by the LSP.
75+
#[serde(flatten)]
8176
pub options: OptionsSupported,
8277
}
8378

@@ -128,8 +123,6 @@ pub struct CreateOrderResponse {
128123
pub order: OrderParams,
129124
/// The datetime when the order was created
130125
pub created_at: chrono::DateTime<Utc>,
131-
/// The datetime when the order expires.
132-
pub expires_at: chrono::DateTime<Utc>,
133126
/// The current state of the order.
134127
pub order_state: OrderState,
135128
/// Contains details about how to pay for the order.
@@ -153,34 +146,58 @@ pub enum OrderState {
153146
/// Details regarding how to pay for an order.
154147
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
155148
pub struct PaymentInfo {
149+
/// A Lightning payment using BOLT 11.
150+
pub bolt11: Option<Bolt11PaymentInfo>,
151+
/// An onchain payment.
152+
pub onchain: Option<OnchainPaymentInfo>,
153+
}
154+
155+
/// A Lightning payment using BOLT 11.
156+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
157+
pub struct Bolt11PaymentInfo {
156158
/// Indicates the current state of the payment.
157-
pub state: PaymentState,
159+
pub state: Bolt11PaymentState,
160+
/// The datetime when the payment option expires.
161+
pub expires_at: chrono::DateTime<Utc>,
158162
/// The total fee the LSP will charge to open this channel in satoshi.
159163
#[serde(with = "string_amount")]
160164
pub fee_total_sat: u64,
161-
/// What the client needs to pay in total to open the requested channel.
165+
/// The amount the client needs to pay to have the requested channel openend.
162166
#[serde(with = "string_amount")]
163167
pub order_total_sat: u64,
164168
/// A BOLT11 invoice the client can pay to have to channel opened.
165-
pub bolt11_invoice: Bolt11Invoice,
169+
pub invoice: Bolt11Invoice,
170+
}
171+
172+
/// An onchain payment.
173+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
174+
pub struct OnchainPaymentInfo {
175+
/// Indicates the current state of the payment.
176+
pub state: OnchainPaymentState,
177+
/// The datetime when the payment option expires.
178+
pub expires_at: chrono::DateTime<Utc>,
179+
/// The total fee the LSP will charge to open this channel in satoshi.
180+
#[serde(with = "string_amount")]
181+
pub fee_total_sat: u64,
182+
/// The amount the client needs to pay to have the requested channel openend.
183+
#[serde(with = "string_amount")]
184+
pub order_total_sat: u64,
166185
/// An on-chain address the client can send [`Self::order_total_sat`] to to have the channel
167186
/// opened.
168-
pub onchain_address: Address<NetworkUnchecked>,
187+
pub address: Address<NetworkUnchecked>,
169188
/// The minimum number of block confirmations that are required for the on-chain payment to be
170189
/// considered confirmed.
171190
pub min_onchain_payment_confirmations: Option<u16>,
172191
/// The minimum fee rate for the on-chain payment in case the client wants the payment to be
173192
/// confirmed without a confirmation.
174193
#[serde(with = "u32_fee_rate")]
175194
pub min_fee_for_0conf: FeeRate,
176-
/// Details regarding a detected on-chain payment.
177-
pub onchain_payment: Option<OnchainPayment>,
178195
}
179196

180-
/// The state of an [`PaymentInfo`].
197+
/// The state of a BOLT 11 payment.
181198
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
182199
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
183-
pub enum PaymentState {
200+
pub enum Bolt11PaymentState {
184201
/// A payment is expected.
185202
ExpectPayment,
186203
/// A Lighting payment has arrived, but the preimage has not been released yet.
@@ -189,6 +206,20 @@ pub enum PaymentState {
189206
Paid,
190207
/// The payment has been refunded.
191208
Refunded,
209+
/// The payment has been cancelled.
210+
Cancelled,
211+
}
212+
213+
/// The state of an onchain payment.
214+
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
215+
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
216+
pub enum OnchainPaymentState {
217+
/// A payment is expected.
218+
ExpectPayment,
219+
/// A sufficient payment has been received.
220+
Paid,
221+
/// The payment has been refunded.
222+
Refunded,
192223
}
193224

194225
/// Details regarding a detected on-chain payment.
@@ -288,9 +319,7 @@ mod tests {
288319
fn options_supported_serialization() {
289320
let min_required_channel_confirmations = 0;
290321
let min_funding_confirms_within_blocks = 6;
291-
let min_onchain_payment_confirmations = Some(6);
292322
let supports_zero_channel_reserve = true;
293-
let min_onchain_payment_size_sat = Some(100_000);
294323
let max_channel_expiry_blocks = 144;
295324
let min_initial_client_balance_sat = 10_000_000;
296325
let max_initial_client_balance_sat = 100_000_000;
@@ -302,9 +331,7 @@ mod tests {
302331
let options_supported = OptionsSupported {
303332
min_required_channel_confirmations,
304333
min_funding_confirms_within_blocks,
305-
min_onchain_payment_confirmations,
306334
supports_zero_channel_reserve,
307-
min_onchain_payment_size_sat,
308335
max_channel_expiry_blocks,
309336
min_initial_client_balance_sat,
310337
max_initial_client_balance_sat,
@@ -314,7 +341,7 @@ mod tests {
314341
max_channel_balance_sat,
315342
};
316343

317-
let json_str = r#"{"max_channel_balance_sat":"100000000","max_channel_expiry_blocks":144,"max_initial_client_balance_sat":"100000000","max_initial_lsp_balance_sat":"100000000","min_channel_balance_sat":"100000","min_funding_confirms_within_blocks":6,"min_initial_client_balance_sat":"10000000","min_initial_lsp_balance_sat":"100000","min_onchain_payment_confirmations":6,"min_onchain_payment_size_sat":"100000","min_required_channel_confirmations":0,"supports_zero_channel_reserve":true}"#;
344+
let json_str = r#"{"max_channel_balance_sat":"100000000","max_channel_expiry_blocks":144,"max_initial_client_balance_sat":"100000000","max_initial_lsp_balance_sat":"100000000","min_channel_balance_sat":"100000","min_funding_confirms_within_blocks":6,"min_initial_client_balance_sat":"10000000","min_initial_lsp_balance_sat":"100000","min_required_channel_confirmations":0,"supports_zero_channel_reserve":true}"#;
318345

319346
assert_eq!(json_str, serde_json::json!(options_supported).to_string());
320347
assert_eq!(options_supported, serde_json::from_str(json_str).unwrap());
@@ -327,20 +354,16 @@ mod tests {
327354
let _get_info_request: GetInfoRequest = serde_json::from_str(json_str).unwrap();
328355

329356
let json_str = r#"{
330-
"options": {
331-
"min_required_channel_confirmations": 0,
332-
"min_funding_confirms_within_blocks" : 6,
333-
"min_onchain_payment_confirmations": null,
334-
"supports_zero_channel_reserve": true,
335-
"min_onchain_payment_size_sat": null,
336-
"max_channel_expiry_blocks": 20160,
337-
"min_initial_client_balance_sat": "20000",
338-
"max_initial_client_balance_sat": "100000000",
339-
"min_initial_lsp_balance_sat": "0",
340-
"max_initial_lsp_balance_sat": "100000000",
341-
"min_channel_balance_sat": "50000",
342-
"max_channel_balance_sat": "100000000"
343-
}
357+
"min_required_channel_confirmations": 0,
358+
"min_funding_confirms_within_blocks" : 6,
359+
"supports_zero_channel_reserve": true,
360+
"max_channel_expiry_blocks": 20160,
361+
"min_initial_client_balance_sat": "20000",
362+
"max_initial_client_balance_sat": "100000000",
363+
"min_initial_lsp_balance_sat": "0",
364+
"max_initial_lsp_balance_sat": "100000000",
365+
"min_channel_balance_sat": "50000",
366+
"max_channel_balance_sat": "100000000"
344367
}"#;
345368
let _get_info_response: GetInfoResponse = serde_json::from_str(json_str).unwrap();
346369

@@ -356,6 +379,46 @@ mod tests {
356379
}"#;
357380
let _create_order_request: CreateOrderRequest = serde_json::from_str(json_str).unwrap();
358381

382+
let json_str = r#"{
383+
"state" : "EXPECT_PAYMENT",
384+
"expires_at": "2025-01-01T00:00:00Z",
385+
"fee_total_sat": "8888",
386+
"order_total_sat": "200888",
387+
"invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05"
388+
}"#;
389+
let _bolt11_payment: Bolt11PaymentInfo = serde_json::from_str(json_str).unwrap();
390+
391+
let json_str = r#"{
392+
"state": "EXPECT_PAYMENT",
393+
"expires_at": "2025-01-01T00:00:00Z",
394+
"fee_total_sat": "9999",
395+
"order_total_sat": "200999",
396+
"address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
397+
"min_onchain_payment_confirmations": 1,
398+
"min_fee_for_0conf": 253
399+
}"#;
400+
let _onchain_payment: OnchainPaymentInfo = serde_json::from_str(json_str).unwrap();
401+
402+
let json_str = r#"{
403+
"bolt11": {
404+
"state" : "EXPECT_PAYMENT",
405+
"expires_at": "2025-01-01T00:00:00Z",
406+
"fee_total_sat": "8888",
407+
"order_total_sat": "200888",
408+
"invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05"
409+
},
410+
"onchain": {
411+
"state": "EXPECT_PAYMENT",
412+
"expires_at": "2025-01-01T00:00:00Z",
413+
"fee_total_sat": "9999",
414+
"order_total_sat": "200999",
415+
"address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
416+
"min_onchain_payment_confirmations": 1,
417+
"min_fee_for_0conf": 253
418+
}
419+
}"#;
420+
let _payment: PaymentInfo = serde_json::from_str(json_str).unwrap();
421+
359422
let json_str = r#"{
360423
"order_id": "bb4b5d0a-8334-49d8-9463-90a6d413af7c",
361424
"lsp_balance_sat": "5000000",
@@ -365,18 +428,25 @@ mod tests {
365428
"channel_expiry_blocks": 12,
366429
"token": "",
367430
"created_at": "2012-04-23T18:25:43.511Z",
368-
"expires_at": "2015-01-25T19:29:44.612Z",
369431
"announce_channel": true,
370432
"order_state": "CREATED",
371433
"payment": {
372-
"state": "EXPECT_PAYMENT",
373-
"fee_total_sat": "8888",
374-
"order_total_sat": "2008888",
375-
"bolt11_invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05",
376-
"onchain_address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
377-
"min_onchain_payment_confirmations": 0,
378-
"min_fee_for_0conf": 253,
379-
"onchain_payment": null
434+
"bolt11": {
435+
"state": "EXPECT_PAYMENT",
436+
"expires_at": "2015-01-25T19:29:44.612Z",
437+
"fee_total_sat": "8888",
438+
"order_total_sat": "2008888",
439+
"invoice" : "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05"
440+
},
441+
"onchain": {
442+
"state": "EXPECT_PAYMENT",
443+
"expires_at": "2015-01-25T19:29:44.612Z",
444+
"fee_total_sat": "9999",
445+
"order_total_sat": "2009999",
446+
"address": "bc1qvmsy0f3yyes6z9jvddk8xqwznndmdwapvrc0xrmhd3vqj5rhdrrq6hz49h",
447+
"min_fee_for_0conf": 253,
448+
"min_onchain_payment_confirmations": 0
449+
}
380450
},
381451
"channel": null
382452
}"#;
@@ -387,22 +457,6 @@ mod tests {
387457
}"#;
388458
let _get_order_request: GetOrderRequest = serde_json::from_str(json_str).unwrap();
389459

390-
let json_str = r#"{
391-
"state": "EXPECT_PAYMENT",
392-
"fee_total_sat": "8888",
393-
"order_total_sat": "2008888",
394-
"bolt11_invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05",
395-
"onchain_address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
396-
"min_onchain_payment_confirmations": 1,
397-
"min_fee_for_0conf": 253,
398-
"onchain_payment": {
399-
"outpoint": "0301e0480b374b32851a9462db29dc19fe830a7f7d7a88b81612b9d42099c0ae:1",
400-
"sat": "1200",
401-
"confirmed": false
402-
}
403-
}"#;
404-
let _payment: PaymentInfo = serde_json::from_str(json_str).unwrap();
405-
406460
let json_str = r#"{
407461
"funded_at": "2012-04-23T18:25:43.511Z",
408462
"funding_outpoint": "0301e0480b374b32851a9462db29dc19fe830a7f7d7a88b81612b9d42099c0ae:0",

src/lsps1/service.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ impl OutboundRequestState {
7474
struct OutboundLSPS1Config {
7575
order: OrderParams,
7676
created_at: chrono::DateTime<Utc>,
77-
expires_at: chrono::DateTime<Utc>,
7877
payment: PaymentInfo,
7978
}
8079

@@ -85,12 +84,12 @@ struct OutboundCRChannel {
8584

8685
impl OutboundCRChannel {
8786
fn new(
88-
order: OrderParams, created_at: chrono::DateTime<Utc>, expires_at: chrono::DateTime<Utc>,
89-
order_id: OrderId, payment: PaymentInfo,
87+
order: OrderParams, created_at: chrono::DateTime<Utc>, order_id: OrderId,
88+
payment: PaymentInfo,
9089
) -> Self {
9190
Self {
9291
state: OutboundRequestState::OrderCreated { order_id },
93-
config: OutboundLSPS1Config { order, created_at, expires_at, payment },
92+
config: OutboundLSPS1Config { order, created_at, payment },
9493
}
9594
}
9695
fn awaiting_payment(&mut self) -> Result<(), LightningError> {
@@ -239,7 +238,7 @@ where
239238
/// [`LSPS1ServiceEvent::RequestForPaymentDetails`]: crate::lsps1::event::LSPS1ServiceEvent::RequestForPaymentDetails
240239
pub fn send_payment_details(
241240
&self, request_id: RequestId, counterparty_node_id: &PublicKey, payment: PaymentInfo,
242-
created_at: chrono::DateTime<Utc>, expires_at: chrono::DateTime<Utc>,
241+
created_at: chrono::DateTime<Utc>,
243242
) -> Result<(), APIError> {
244243
let (result, response) = {
245244
let outer_state_lock = self.per_peer_state.read().unwrap();
@@ -254,7 +253,6 @@ where
254253
let channel = OutboundCRChannel::new(
255254
params.order.clone(),
256255
created_at.clone(),
257-
expires_at.clone(),
258256
order_id.clone(),
259257
payment.clone(),
260258
);
@@ -266,7 +264,6 @@ where
266264
order_id,
267265
order_state: OrderState::Created,
268266
created_at,
269-
expires_at,
270267
payment,
271268
channel: None,
272269
});
@@ -386,7 +383,6 @@ where
386383
order: config.order.clone(),
387384
order_state,
388385
created_at: config.created_at,
389-
expires_at: config.expires_at,
390386
payment: config.payment.clone(),
391387
channel,
392388
});

0 commit comments

Comments
 (0)