1use alloc::string::String;
8
9use core::fmt::{self, Display};
10use core::str::FromStr;
11
12use crate::lsps0::msgs::{
13 LSPS0ListProtocolsRequest, LSPS0Message, LSPS0Request, LSPS0Response,
14 LSPS0_LISTPROTOCOLS_METHOD_NAME,
15};
16
17use crate::lsps1::msgs::{
18 LSPS1Message, LSPS1Request, LSPS1Response, LSPS1_CREATE_ORDER_METHOD_NAME,
19 LSPS1_GET_INFO_METHOD_NAME, LSPS1_GET_ORDER_METHOD_NAME,
20};
21use crate::lsps2::msgs::{
22 LSPS2Message, LSPS2Request, LSPS2Response, LSPS2_BUY_METHOD_NAME, LSPS2_GET_INFO_METHOD_NAME,
23};
24use crate::lsps5::msgs::{
25 LSPS5Message, LSPS5Request, LSPS5Response, LSPS5_LIST_WEBHOOKS_METHOD_NAME,
26 LSPS5_REMOVE_WEBHOOK_METHOD_NAME, LSPS5_SET_WEBHOOK_METHOD_NAME,
27};
28
29use crate::prelude::HashMap;
30
31use lightning::ln::msgs::{DecodeError, LightningError};
32use lightning::ln::wire;
33use lightning::util::ser::{LengthLimitedRead, LengthReadable, Readable, WithoutLength, Writeable};
34
35use bitcoin::secp256k1::PublicKey;
36
37use core::time::Duration;
38#[cfg(feature = "time")]
39use std::time::{SystemTime, UNIX_EPOCH};
40
41use serde::de::{self, MapAccess, Visitor};
42use serde::ser::SerializeStruct;
43use serde::{Deserialize, Deserializer, Serialize};
44use serde_json::json;
45
46pub(crate) const LSPS_MESSAGE_SERIALIZED_STRUCT_NAME: &str = "LSPSMessage";
47pub(crate) const JSONRPC_FIELD_KEY: &str = "jsonrpc";
48pub(crate) const JSONRPC_FIELD_VALUE: &str = "2.0";
49pub(crate) const JSONRPC_METHOD_FIELD_KEY: &str = "method";
50pub(crate) const JSONRPC_ID_FIELD_KEY: &str = "id";
51pub(crate) const JSONRPC_PARAMS_FIELD_KEY: &str = "params";
52pub(crate) const JSONRPC_RESULT_FIELD_KEY: &str = "result";
53pub(crate) const JSONRPC_ERROR_FIELD_KEY: &str = "error";
54pub(crate) const JSONRPC_INVALID_MESSAGE_ERROR_CODE: i32 = -32700;
55pub(crate) const JSONRPC_INVALID_MESSAGE_ERROR_MESSAGE: &str = "parse error";
56pub(crate) const JSONRPC_INTERNAL_ERROR_ERROR_CODE: i32 = -32603;
57pub(crate) const JSONRPC_INTERNAL_ERROR_ERROR_MESSAGE: &str = "Internal error";
58
59pub(crate) const LSPS0_CLIENT_REJECTED_ERROR_CODE: i32 = 1;
60
61#[derive(Copy, Clone, Debug, PartialEq, Eq)]
62pub(crate) enum LSPSMethod {
63 LSPS0ListProtocols,
64 LSPS1GetInfo,
65 LSPS1GetOrder,
66 LSPS1CreateOrder,
67 LSPS2GetInfo,
68 LSPS2Buy,
69 LSPS5SetWebhook,
70 LSPS5ListWebhooks,
71 LSPS5RemoveWebhook,
72}
73
74impl LSPSMethod {
75 fn as_static_str(&self) -> &'static str {
76 match self {
77 Self::LSPS0ListProtocols => LSPS0_LISTPROTOCOLS_METHOD_NAME,
78 Self::LSPS1GetInfo => LSPS1_GET_INFO_METHOD_NAME,
79 Self::LSPS1CreateOrder => LSPS1_CREATE_ORDER_METHOD_NAME,
80 Self::LSPS1GetOrder => LSPS1_GET_ORDER_METHOD_NAME,
81 Self::LSPS2GetInfo => LSPS2_GET_INFO_METHOD_NAME,
82 Self::LSPS2Buy => LSPS2_BUY_METHOD_NAME,
83 Self::LSPS5SetWebhook => LSPS5_SET_WEBHOOK_METHOD_NAME,
84 Self::LSPS5ListWebhooks => LSPS5_LIST_WEBHOOKS_METHOD_NAME,
85 Self::LSPS5RemoveWebhook => LSPS5_REMOVE_WEBHOOK_METHOD_NAME,
86 }
87 }
88}
89
90impl FromStr for LSPSMethod {
91 type Err = &'static str;
92 fn from_str(s: &str) -> Result<Self, Self::Err> {
93 match s {
94 LSPS0_LISTPROTOCOLS_METHOD_NAME => Ok(Self::LSPS0ListProtocols),
95 LSPS1_GET_INFO_METHOD_NAME => Ok(Self::LSPS1GetInfo),
96 LSPS1_CREATE_ORDER_METHOD_NAME => Ok(Self::LSPS1CreateOrder),
97 LSPS1_GET_ORDER_METHOD_NAME => Ok(Self::LSPS1GetOrder),
98 LSPS2_GET_INFO_METHOD_NAME => Ok(Self::LSPS2GetInfo),
99 LSPS2_BUY_METHOD_NAME => Ok(Self::LSPS2Buy),
100 LSPS5_SET_WEBHOOK_METHOD_NAME => Ok(Self::LSPS5SetWebhook),
101 LSPS5_LIST_WEBHOOKS_METHOD_NAME => Ok(Self::LSPS5ListWebhooks),
102 LSPS5_REMOVE_WEBHOOK_METHOD_NAME => Ok(Self::LSPS5RemoveWebhook),
103 _ => Err(&"Unknown method name"),
104 }
105 }
106}
107
108impl From<&LSPS0Request> for LSPSMethod {
109 fn from(value: &LSPS0Request) -> Self {
110 match value {
111 LSPS0Request::ListProtocols(_) => Self::LSPS0ListProtocols,
112 }
113 }
114}
115
116impl From<&LSPS1Request> for LSPSMethod {
117 fn from(value: &LSPS1Request) -> Self {
118 match value {
119 LSPS1Request::GetInfo(_) => Self::LSPS1GetInfo,
120 LSPS1Request::CreateOrder(_) => Self::LSPS1CreateOrder,
121 LSPS1Request::GetOrder(_) => Self::LSPS1GetOrder,
122 }
123 }
124}
125
126impl From<&LSPS2Request> for LSPSMethod {
127 fn from(value: &LSPS2Request) -> Self {
128 match value {
129 LSPS2Request::GetInfo(_) => Self::LSPS2GetInfo,
130 LSPS2Request::Buy(_) => Self::LSPS2Buy,
131 }
132 }
133}
134
135impl From<&LSPS5Request> for LSPSMethod {
136 fn from(value: &LSPS5Request) -> Self {
137 match value {
138 LSPS5Request::SetWebhook(_) => Self::LSPS5SetWebhook,
139 LSPS5Request::ListWebhooks(_) => Self::LSPS5ListWebhooks,
140 LSPS5Request::RemoveWebhook(_) => Self::LSPS5RemoveWebhook,
141 }
142 }
143}
144
145impl<'de> Deserialize<'de> for LSPSMethod {
146 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
147 where
148 D: Deserializer<'de>,
149 {
150 let s = <&str>::deserialize(deserializer)?;
151 FromStr::from_str(&s).map_err(de::Error::custom)
152 }
153}
154
155impl Serialize for LSPSMethod {
156 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
157 where
158 S: serde::Serializer,
159 {
160 serializer.serialize_str(&self.as_static_str())
161 }
162}
163
164pub const LSPS_MESSAGE_TYPE_ID: u16 = 37913;
166
167pub(crate) trait LSPSProtocolMessageHandler {
172 type ProtocolMessage: TryFrom<LSPSMessage> + Into<LSPSMessage>;
173 const PROTOCOL_NUMBER: Option<u16>;
174
175 fn handle_message(
176 &self, message: Self::ProtocolMessage, counterparty_node_id: &PublicKey,
177 ) -> Result<(), LightningError>;
178}
179
180#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
182pub struct RawLSPSMessage {
183 pub payload: String,
185}
186
187impl lightning::util::ser::Writeable for RawLSPSMessage {
190 fn write<W: lightning::util::ser::Writer>(
191 &self, w: &mut W,
192 ) -> Result<(), lightning::io::Error> {
193 WithoutLength(&self.payload).write(w)?;
194 Ok(())
195 }
196}
197
198impl LengthReadable for RawLSPSMessage {
199 fn read_from_fixed_length_buffer<R: LengthLimitedRead>(r: &mut R) -> Result<Self, DecodeError> {
200 let payload_without_length: WithoutLength<String> =
201 LengthReadable::read_from_fixed_length_buffer(r)?;
202 Ok(Self { payload: payload_without_length.0 })
203 }
204}
205
206impl wire::Type for RawLSPSMessage {
207 fn type_id(&self) -> u16 {
208 LSPS_MESSAGE_TYPE_ID
209 }
210}
211
212#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
217#[serde(transparent)]
218pub struct LSPSRequestId(pub String);
219
220impl Writeable for LSPSRequestId {
221 fn write<W: lightning::util::ser::Writer>(
222 &self, writer: &mut W,
223 ) -> Result<(), lightning::io::Error> {
224 self.0.write(writer)?;
225 Ok(())
226 }
227}
228
229impl Readable for LSPSRequestId {
230 fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
231 let s: String = Readable::read(reader)?;
232 Ok(Self(s))
233 }
234}
235
236#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, Deserialize, Serialize)]
238#[serde(transparent)]
239pub struct LSPSDateTime(pub chrono::DateTime<chrono::Utc>);
240
241impl LSPSDateTime {
242 pub fn to_rfc3339(&self) -> String {
244 self.0.to_rfc3339()
245 }
246
247 #[cfg(feature = "time")]
249 pub fn is_past(&self) -> bool {
250 let now_seconds_since_epoch = SystemTime::now()
251 .duration_since(UNIX_EPOCH)
252 .expect("system clock to be ahead of the unix epoch")
253 .as_secs();
254 let datetime_seconds_since_epoch =
255 self.0.timestamp().try_into().expect("expiration to be ahead of unix epoch");
256 now_seconds_since_epoch > datetime_seconds_since_epoch
257 }
258
259 pub fn duration_since(&self, other: &Self) -> Duration {
261 let diff_secs = self.0.timestamp().abs_diff(other.0.timestamp());
262 Duration::from_secs(diff_secs)
263 }
264
265 pub fn new_from_duration_since_epoch(duration: Duration) -> Self {
267 Self(chrono::DateTime::UNIX_EPOCH + duration)
268 }
269}
270
271impl FromStr for LSPSDateTime {
272 type Err = ();
273 fn from_str(s: &str) -> Result<Self, Self::Err> {
274 let datetime = chrono::DateTime::parse_from_rfc3339(s).map_err(|_| ())?;
275 Ok(Self(datetime.into()))
276 }
277}
278
279impl Display for LSPSDateTime {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 write!(f, "{}", self.to_rfc3339())
282 }
283}
284
285impl Writeable for LSPSDateTime {
286 fn write<W: lightning::util::ser::Writer>(
287 &self, writer: &mut W,
288 ) -> Result<(), lightning::io::Error> {
289 self.to_rfc3339().write(writer)?;
290 Ok(())
291 }
292}
293
294impl Readable for LSPSDateTime {
295 fn read<R: lightning::io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
296 let s: String = Readable::read(reader)?;
297 let val = Self::from_str(&s).map_err(|_| lightning::ln::msgs::DecodeError::InvalidValue)?;
298 Ok(val)
299 }
300}
301
302#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
307pub struct LSPSResponseError {
308 pub code: i32,
310 pub message: String,
312 pub data: Option<String>,
314}
315
316#[derive(Clone, Debug, PartialEq, Eq)]
318pub enum LSPSMessage {
319 Invalid(LSPSResponseError),
321 LSPS0(LSPS0Message),
323 LSPS1(LSPS1Message),
325 LSPS2(LSPS2Message),
327 LSPS5(LSPS5Message),
329}
330
331impl LSPSMessage {
332 pub(crate) fn from_str_with_id_map(
337 json_str: &str, request_id_to_method_map: &mut HashMap<LSPSRequestId, LSPSMethod>,
338 ) -> Result<Self, serde_json::Error> {
339 let deserializer = &mut serde_json::Deserializer::from_str(json_str);
340 let visitor = LSPSMessageVisitor { request_id_to_method_map };
341 deserializer.deserialize_any(visitor)
342 }
343
344 pub(crate) fn get_request_id_and_method(&self) -> Option<(LSPSRequestId, LSPSMethod)> {
346 match self {
347 LSPSMessage::LSPS0(LSPS0Message::Request(request_id, request)) => {
348 Some((LSPSRequestId(request_id.0.clone()), request.into()))
349 },
350 LSPSMessage::LSPS1(LSPS1Message::Request(request_id, request)) => {
351 Some((LSPSRequestId(request_id.0.clone()), request.into()))
352 },
353 LSPSMessage::LSPS2(LSPS2Message::Request(request_id, request)) => {
354 Some((LSPSRequestId(request_id.0.clone()), request.into()))
355 },
356 LSPSMessage::LSPS5(LSPS5Message::Request(request_id, request)) => {
357 Some((LSPSRequestId(request_id.0.clone()), request.into()))
358 },
359 _ => None,
360 }
361 }
362}
363
364impl Serialize for LSPSMessage {
365 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
366 where
367 S: serde::Serializer,
368 {
369 let mut jsonrpc_object =
370 serializer.serialize_struct(LSPS_MESSAGE_SERIALIZED_STRUCT_NAME, 3)?;
371
372 jsonrpc_object.serialize_field(JSONRPC_FIELD_KEY, JSONRPC_FIELD_VALUE)?;
373
374 match self {
375 LSPSMessage::LSPS0(LSPS0Message::Request(request_id, request)) => {
376 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
377 jsonrpc_object
378 .serialize_field(JSONRPC_METHOD_FIELD_KEY, &LSPSMethod::from(request))?;
379
380 match request {
381 LSPS0Request::ListProtocols(params) => {
382 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
383 },
384 };
385 },
386 LSPSMessage::LSPS0(LSPS0Message::Response(request_id, response)) => {
387 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
388
389 match response {
390 LSPS0Response::ListProtocols(result) => {
391 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?;
392 },
393 LSPS0Response::ListProtocolsError(error) => {
394 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?;
395 },
396 }
397 },
398 LSPSMessage::LSPS1(LSPS1Message::Request(request_id, request)) => {
399 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
400 jsonrpc_object
401 .serialize_field(JSONRPC_METHOD_FIELD_KEY, &LSPSMethod::from(request))?;
402
403 match request {
404 LSPS1Request::GetInfo(params) => {
405 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
406 },
407 LSPS1Request::CreateOrder(params) => {
408 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
409 },
410 LSPS1Request::GetOrder(params) => {
411 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
412 },
413 }
414 },
415 LSPSMessage::LSPS1(LSPS1Message::Response(request_id, response)) => {
416 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
417
418 match response {
419 LSPS1Response::GetInfo(result) => {
420 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
421 },
422 LSPS1Response::GetInfoError(error) => {
423 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
424 },
425 LSPS1Response::CreateOrder(result) => {
426 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
427 },
428 LSPS1Response::CreateOrderError(error) => {
429 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
430 },
431 LSPS1Response::GetOrder(result) => {
432 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
433 },
434 LSPS1Response::GetOrderError(error) => {
435 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
436 },
437 }
438 },
439 LSPSMessage::LSPS2(LSPS2Message::Request(request_id, request)) => {
440 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
441 jsonrpc_object
442 .serialize_field(JSONRPC_METHOD_FIELD_KEY, &LSPSMethod::from(request))?;
443
444 match request {
445 LSPS2Request::GetInfo(params) => {
446 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
447 },
448 LSPS2Request::Buy(params) => {
449 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
450 },
451 }
452 },
453 LSPSMessage::LSPS2(LSPS2Message::Response(request_id, response)) => {
454 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
455
456 match response {
457 LSPS2Response::GetInfo(result) => {
458 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
459 },
460 LSPS2Response::GetInfoError(error) => {
461 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
462 },
463 LSPS2Response::Buy(result) => {
464 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
465 },
466 LSPS2Response::BuyError(error) => {
467 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
468 },
469 }
470 },
471 LSPSMessage::Invalid(error) => {
472 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &serde_json::Value::Null)?;
473 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, &error)?;
474 },
475 LSPSMessage::LSPS5(LSPS5Message::Request(request_id, request)) => {
476 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
477 jsonrpc_object
478 .serialize_field(JSONRPC_METHOD_FIELD_KEY, &LSPSMethod::from(request))?;
479
480 match request {
481 LSPS5Request::SetWebhook(params) => {
482 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
483 },
484 LSPS5Request::ListWebhooks(params) => {
485 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
486 },
487 LSPS5Request::RemoveWebhook(params) => {
488 jsonrpc_object.serialize_field(JSONRPC_PARAMS_FIELD_KEY, params)?
489 },
490 }
491 },
492 LSPSMessage::LSPS5(LSPS5Message::Response(request_id, response)) => {
493 jsonrpc_object.serialize_field(JSONRPC_ID_FIELD_KEY, &request_id.0)?;
494
495 match response {
496 LSPS5Response::SetWebhook(result) => {
497 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
498 },
499 LSPS5Response::SetWebhookError(error) => {
500 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
501 },
502 LSPS5Response::ListWebhooks(result) => {
503 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
504 },
505 LSPS5Response::RemoveWebhook(result) => {
506 jsonrpc_object.serialize_field(JSONRPC_RESULT_FIELD_KEY, result)?
507 },
508 LSPS5Response::RemoveWebhookError(error) => {
509 jsonrpc_object.serialize_field(JSONRPC_ERROR_FIELD_KEY, error)?
510 },
511 }
512 },
513 }
514
515 jsonrpc_object.end()
516 }
517}
518
519struct LSPSMessageVisitor<'a> {
520 request_id_to_method_map: &'a mut HashMap<LSPSRequestId, LSPSMethod>,
521}
522
523impl<'de, 'a> Visitor<'de> for LSPSMessageVisitor<'a> {
524 type Value = LSPSMessage;
525
526 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
527 formatter.write_str("JSON-RPC object")
528 }
529
530 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
531 where
532 A: MapAccess<'de>,
533 {
534 let mut id: Option<LSPSRequestId> = None;
535 let mut method: Option<LSPSMethod> = None;
536 let mut params = None;
537 let mut result = None;
538 let mut error: Option<LSPSResponseError> = None;
539
540 while let Some(key) = map.next_key()? {
541 match key {
542 "id" => {
543 id = map.next_value()?;
544 },
545 "method" => {
546 method = Some(map.next_value()?);
547 },
548 "params" => {
549 params = Some(map.next_value()?);
550 },
551 "result" => {
552 result = Some(map.next_value()?);
553 },
554 "error" => {
555 error = Some(map.next_value()?);
556 },
557 _ => {
558 let _: serde_json::Value = map.next_value()?;
559 },
560 }
561 }
562
563 let id = match id {
564 Some(id) => id,
565 None => {
566 if let Some(method) = method {
567 return Err(de::Error::custom(format!(
568 "Received unknown notification: {}",
569 method.as_static_str()
570 )));
571 } else {
572 if let Some(error) = error {
573 if error.code == JSONRPC_INVALID_MESSAGE_ERROR_CODE {
574 return Ok(LSPSMessage::Invalid(error));
575 }
576 }
577
578 return Err(de::Error::custom("Received unknown error message"));
579 }
580 },
581 };
582
583 match method {
584 Some(method) => match method {
585 LSPSMethod::LSPS0ListProtocols => Ok(LSPSMessage::LSPS0(LSPS0Message::Request(
586 id,
587 LSPS0Request::ListProtocols(LSPS0ListProtocolsRequest {}),
588 ))),
589 LSPSMethod::LSPS1GetInfo => {
590 let request = serde_json::from_value(params.unwrap_or(json!({})))
591 .map_err(de::Error::custom)?;
592 Ok(LSPSMessage::LSPS1(LSPS1Message::Request(
593 id,
594 LSPS1Request::GetInfo(request),
595 )))
596 },
597 LSPSMethod::LSPS1CreateOrder => {
598 let request = serde_json::from_value(params.unwrap_or(json!({})))
599 .map_err(de::Error::custom)?;
600 Ok(LSPSMessage::LSPS1(LSPS1Message::Request(
601 id,
602 LSPS1Request::CreateOrder(request),
603 )))
604 },
605 LSPSMethod::LSPS1GetOrder => {
606 let request = serde_json::from_value(params.unwrap_or(json!({})))
607 .map_err(de::Error::custom)?;
608 Ok(LSPSMessage::LSPS1(LSPS1Message::Request(
609 id,
610 LSPS1Request::GetOrder(request),
611 )))
612 },
613 LSPSMethod::LSPS2GetInfo => {
614 let request = serde_json::from_value(params.unwrap_or(json!({})))
615 .map_err(de::Error::custom)?;
616 Ok(LSPSMessage::LSPS2(LSPS2Message::Request(
617 id,
618 LSPS2Request::GetInfo(request),
619 )))
620 },
621 LSPSMethod::LSPS2Buy => {
622 let request = serde_json::from_value(params.unwrap_or(json!({})))
623 .map_err(de::Error::custom)?;
624 Ok(LSPSMessage::LSPS2(LSPS2Message::Request(id, LSPS2Request::Buy(request))))
625 },
626 LSPSMethod::LSPS5SetWebhook => {
627 let request = serde_json::from_value(params.unwrap_or(json!({})))
628 .map_err(de::Error::custom)?;
629 Ok(LSPSMessage::LSPS5(LSPS5Message::Request(
630 id,
631 LSPS5Request::SetWebhook(request),
632 )))
633 },
634 LSPSMethod::LSPS5ListWebhooks => {
635 let request = serde_json::from_value(params.unwrap_or(json!({})))
636 .map_err(de::Error::custom)?;
637 Ok(LSPSMessage::LSPS5(LSPS5Message::Request(
638 id,
639 LSPS5Request::ListWebhooks(request),
640 )))
641 },
642 LSPSMethod::LSPS5RemoveWebhook => {
643 let request = serde_json::from_value(params.unwrap_or(json!({})))
644 .map_err(de::Error::custom)?;
645 Ok(LSPSMessage::LSPS5(LSPS5Message::Request(
646 id,
647 LSPS5Request::RemoveWebhook(request),
648 )))
649 },
650 },
651 None => match self.request_id_to_method_map.remove(&id) {
652 Some(method) => match method {
653 LSPSMethod::LSPS0ListProtocols => {
654 if let Some(error) = error {
655 Ok(LSPSMessage::LSPS0(LSPS0Message::Response(
656 id,
657 LSPS0Response::ListProtocolsError(error),
658 )))
659 } else if let Some(result) = result {
660 let list_protocols_response =
661 serde_json::from_value(result).map_err(de::Error::custom)?;
662 Ok(LSPSMessage::LSPS0(LSPS0Message::Response(
663 id,
664 LSPS0Response::ListProtocols(list_protocols_response),
665 )))
666 } else {
667 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
668 }
669 },
670 LSPSMethod::LSPS1GetInfo => {
671 if let Some(error) = error {
672 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
673 id,
674 LSPS1Response::GetInfoError(error),
675 )))
676 } else if let Some(result) = result {
677 let response =
678 serde_json::from_value(result).map_err(de::Error::custom)?;
679 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
680 id,
681 LSPS1Response::GetInfo(response),
682 )))
683 } else {
684 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
685 }
686 },
687 LSPSMethod::LSPS1CreateOrder => {
688 if let Some(error) = error {
689 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
690 id,
691 LSPS1Response::CreateOrderError(error),
692 )))
693 } else if let Some(result) = result {
694 let response =
695 serde_json::from_value(result).map_err(de::Error::custom)?;
696 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
697 id,
698 LSPS1Response::CreateOrder(response),
699 )))
700 } else {
701 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
702 }
703 },
704 LSPSMethod::LSPS1GetOrder => {
705 if let Some(error) = error {
706 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
707 id,
708 LSPS1Response::GetOrderError(error),
709 )))
710 } else if let Some(result) = result {
711 let response =
712 serde_json::from_value(result).map_err(de::Error::custom)?;
713 Ok(LSPSMessage::LSPS1(LSPS1Message::Response(
714 id,
715 LSPS1Response::GetOrder(response),
716 )))
717 } else {
718 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
719 }
720 },
721 LSPSMethod::LSPS2GetInfo => {
722 if let Some(error) = error {
723 Ok(LSPSMessage::LSPS2(LSPS2Message::Response(
724 id,
725 LSPS2Response::GetInfoError(error),
726 )))
727 } else if let Some(result) = result {
728 let response =
729 serde_json::from_value(result).map_err(de::Error::custom)?;
730 Ok(LSPSMessage::LSPS2(LSPS2Message::Response(
731 id,
732 LSPS2Response::GetInfo(response),
733 )))
734 } else {
735 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
736 }
737 },
738 LSPSMethod::LSPS2Buy => {
739 if let Some(error) = error {
740 Ok(LSPSMessage::LSPS2(LSPS2Message::Response(
741 id,
742 LSPS2Response::BuyError(error),
743 )))
744 } else if let Some(result) = result {
745 let response =
746 serde_json::from_value(result).map_err(de::Error::custom)?;
747 Ok(LSPSMessage::LSPS2(LSPS2Message::Response(
748 id,
749 LSPS2Response::Buy(response),
750 )))
751 } else {
752 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
753 }
754 },
755 LSPSMethod::LSPS5SetWebhook => {
756 if let Some(error) = error {
757 Ok(LSPSMessage::LSPS5(LSPS5Message::Response(
758 id,
759 LSPS5Response::SetWebhookError(error.into()),
760 )))
761 } else if let Some(result) = result {
762 let response =
763 serde_json::from_value(result).map_err(de::Error::custom)?;
764 Ok(LSPSMessage::LSPS5(LSPS5Message::Response(
765 id,
766 LSPS5Response::SetWebhook(response),
767 )))
768 } else {
769 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
770 }
771 },
772 LSPSMethod::LSPS5ListWebhooks => {
773 if let Some(result) = result {
774 let response =
775 serde_json::from_value(result).map_err(de::Error::custom)?;
776 Ok(LSPSMessage::LSPS5(LSPS5Message::Response(
777 id,
778 LSPS5Response::ListWebhooks(response),
779 )))
780 } else {
781 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
782 }
783 },
784 LSPSMethod::LSPS5RemoveWebhook => {
785 if let Some(error) = error {
786 Ok(LSPSMessage::LSPS5(LSPS5Message::Response(
787 id,
788 LSPS5Response::RemoveWebhookError(error.into()),
789 )))
790 } else if let Some(result) = result {
791 let response =
792 serde_json::from_value(result).map_err(de::Error::custom)?;
793 Ok(LSPSMessage::LSPS5(LSPS5Message::Response(
794 id,
795 LSPS5Response::RemoveWebhook(response),
796 )))
797 } else {
798 Err(de::Error::custom("Received invalid JSON-RPC object: one of method, result, or error required"))
799 }
800 },
801 },
802 None => Err(de::Error::custom(format!(
803 "Received response for unknown request id: {}",
804 id.0
805 ))),
806 },
807 }
808 }
809}
810
811pub(crate) mod string_amount {
812 use alloc::string::{String, ToString};
813 use core::str::FromStr;
814 use serde::de::Unexpected;
815 use serde::{Deserialize, Deserializer, Serializer};
816
817 pub(crate) fn serialize<S>(x: &u64, s: S) -> Result<S::Ok, S::Error>
818 where
819 S: Serializer,
820 {
821 s.serialize_str(&x.to_string())
822 }
823
824 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
825 where
826 D: Deserializer<'de>,
827 {
828 let buf = String::deserialize(deserializer)?;
829
830 u64::from_str(&buf).map_err(|_| {
831 serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid u64 amount string")
832 })
833 }
834}
835
836pub(crate) mod string_amount_option {
837 use alloc::string::{String, ToString};
838 use core::str::FromStr;
839 use serde::de::Unexpected;
840 use serde::{Deserialize, Deserializer, Serialize, Serializer};
841
842 pub(crate) fn serialize<S>(x: &Option<u64>, s: S) -> Result<S::Ok, S::Error>
843 where
844 S: Serializer,
845 {
846 let v = x.as_ref().map(|v| v.to_string());
847 Option::<String>::serialize(&v, s)
848 }
849
850 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
851 where
852 D: Deserializer<'de>,
853 {
854 if let Some(buf) = Option::<String>::deserialize(deserializer)? {
855 let val = u64::from_str(&buf).map_err(|_| {
856 serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid u64 amount string")
857 })?;
858 Ok(Some(val))
859 } else {
860 Ok(None)
861 }
862 }
863}
864
865pub(crate) mod string_offer {
866 use alloc::string::{String, ToString};
867 use core::str::FromStr;
868 use lightning::offers::offer::Offer;
869 use serde::de::Unexpected;
870 use serde::{Deserialize, Deserializer, Serializer};
871
872 pub(crate) fn serialize<S>(x: &Offer, s: S) -> Result<S::Ok, S::Error>
873 where
874 S: Serializer,
875 {
876 s.serialize_str(&x.to_string())
877 }
878
879 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Offer, D::Error>
880 where
881 D: Deserializer<'de>,
882 {
883 let buf = String::deserialize(deserializer)?;
884
885 Offer::from_str(&buf).map_err(|_| {
886 serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid offer string")
887 })
888 }
889}
890
891pub(crate) mod unchecked_address {
892 use alloc::string::{String, ToString};
893 use bitcoin::Address;
894 use core::str::FromStr;
895 use serde::de::Unexpected;
896 use serde::{Deserialize, Deserializer, Serializer};
897
898 pub(crate) fn serialize<S>(x: &Address, s: S) -> Result<S::Ok, S::Error>
899 where
900 S: Serializer,
901 {
902 s.serialize_str(&x.to_string())
903 }
904
905 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Address, D::Error>
906 where
907 D: Deserializer<'de>,
908 {
909 let buf = String::deserialize(deserializer)?;
910
911 let parsed_addr = Address::from_str(&buf).map_err(|_| {
912 serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid address string")
913 })?;
914 Ok(parsed_addr.assume_checked())
915 }
916}
917
918pub(crate) mod unchecked_address_option {
919 use alloc::string::{String, ToString};
920 use bitcoin::Address;
921 use core::str::FromStr;
922 use serde::de::Unexpected;
923 use serde::{Deserialize, Deserializer, Serialize, Serializer};
924
925 pub(crate) fn serialize<S>(x: &Option<Address>, s: S) -> Result<S::Ok, S::Error>
926 where
927 S: Serializer,
928 {
929 let v = x.as_ref().map(|v| v.to_string());
930 Option::<String>::serialize(&v, s)
931 }
932
933 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<Option<bitcoin::Address>, D::Error>
934 where
935 D: Deserializer<'de>,
936 {
937 if let Some(buf) = Option::<String>::deserialize(deserializer)? {
938 let val = Address::from_str(&buf).map_err(|_| {
939 serde::de::Error::invalid_value(Unexpected::Str(&buf), &"invalid address string")
940 })?;
941 Ok(Some(val.assume_checked()))
942 } else {
943 Ok(None)
944 }
945 }
946}
947
948pub(crate) mod u32_fee_rate {
949 use bitcoin::FeeRate;
950 use serde::{Deserialize, Deserializer, Serializer};
951
952 pub(crate) fn serialize<S>(x: &FeeRate, s: S) -> Result<S::Ok, S::Error>
953 where
954 S: Serializer,
955 {
956 let fee_rate_sat_kwu = x.to_sat_per_kwu();
957 s.serialize_u32(fee_rate_sat_kwu as u32)
958 }
959
960 pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<FeeRate, D::Error>
961 where
962 D: Deserializer<'de>,
963 {
964 let fee_rate_sat_kwu = u32::deserialize(deserializer)?;
965
966 Ok(FeeRate::from_sat_per_kwu(fee_rate_sat_kwu as u64))
967 }
968}
969
970#[cfg(test)]
971mod tests {
972 use super::*;
973
974 use lightning::io::Cursor;
975
976 #[test]
977 fn datetime_serializaton() {
978 let expected_datetime = LSPSDateTime::from_str("2035-05-20T08:30:45Z").unwrap();
979 let mut buf = Vec::new();
980 expected_datetime.write(&mut buf).unwrap();
981 let decoded_datetime: LSPSDateTime = Readable::read(&mut Cursor::new(buf)).unwrap();
982 assert_eq!(expected_datetime, decoded_datetime);
983 }
984}