@@ -7,6 +7,7 @@ use crate::lsps0::ser::{
7
7
use crate :: prelude:: { String , Vec } ;
8
8
9
9
use bitcoin:: address:: { Address , NetworkUnchecked } ;
10
+ use bitcoin:: OutPoint ;
10
11
11
12
use lightning_invoice:: Bolt11Invoice ;
12
13
@@ -38,8 +39,10 @@ pub struct GetInfoRequest {}
38
39
/// An object representing the supported protocol options.
39
40
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
40
41
pub struct OptionsSupported {
41
- /// The minimum number of block confirmations before the LSP accepts a channel as confirmed.
42
- pub min_channel_confirmations : u8 ,
42
+ /// The smallest number of confirmations needed for the LSP to accept a channel as confirmed.
43
+ pub min_required_channel_confirmations : u8 ,
44
+ /// The smallest number of blocks in which the LSP can confirm the funding transaction.
45
+ pub min_funding_confirms_within_blocks : u8 ,
43
46
/// The minimum number of block confirmations before the LSP accepts an on-chain payment as confirmed.
44
47
pub min_onchain_payment_confirmations : Option < u8 > ,
45
48
/// Indicates if the LSP supports zero reserve.
@@ -70,11 +73,9 @@ pub struct OptionsSupported {
70
73
pub max_channel_balance_sat : u64 ,
71
74
}
72
75
73
- /// A response to an [`GetInfoRequest`].
76
+ /// A response to a [`GetInfoRequest`].
74
77
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
75
78
pub struct GetInfoResponse {
76
- /// The website of the LSP.
77
- pub website : String ,
78
79
/// All options supported by the LSP.
79
80
pub options : OptionsSupported ,
80
81
}
@@ -86,6 +87,7 @@ pub struct GetInfoResponse {
86
87
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
87
88
pub struct CreateOrderRequest {
88
89
/// The order made.
90
+ #[ serde( flatten) ]
89
91
pub order : OrderParams ,
90
92
}
91
93
@@ -101,8 +103,10 @@ pub struct OrderParams {
101
103
/// the channel.
102
104
#[ serde( with = "string_amount" ) ]
103
105
pub client_balance_sat : u64 ,
104
- /// The number of blocks the client wants to wait maximally for the channel to be confirmed.
105
- pub confirms_within_blocks : u32 ,
106
+ /// The number of confirmations the funding tx must have before the LSP sends `channel_ready`.
107
+ pub required_channel_confirmations : u8 ,
108
+ /// The maximum number of blocks the client wants to wait until the funding transaction is confirmed.
109
+ pub funding_confirms_within_blocks : u8 ,
106
110
/// Indicates how long the channel is leased for in block time.
107
111
pub channel_expiry_blocks : u32 ,
108
112
/// May contain arbitrary associated data like a coupon code or a authentication token.
@@ -119,6 +123,7 @@ pub struct CreateOrderResponse {
119
123
/// The id of the channel order.
120
124
pub order_id : OrderId ,
121
125
/// The parameters of channel order.
126
+ #[ serde( flatten) ]
122
127
pub order : OrderParams ,
123
128
/// The datetime when the order was created
124
129
pub created_at : chrono:: DateTime < Utc > ,
@@ -127,13 +132,14 @@ pub struct CreateOrderResponse {
127
132
/// The current state of the order.
128
133
pub order_state : OrderState ,
129
134
/// Contains details about how to pay for the order.
130
- pub payment : OrderPayment ,
135
+ pub payment : PaymentInfo ,
131
136
/// Contains information about the channel state.
132
137
pub channel : Option < ChannelInfo > ,
133
138
}
134
139
135
140
/// An object representing the state of an order.
136
141
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
142
+ #[ serde( rename_all = "SCREAMING_SNAKE_CASE" ) ]
137
143
pub enum OrderState {
138
144
/// The order has been created.
139
145
Created ,
@@ -145,7 +151,7 @@ pub enum OrderState {
145
151
146
152
/// Details regarding how to pay for an order.
147
153
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
148
- pub struct OrderPayment {
154
+ pub struct PaymentInfo {
149
155
/// Indicates the current state of the payment.
150
156
pub state : PaymentState ,
151
157
/// The total fee the LSP will charge to open this channel in satoshi.
@@ -166,11 +172,12 @@ pub struct OrderPayment {
166
172
/// confirmed without a confirmation.
167
173
pub min_fee_for_0conf : u8 ,
168
174
/// Details regarding a detected on-chain payment.
169
- pub onchain_payment : OnchainPayment ,
175
+ pub onchain_payment : Option < OnchainPayment > ,
170
176
}
171
177
172
- /// The state of an [`OrderPayment `].
178
+ /// The state of an [`PaymentInfo `].
173
179
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
180
+ #[ serde( rename_all = "SCREAMING_SNAKE_CASE" ) ]
174
181
pub enum PaymentState {
175
182
/// A payment is expected.
176
183
ExpectPayment ,
@@ -198,11 +205,11 @@ pub struct OnchainPayment {
198
205
#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
199
206
pub struct ChannelInfo {
200
207
/// The datetime when the funding transaction has been published.
201
- pub funded_at : String ,
208
+ pub funded_at : chrono :: DateTime < Utc > ,
202
209
/// The outpoint of the funding transaction.
203
- pub funding_outpoint : String ,
210
+ pub funding_outpoint : OutPoint ,
204
211
/// The earliest datetime when the channel may be closed by the LSP.
205
- pub expires_at : String ,
212
+ pub expires_at : chrono :: DateTime < Utc > ,
206
213
}
207
214
208
215
/// A request made to an LSP to retrieve information about an previously made order.
@@ -277,7 +284,8 @@ mod tests {
277
284
278
285
#[ test]
279
286
fn options_supported_serialization ( ) {
280
- let min_channel_confirmations = 6 ;
287
+ let min_required_channel_confirmations = 0 ;
288
+ let min_funding_confirms_within_blocks = 6 ;
281
289
let min_onchain_payment_confirmations = Some ( 6 ) ;
282
290
let supports_zero_channel_reserve = true ;
283
291
let min_onchain_payment_size_sat = Some ( 100_000 ) ;
@@ -290,7 +298,8 @@ mod tests {
290
298
let max_channel_balance_sat = 100_000_000 ;
291
299
292
300
let options_supported = OptionsSupported {
293
- min_channel_confirmations,
301
+ min_required_channel_confirmations,
302
+ min_funding_confirms_within_blocks,
294
303
min_onchain_payment_confirmations,
295
304
supports_zero_channel_reserve,
296
305
min_onchain_payment_size_sat,
@@ -303,8 +312,100 @@ mod tests {
303
312
max_channel_balance_sat,
304
313
} ;
305
314
306
- 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_channel_confirmations":6,"min_initial_client_balance_sat":"10000000","min_initial_lsp_balance_sat":"100000","min_onchain_payment_confirmations":6,"min_onchain_payment_size_sat":"100000","supports_zero_channel_reserve":true}"# ;
315
+ 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}"# ;
316
+
307
317
assert_eq ! ( json_str, serde_json:: json!( options_supported) . to_string( ) ) ;
308
318
assert_eq ! ( options_supported, serde_json:: from_str( json_str) . unwrap( ) ) ;
309
319
}
320
+
321
+ #[ test]
322
+ fn parse_spec_test_vectors ( ) {
323
+ // Here, we simply assert that we're able to parse all examples given in LSPS1.
324
+ let json_str = r#"{}"# ;
325
+ let _get_info_request: GetInfoRequest = serde_json:: from_str ( json_str) . unwrap ( ) ;
326
+
327
+ let json_str = r#"{
328
+ "options": {
329
+ "min_required_channel_confirmations": 0,
330
+ "min_funding_confirms_within_blocks" : 6,
331
+ "min_onchain_payment_confirmations": null,
332
+ "supports_zero_channel_reserve": true,
333
+ "min_onchain_payment_size_sat": null,
334
+ "max_channel_expiry_blocks": 20160,
335
+ "min_initial_client_balance_sat": "20000",
336
+ "max_initial_client_balance_sat": "100000000",
337
+ "min_initial_lsp_balance_sat": "0",
338
+ "max_initial_lsp_balance_sat": "100000000",
339
+ "min_channel_balance_sat": "50000",
340
+ "max_channel_balance_sat": "100000000"
341
+ }
342
+ }"# ;
343
+ let _get_info_response: GetInfoResponse = serde_json:: from_str ( json_str) . unwrap ( ) ;
344
+
345
+ let json_str = r#"{
346
+ "lsp_balance_sat": "5000000",
347
+ "client_balance_sat": "2000000",
348
+ "required_channel_confirmations" : 0,
349
+ "funding_confirms_within_blocks": 6,
350
+ "channel_expiry_blocks": 144,
351
+ "token": "",
352
+ "refund_onchain_address": "bc1qvmsy0f3yyes6z9jvddk8xqwznndmdwapvrc0xrmhd3vqj5rhdrrq6hz49h",
353
+ "announce_channel": true
354
+ }"# ;
355
+ let _create_order_request: CreateOrderRequest = serde_json:: from_str ( json_str) . unwrap ( ) ;
356
+
357
+ let json_str = r#"{
358
+ "order_id": "bb4b5d0a-8334-49d8-9463-90a6d413af7c",
359
+ "lsp_balance_sat": "5000000",
360
+ "client_balance_sat": "2000000",
361
+ "required_channel_confirmations" : 0,
362
+ "funding_confirms_within_blocks": 1,
363
+ "channel_expiry_blocks": 12,
364
+ "token": "",
365
+ "created_at": "2012-04-23T18:25:43.511Z",
366
+ "expires_at": "2015-01-25T19:29:44.612Z",
367
+ "announce_channel": true,
368
+ "order_state": "CREATED",
369
+ "payment": {
370
+ "state": "EXPECT_PAYMENT",
371
+ "fee_total_sat": "8888",
372
+ "order_total_sat": "2008888",
373
+ "bolt11_invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05",
374
+ "onchain_address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
375
+ "min_onchain_payment_confirmations": 0,
376
+ "min_fee_for_0conf": 253,
377
+ "onchain_payment": null
378
+ },
379
+ "channel": null
380
+ }"# ;
381
+ let _create_order_response: CreateOrderResponse = serde_json:: from_str ( json_str) . unwrap ( ) ;
382
+
383
+ let json_str = r#"{
384
+ "order_id": "bb4b5d0a-8334-49d8-9463-90a6d413af7c"
385
+ }"# ;
386
+ let _get_order_request: GetOrderRequest = serde_json:: from_str ( json_str) . unwrap ( ) ;
387
+
388
+ let json_str = r#"{
389
+ "state": "EXPECT_PAYMENT",
390
+ "fee_total_sat": "8888",
391
+ "order_total_sat": "2008888",
392
+ "bolt11_invoice": "lnbc252u1p3aht9ysp580g4633gd2x9lc5al0wd8wx0mpn9748jeyz46kqjrpxn52uhfpjqpp5qgf67tcqmuqehzgjm8mzya90h73deafvr4m5705l5u5l4r05l8cqdpud3h8ymm4w3jhytnpwpczqmt0de6xsmre2pkxzm3qydmkzdjrdev9s7zhgfaqxqyjw5qcqpjrzjqt6xptnd85lpqnu2lefq4cx070v5cdwzh2xlvmdgnu7gqp4zvkus5zapryqqx9qqqyqqqqqqqqqqqcsq9q9qyysgqen77vu8xqjelum24hgjpgfdgfgx4q0nehhalcmuggt32japhjuksq9jv6eksjfnppm4hrzsgyxt8y8xacxut9qv3fpyetz8t7tsymygq8yzn05",
393
+ "onchain_address": "bc1p5uvtaxzkjwvey2tfy49k5vtqfpjmrgm09cvs88ezyy8h2zv7jhas9tu4yr",
394
+ "min_onchain_payment_confirmations": 1,
395
+ "min_fee_for_0conf": 253,
396
+ "onchain_payment": {
397
+ "outpoint": "0301e0480b374b32851a9462db29dc19fe830a7f7d7a88b81612b9d42099c0ae:1",
398
+ "sat": "1200",
399
+ "confirmed": false
400
+ }
401
+ }"# ;
402
+ let _payment: PaymentInfo = serde_json:: from_str ( json_str) . unwrap ( ) ;
403
+
404
+ let json_str = r#"{
405
+ "funded_at": "2012-04-23T18:25:43.511Z",
406
+ "funding_outpoint": "0301e0480b374b32851a9462db29dc19fe830a7f7d7a88b81612b9d42099c0ae:0",
407
+ "expires_at": "2012-04-23T18:25:43.511Z"
408
+ }"# ;
409
+ let _channel: ChannelInfo = serde_json:: from_str ( json_str) . unwrap ( ) ;
410
+ }
310
411
}
0 commit comments