1use crate::json_rpc::NoParams;
2use crate::lsps0::common_schemas::{
3 FeeRate, IsoDatetime, OnchainAddress, Outpoint, SatAmount
4};
5use crate::lsps0::parameter_validation::ExpectedFields;
6use serde::{Deserialize, Serialize};
7use uuid::Uuid;
8
9pub type Lsps1InfoRequest = NoParams;
10
11#[derive(Debug, Serialize, Deserialize, Clone)]
12pub struct Lsps1GetInfoResponse {
13 pub website: Option<String>,
14 pub options: Lsps1Options,
15 #[serde(skip_serializing, default)]
17 pub(crate) _private: (),
18}
19
20#[derive(Debug, Serialize, Deserialize, Clone)]
22pub struct Lsps1Options {
23 pub min_channel_confirmations: u8,
24 pub min_onchain_payment_confirmations: Option<u8>,
25 pub supports_zero_channel_reserve: bool,
26 pub min_onchain_payment_size_sat: Option<SatAmount>,
27 pub max_channel_expiry_blocks: u32,
28 pub min_initial_client_balance_sat: SatAmount,
29 pub max_initial_client_balance_sat: SatAmount,
30 pub min_initial_lsp_balance_sat: SatAmount,
31 pub max_initial_lsp_balance_sat: SatAmount,
32 pub min_channel_balance_sat: SatAmount,
33 pub max_channel_balance_sat: SatAmount,
34 #[serde(skip_serializing, default)]
36 pub(crate) _private: (),
37}
38
39#[derive(Debug, Serialize, Deserialize, Clone)]
40pub struct Lsps1CreateOrderRequest {
41 pub lsp_balance_sat: SatAmount,
42 pub client_balance_sat: SatAmount,
43 pub confirms_within_blocks: u8,
44 pub channel_expiry_blocks: u32,
45 pub token: Option<String>,
46 pub refund_onchain_address: Option<OnchainAddress>,
47 pub announce_channel: bool,
48 #[serde(skip_serializing, default)]
50 pub(crate) _private: (),
51}
52
53impl ExpectedFields for Lsps1CreateOrderRequest {
54 fn expected_fields() -> Vec<String> {
55 vec![
56 "lsp_balance_sat".to_string(),
57 "client_balance_sat".to_string(),
58 "confirms_within_blocks".to_string(),
59 "channel_expiry_blocks".to_string(),
60 "token".to_string(),
61 "refund_onchain_address".to_string(),
62 "announce_channel".to_string(),
63 ]
64 }
65}
66
67#[derive(Debug, Serialize, Deserialize, Clone)]
68pub struct Lsps1CreateOrderResponse {
69 pub order_id: Uuid,
70 pub lsp_balance_sat: SatAmount,
71 pub client_balance_sat: SatAmount,
72 pub confirms_within_blocks: u8,
73 pub channel_expiry_blocks: u32,
74 pub token: String,
75 #[serde(rename = "announceChannel")]
76 pub announce_channel: bool,
77 pub created_at: IsoDatetime,
78 pub expires_at: IsoDatetime,
79 pub order_state: OrderState,
80
81 pub payment: Payment,
82 pub channel: Option<Channel>,
83 #[serde(skip_serializing, default)]
85 pub(crate) _private: (),
86}
87
88#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
89pub enum OrderState {
90 #[serde(rename = "CREATED")]
91 Created,
92 #[serde(rename = "COMPLETED")]
93 Completed,
94 #[serde(rename = "FAILED")]
95 Failed,
96}
97
98#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
99pub enum PaymentState {
100 #[serde(rename = "EXPECT_PAYMENT")]
101 ExpectPayment,
102 #[serde(rename = "HOLD")]
103 Hold,
104 #[serde(rename = "PAID")]
105 Paid,
106 #[serde(rename = "REFUNDED")]
107 Refunded,
108}
109
110#[derive(Debug, Serialize, Deserialize, Clone)]
111pub struct OnchainPayment {
112 pub outpoint: String,
113 pub sat: SatAmount,
114 pub confirmed: bool,
115 #[serde(skip_serializing, default)]
117 pub(crate) _private: (),
118}
119
120#[derive(Debug, Serialize, Deserialize, Clone)]
121pub struct Payment {
122 pub state: PaymentState,
123 pub fee_total_sat: SatAmount,
124 pub order_total_sat: SatAmount,
125
126 pub bolt11_invoice: String,
127 pub onchain_address: Option<OnchainAddress>,
128 pub min_onchain_payment_confirmations: Option<u8>,
129
130 pub min_fee_for_0conf: Option<FeeRate>,
131 pub onchain_payment: Option<OnchainPayment>,
132
133 #[serde(skip_serializing, default)]
135 pub(crate) _private: (),
136}
137
138#[derive(Debug, Serialize, Deserialize, Clone)]
139pub struct Channel {
140 pub funded_at: IsoDatetime,
141 pub funding_outpoint: Outpoint,
142 pub expires_at: IsoDatetime,
143}
144
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct Lsps1GetOrderRequest {
148 pub order_id: String,
149 #[serde(skip_serializing, default)]
150 pub(crate) _private: (),
151}
152
153impl ExpectedFields for Lsps1GetOrderRequest {
154 fn expected_fields() -> Vec<String> {
155 vec!["order_id".to_string()]
156 }
157}
158
159pub type Lsps1GetOrderResponse = Lsps1CreateOrderResponse;
160
161#[cfg(test)]
162mod test {
163
164 use super::*;
165
166 #[test]
167 fn deserialize_lsps1_options() {
168 let json_data = serde_json::json!(
170 {
171 "min_channel_confirmations": 0,
172 "min_onchain_payment_confirmations": 1,
173 "supports_zero_channel_reserve": true,
174 "min_onchain_payment_size_sat": null,
175 "max_channel_expiry_blocks": 20160,
176 "min_initial_client_balance_sat": "20000",
177 "max_initial_client_balance_sat": "100000000",
178 "min_initial_lsp_balance_sat": "0",
179 "max_initial_lsp_balance_sat": "100000000",
180 "min_channel_balance_sat": "50000",
181 "max_channel_balance_sat": "100000000"
182 }
183
184 );
185 serde_json::from_value::<Lsps1Options>(json_data).unwrap();
186 }
187
188 #[test]
189 fn deserialize_lsps1_info() {
190 let json_data = serde_json::json!(
192 {
193 "supported_versions": [1],
194 "website": "http://example.com/contact",
195 "options": {
196 "min_channel_confirmations": 0,
197 "min_onchain_payment_confirmations": 1,
198 "supports_zero_channel_reserve": true,
199 "min_onchain_payment_size_sat": null,
200 "max_channel_expiry_blocks": 20160,
201 "min_initial_client_balance_sat": "20000",
202 "max_initial_client_balance_sat": "100000000",
203 "min_initial_lsp_balance_sat": "0",
204 "max_initial_lsp_balance_sat": "100000000",
205 "min_channel_balance_sat": "50000",
206 "max_channel_balance_sat": "100000000"
207 }
208 }
209 );
210
211 serde_json::from_value::<Lsps1GetInfoResponse>(json_data).unwrap();
212 }
213
214 #[test]
215 fn lsps1_implements_serialize() {
216 use core::str::FromStr;
217 let onchain = OnchainAddress::from_str("32iVBEu4dxkUQk9dJbZUiBiQdmypcEyJRf").unwrap();
218
219 let request = Lsps1CreateOrderRequest {
220 lsp_balance_sat: SatAmount::new(100_000),
221 client_balance_sat: SatAmount::new(1_000),
222 confirms_within_blocks: 10,
223 channel_expiry_blocks: 1000,
224 token: None,
225 refund_onchain_address: Some(onchain),
226 announce_channel: false,
227 _private: (),
228 };
229
230 let _ = serde_json::to_value(request).unwrap();
231 }
232}