@@ -7,6 +7,7 @@ use crate::lsps0::ser::{
77use crate :: prelude:: { String , Vec } ;
88
99use bitcoin:: address:: { Address , NetworkUnchecked } ;
10+ use bitcoin:: OutPoint ;
1011
1112use lightning_invoice:: Bolt11Invoice ;
1213
@@ -38,8 +39,10 @@ pub struct GetInfoRequest {}
3839/// An object representing the supported protocol options.
3940#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
4041pub 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 ,
4346 /// The minimum number of block confirmations before the LSP accepts an on-chain payment as confirmed.
4447 pub min_onchain_payment_confirmations : Option < u8 > ,
4548 /// Indicates if the LSP supports zero reserve.
@@ -70,11 +73,9 @@ pub struct OptionsSupported {
7073 pub max_channel_balance_sat : u64 ,
7174}
7275
73- /// A response to an [`GetInfoRequest`].
76+ /// A response to a [`GetInfoRequest`].
7477#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
7578pub struct GetInfoResponse {
76- /// The website of the LSP.
77- pub website : String ,
7879 /// All options supported by the LSP.
7980 pub options : OptionsSupported ,
8081}
@@ -86,6 +87,7 @@ pub struct GetInfoResponse {
8687#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
8788pub struct CreateOrderRequest {
8889 /// The order made.
90+ #[ serde( flatten) ]
8991 pub order : OrderParams ,
9092}
9193
@@ -101,8 +103,10 @@ pub struct OrderParams {
101103 /// the channel.
102104 #[ serde( with = "string_amount" ) ]
103105 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 ,
106110 /// Indicates how long the channel is leased for in block time.
107111 pub channel_expiry_blocks : u32 ,
108112 /// May contain arbitrary associated data like a coupon code or a authentication token.
@@ -119,6 +123,7 @@ pub struct CreateOrderResponse {
119123 /// The id of the channel order.
120124 pub order_id : OrderId ,
121125 /// The parameters of channel order.
126+ #[ serde( flatten) ]
122127 pub order : OrderParams ,
123128 /// The datetime when the order was created
124129 pub created_at : chrono:: DateTime < Utc > ,
@@ -127,13 +132,14 @@ pub struct CreateOrderResponse {
127132 /// The current state of the order.
128133 pub order_state : OrderState ,
129134 /// Contains details about how to pay for the order.
130- pub payment : OrderPayment ,
135+ pub payment : PaymentInfo ,
131136 /// Contains information about the channel state.
132137 pub channel : Option < ChannelInfo > ,
133138}
134139
135140/// An object representing the state of an order.
136141#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
142+ #[ serde( rename_all = "SCREAMING_SNAKE_CASE" ) ]
137143pub enum OrderState {
138144 /// The order has been created.
139145 Created ,
@@ -145,7 +151,7 @@ pub enum OrderState {
145151
146152/// Details regarding how to pay for an order.
147153#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
148- pub struct OrderPayment {
154+ pub struct PaymentInfo {
149155 /// Indicates the current state of the payment.
150156 pub state : PaymentState ,
151157 /// The total fee the LSP will charge to open this channel in satoshi.
@@ -166,11 +172,12 @@ pub struct OrderPayment {
166172 /// confirmed without a confirmation.
167173 pub min_fee_for_0conf : u8 ,
168174 /// Details regarding a detected on-chain payment.
169- pub onchain_payment : OnchainPayment ,
175+ pub onchain_payment : Option < OnchainPayment > ,
170176}
171177
172- /// The state of an [`OrderPayment `].
178+ /// The state of an [`PaymentInfo `].
173179#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
180+ #[ serde( rename_all = "SCREAMING_SNAKE_CASE" ) ]
174181pub enum PaymentState {
175182 /// A payment is expected.
176183 ExpectPayment ,
@@ -198,11 +205,11 @@ pub struct OnchainPayment {
198205#[ derive( Clone , Debug , PartialEq , Eq , Deserialize , Serialize ) ]
199206pub struct ChannelInfo {
200207 /// The datetime when the funding transaction has been published.
201- pub funded_at : String ,
208+ pub funded_at : chrono :: DateTime < Utc > ,
202209 /// The outpoint of the funding transaction.
203- pub funding_outpoint : String ,
210+ pub funding_outpoint : OutPoint ,
204211 /// The earliest datetime when the channel may be closed by the LSP.
205- pub expires_at : String ,
212+ pub expires_at : chrono :: DateTime < Utc > ,
206213}
207214
208215/// A request made to an LSP to retrieve information about an previously made order.
@@ -277,7 +284,8 @@ mod tests {
277284
278285 #[ test]
279286 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 ;
281289 let min_onchain_payment_confirmations = Some ( 6 ) ;
282290 let supports_zero_channel_reserve = true ;
283291 let min_onchain_payment_size_sat = Some ( 100_000 ) ;
@@ -290,7 +298,8 @@ mod tests {
290298 let max_channel_balance_sat = 100_000_000 ;
291299
292300 let options_supported = OptionsSupported {
293- min_channel_confirmations,
301+ min_required_channel_confirmations,
302+ min_funding_confirms_within_blocks,
294303 min_onchain_payment_confirmations,
295304 supports_zero_channel_reserve,
296305 min_onchain_payment_size_sat,
@@ -303,8 +312,100 @@ mod tests {
303312 max_channel_balance_sat,
304313 } ;
305314
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+
307317 assert_eq ! ( json_str, serde_json:: json!( options_supported) . to_string( ) ) ;
308318 assert_eq ! ( options_supported, serde_json:: from_str( json_str) . unwrap( ) ) ;
309319 }
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+ }
310411}
0 commit comments