1use anyhow::Context;
3use anyhow::{anyhow, Error, Result};
4use bitcoin::hashes::Hash as BitcoinHash;
5use serde::{Deserialize, Serialize};
6use serde::{Deserializer, Serializer};
7use serde_json::Value;
8use std::fmt::{Display, Formatter};
9use std::str::FromStr;
10use std::string::ToString;
11
12pub use bitcoin::hashes::sha256::Hash as Sha256;
13pub use bitcoin::secp256k1::PublicKey;
14
15#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
16#[allow(non_camel_case_types)]
17pub enum ChannelState {
18 OPENINGD = 0,
19 CHANNELD_AWAITING_LOCKIN = 1,
20 CHANNELD_NORMAL = 2,
21 CHANNELD_SHUTTING_DOWN = 3,
22 CLOSINGD_SIGEXCHANGE = 4,
23 CLOSINGD_COMPLETE = 5,
24 AWAITING_UNILATERAL = 6,
25 FUNDING_SPEND_SEEN = 7,
26 ONCHAIN = 8,
27 DUALOPEND_OPEN_INIT = 9,
28 DUALOPEND_AWAITING_LOCKIN = 10,
29 CHANNELD_AWAITING_SPLICE = 11,
30 DUALOPEND_OPEN_COMMITTED = 12,
31 DUALOPEND_OPEN_COMMIT_READY = 13,
32}
33
34#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
35#[allow(non_camel_case_types)]
36pub enum HtlcState {
37 SENT_ADD_HTLC = 0,
38 SENT_ADD_COMMIT = 1,
39 RCVD_ADD_REVOCATION = 2,
40 RCVD_ADD_ACK_COMMIT = 3,
41 SENT_ADD_ACK_REVOCATION = 4,
42 RCVD_ADD_ACK_REVOCATION = 5,
43 RCVD_REMOVE_HTLC = 6,
44 RCVD_REMOVE_COMMIT = 7,
45 SENT_REMOVE_REVOCATION = 8,
46 SENT_REMOVE_ACK_COMMIT = 9,
47 RCVD_REMOVE_ACK_REVOCATION = 10,
48 RCVD_ADD_HTLC = 11,
49 RCVD_ADD_COMMIT = 12,
50 SENT_ADD_REVOCATION = 13,
51 SENT_ADD_ACK_COMMIT = 14,
52 SENT_REMOVE_HTLC = 15,
53 SENT_REMOVE_COMMIT = 16,
54 RCVD_REMOVE_REVOCATION = 17,
55 RCVD_REMOVE_ACK_COMMIT = 18,
56 SENT_REMOVE_ACK_REVOCATION = 19,
57}
58
59#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
60#[allow(non_camel_case_types)]
61pub enum ChannelTypeName {
62 #[serde(rename = "static_remotekey/even")]
63 STATIC_REMOTEKEY_EVEN = 0,
64 #[serde(rename = "anchor_outputs/even")]
65 ANCHOR_OUTPUTS_EVEN = 1,
66 #[serde(rename = "anchors_zero_fee_htlc_tx/even")]
67 ANCHORS_ZERO_FEE_HTLC_TX_EVEN = 2,
68 #[serde(rename = "scid_alias/even")]
69 SCID_ALIAS_EVEN = 3,
70 #[serde(rename = "zeroconf/even")]
71 ZEROCONF_EVEN = 4,
72 #[serde(rename = "anchors/even")]
73 ANCHORS_EVEN = 5,
74}
75
76#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
77#[allow(non_camel_case_types)]
78pub enum AutocleanSubsystem {
79 #[serde(rename = "succeededforwards")]
80 SUCCEEDEDFORWARDS = 0,
81 #[serde(rename = "failedforwards")]
82 FAILEDFORWARDS = 1,
83 #[serde(rename = "succeededpays")]
84 SUCCEEDEDPAYS = 2,
85 #[serde(rename = "failedpays")]
86 FAILEDPAYS = 3,
87 #[serde(rename = "paidinvoices")]
88 PAIDINVOICES = 4,
89 #[serde(rename = "expiredinvoices")]
90 EXPIREDINVOICES = 5,
91}
92
93impl TryFrom<i32> for AutocleanSubsystem {
94 type Error = crate::Error;
95
96 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
97 match value {
98 0 => Ok(AutocleanSubsystem::SUCCEEDEDFORWARDS),
99 1 => Ok(AutocleanSubsystem::FAILEDFORWARDS),
100 2 => Ok(AutocleanSubsystem::SUCCEEDEDPAYS),
101 3 => Ok(AutocleanSubsystem::FAILEDPAYS),
102 4 => Ok(AutocleanSubsystem::PAIDINVOICES),
103 5 => Ok(AutocleanSubsystem::EXPIREDINVOICES),
104 _ => Err(anyhow!("Invalid AutocleanSubsystem {}", value)),
105 }
106 }
107}
108
109#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
110#[allow(non_camel_case_types)]
111pub enum PluginSubcommand {
112 #[serde(rename = "start")]
113 START = 0,
114 #[serde(rename = "stop")]
115 STOP = 1,
116 #[serde(rename = "rescan")]
117 RESCAN = 2,
118 #[serde(rename = "startdir")]
119 STARTDIR = 3,
120 #[serde(rename = "list")]
121 LIST = 4,
122}
123
124impl TryFrom<i32> for PluginSubcommand {
125 type Error = crate::Error;
126
127 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
128 match value {
129 0 => Ok(PluginSubcommand::START),
130 1 => Ok(PluginSubcommand::STOP),
131 2 => Ok(PluginSubcommand::RESCAN),
132 3 => Ok(PluginSubcommand::STARTDIR),
133 4 => Ok(PluginSubcommand::LIST),
134 _ => Err(anyhow!("Invalid PluginSubcommand mapping!")),
135 }
136 }
137}
138
139#[derive(Debug, Copy, Clone, PartialEq)]
143pub enum AmountOrAny {
144 Amount(Amount),
145 Any,
146}
147
148#[derive(Debug, Copy, Clone, PartialEq)]
151pub enum AmountOrAll {
152 Amount(Amount),
153 All,
154}
155
156#[derive(Copy, Clone, Debug, PartialEq)]
157pub struct Amount {
158 msat: u64,
159}
160
161impl Amount {
162 pub fn from_msat(msat: u64) -> Amount {
163 Amount { msat }
164 }
165
166 pub fn from_sat(sat: u64) -> Amount {
167 Amount { msat: 1_000 * sat }
168 }
169
170 pub fn from_btc(btc: u64) -> Amount {
171 Amount {
172 msat: 100_000_000_000 * btc,
173 }
174 }
175
176 pub fn msat(&self) -> u64 {
177 self.msat
178 }
179}
180
181impl std::ops::Add for Amount {
182 type Output = Amount;
183
184 fn add(self, rhs: Self) -> Self::Output {
185 Amount {
186 msat: self.msat + rhs.msat,
187 }
188 }
189}
190
191impl std::ops::Sub for Amount {
192 type Output = Amount;
193
194 fn sub(self, rhs: Self) -> Self::Output {
195 Amount {
196 msat: self.msat - rhs.msat,
197 }
198 }
199}
200
201#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
202pub struct ShortChannelId(u64);
203
204impl Serialize for ShortChannelId {
205 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
206 where
207 S: Serializer,
208 {
209 serializer.serialize_str(&self.to_string())
210 }
211}
212
213impl<'de> Deserialize<'de> for ShortChannelId {
214 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
215 where
216 D: Deserializer<'de>,
217 {
218 use serde::de::Error;
219 let s: String = Deserialize::deserialize(deserializer)?;
220 Ok(Self::from_str(&s).map_err(|e| Error::custom(e.to_string()))?)
221 }
222}
223
224impl FromStr for ShortChannelId {
225 type Err = crate::Error;
226 fn from_str(s: &str) -> Result<Self, Self::Err> {
227 let parts: Result<Vec<u64>, _> = s.split('x').map(|p| p.parse()).collect();
228 let parts = parts.with_context(|| format!("Malformed short_channel_id: {}", s))?;
229 if parts.len() != 3 {
230 return Err(anyhow!(
231 "Malformed short_channel_id: element count mismatch"
232 ));
233 }
234
235 Ok(ShortChannelId(
236 (parts[0] << 40) | (parts[1] << 16) | (parts[2] << 0),
237 ))
238 }
239}
240impl From<u64> for ShortChannelId {
241 fn from(scid: u64) -> Self {
242 ShortChannelId(scid)
243 }
244}
245impl Display for ShortChannelId {
246 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
247 write!(f, "{}x{}x{}", self.block(), self.txindex(), self.outnum())
248 }
249}
250impl ShortChannelId {
251 pub fn block(&self) -> u32 {
252 (self.0 >> 40) as u32 & 0xFFFFFF
253 }
254 pub fn txindex(&self) -> u32 {
255 (self.0 >> 16) as u32 & 0xFFFFFF
256 }
257 pub fn outnum(&self) -> u16 {
258 self.0 as u16 & 0xFFFF
259 }
260 pub fn to_u64(&self) -> u64 {
261 self.0
262 }
263}
264
265#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
266pub struct ShortChannelIdDir {
267 pub short_channel_id: ShortChannelId,
268 pub direction: u32,
269}
270impl Serialize for ShortChannelIdDir {
271 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
272 where
273 S: Serializer,
274 {
275 serializer.serialize_str(&self.to_string())
276 }
277}
278
279impl<'de> Deserialize<'de> for ShortChannelIdDir {
280 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
281 where
282 D: Deserializer<'de>,
283 {
284 use serde::de::Error;
285 let s: String = Deserialize::deserialize(deserializer)?;
286 Ok(Self::from_str(&s).map_err(|e| Error::custom(e.to_string()))?)
287 }
288}
289impl FromStr for ShortChannelIdDir {
290 type Err = crate::Error;
291 fn from_str(s: &str) -> Result<Self, Self::Err> {
292 let parts: Result<Vec<String>, _> = s.split('/').map(|p| p.parse()).collect();
293 let parts = parts.with_context(|| format!("Malformed short_channel_id_dir: {}", s))?;
294 if parts.len() != 2 {
295 return Err(anyhow!(
296 "Malformed short_channel_id_dir: element count mismatch"
297 ));
298 }
299
300 Ok(ShortChannelIdDir {
301 short_channel_id: ShortChannelId::from_str(&parts[0])?,
302 direction: parts[1].parse::<u32>()?,
303 })
304 }
305}
306impl Display for ShortChannelIdDir {
307 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
308 write!(
309 f,
310 "{}x{}x{}/{}",
311 self.short_channel_id.block(),
312 self.short_channel_id.txindex(),
313 self.short_channel_id.outnum(),
314 self.direction
315 )
316 }
317}
318
319#[derive(Clone, Copy, Debug)]
320pub struct Secret([u8; 32]);
321
322impl TryFrom<Vec<u8>> for Secret {
323 type Error = crate::Error;
324 fn try_from(v: Vec<u8>) -> Result<Self, crate::Error> {
325 if v.len() != 32 {
326 Err(anyhow!("Unexpected secret length: {}", hex::encode(v)))
327 } else {
328 Ok(Secret(v.try_into().unwrap()))
329 }
330 }
331}
332
333impl Serialize for Secret {
334 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
335 where
336 S: Serializer,
337 {
338 serializer.serialize_str(&hex::encode(&self.0))
339 }
340}
341
342impl<'de> Deserialize<'de> for Secret {
343 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
344 where
345 D: Deserializer<'de>,
346 {
347 use serde::de::Error;
348 let s: String = Deserialize::deserialize(deserializer)?;
349 let h = hex::decode(s).map_err(|_| Error::custom("not a valid hex string"))?;
350 Ok(Secret(h.try_into().map_err(|_| {
351 Error::custom("not a valid hex-encoded hash")
352 })?))
353 }
354}
355
356impl Secret {
357 pub fn to_vec(self) -> Vec<u8> {
358 self.0.to_vec()
359 }
360}
361
362impl From<Secret> for [u8; 32] {
363 fn from(s: Secret) -> [u8; 32] {
364 s.0
365 }
366}
367
368#[derive(Clone, Copy, Debug, PartialEq)]
369pub struct Outpoint {
370 pub txid: Sha256,
371 pub outnum: u32,
372}
373
374impl Serialize for Outpoint {
375 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
376 where
377 S: Serializer,
378 {
379 serializer.serialize_str(&format!("{}:{}", hex::encode(&self.txid), self.outnum))
380 }
381}
382
383impl<'de> Deserialize<'de> for Outpoint {
384 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
385 where
386 D: Deserializer<'de>,
387 {
388 use serde::de::Error;
389 let s: String = Deserialize::deserialize(deserializer)?;
390
391 let splits: Vec<&str> = s.split(':').collect();
392 if splits.len() != 2 {
393 return Err(Error::custom("not a valid txid:output tuple"));
394 }
395
396 let txid_bytes =
397 hex::decode(splits[0]).map_err(|_| Error::custom("not a valid hex encoded txid"))?;
398
399 let txid = Sha256::from_slice(&txid_bytes)
400 .map_err(|e| Error::custom(format!("Invalid TxId: {}", e)))?;
401
402 let outnum: u32 = splits[1]
403 .parse()
404 .map_err(|e| Error::custom(format!("{} is not a valid number: {}", s, e)))?;
405
406 Ok(Outpoint { txid, outnum })
407 }
408}
409
410#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
411#[serde(rename_all = "lowercase")]
412pub enum ChannelSide {
413 LOCAL,
414 REMOTE,
415}
416
417impl TryFrom<i32> for ChannelSide {
418 type Error = crate::Error;
419
420 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
421 match value {
422 0 => Ok(ChannelSide::LOCAL),
423 1 => Ok(ChannelSide::REMOTE),
424 _ => Err(anyhow!(
425 "Invalid ChannelSide mapping, only 0 or 1 are allowed"
426 )),
427 }
428 }
429}
430
431impl TryFrom<i32> for ChannelState {
432 type Error = crate::Error;
433
434 fn try_from(value: i32) -> std::result::Result<Self, Self::Error> {
435 match value {
436 0 => Ok(ChannelState::OPENINGD),
437 1 => Ok(ChannelState::CHANNELD_AWAITING_LOCKIN),
438 2 => Ok(ChannelState::CHANNELD_NORMAL),
439 3 => Ok(ChannelState::CHANNELD_SHUTTING_DOWN),
440 4 => Ok(ChannelState::CLOSINGD_SIGEXCHANGE),
441 5 => Ok(ChannelState::CLOSINGD_COMPLETE),
442 6 => Ok(ChannelState::AWAITING_UNILATERAL),
443 7 => Ok(ChannelState::FUNDING_SPEND_SEEN),
444 8 => Ok(ChannelState::ONCHAIN),
445 9 => Ok(ChannelState::DUALOPEND_OPEN_INIT),
446 10 => Ok(ChannelState::DUALOPEND_AWAITING_LOCKIN),
447 11 => Ok(ChannelState::CHANNELD_AWAITING_SPLICE),
448 12 => Ok(ChannelState::DUALOPEND_OPEN_COMMITTED),
449 13 => Ok(ChannelState::DUALOPEND_OPEN_COMMIT_READY),
450 _ => Err(anyhow!("Invalid channel state {}", value)),
451 }
452 }
453}
454
455impl From<i32> for ChannelTypeName {
456 fn from(value: i32) -> Self {
457 match value {
458 0 => ChannelTypeName::STATIC_REMOTEKEY_EVEN,
459 1 => ChannelTypeName::ANCHOR_OUTPUTS_EVEN,
460 2 => ChannelTypeName::ANCHORS_ZERO_FEE_HTLC_TX_EVEN,
461 3 => ChannelTypeName::SCID_ALIAS_EVEN,
462 4 => ChannelTypeName::ZEROCONF_EVEN,
463 5 => ChannelTypeName::ANCHORS_EVEN,
464 o => panic!("Unmapped ChannelTypeName {}", o),
465 }
466 }
467}
468
469impl From<ChannelTypeName> for i32 {
470 fn from(value: ChannelTypeName) -> Self {
471 match value {
472 ChannelTypeName::STATIC_REMOTEKEY_EVEN => 0,
473 ChannelTypeName::ANCHOR_OUTPUTS_EVEN => 1,
474 ChannelTypeName::ANCHORS_ZERO_FEE_HTLC_TX_EVEN => 2,
475 ChannelTypeName::SCID_ALIAS_EVEN => 3,
476 ChannelTypeName::ZEROCONF_EVEN => 4,
477 ChannelTypeName::ANCHORS_EVEN => 5,
478 }
479 }
480}
481
482impl From<i32> for HtlcState {
483 fn from(value: i32) -> Self {
484 match value {
485 0 => HtlcState::SENT_ADD_HTLC,
486 1 => HtlcState::SENT_ADD_COMMIT,
487 2 => HtlcState::RCVD_ADD_REVOCATION,
488 3 => HtlcState::RCVD_ADD_ACK_COMMIT,
489 4 => HtlcState::SENT_ADD_ACK_REVOCATION,
490 5 => HtlcState::RCVD_ADD_ACK_REVOCATION,
491 6 => HtlcState::RCVD_REMOVE_HTLC,
492 7 => HtlcState::RCVD_REMOVE_COMMIT,
493 8 => HtlcState::SENT_REMOVE_REVOCATION,
494 9 => HtlcState::SENT_REMOVE_ACK_COMMIT,
495 10 => HtlcState::RCVD_REMOVE_ACK_REVOCATION,
496 11 => HtlcState::RCVD_ADD_HTLC,
497 12 => HtlcState::RCVD_ADD_COMMIT,
498 13 => HtlcState::SENT_ADD_REVOCATION,
499 14 => HtlcState::SENT_ADD_ACK_COMMIT,
500 15 => HtlcState::SENT_REMOVE_HTLC,
501 16 => HtlcState::SENT_REMOVE_COMMIT,
502 17 => HtlcState::RCVD_REMOVE_REVOCATION,
503 18 => HtlcState::RCVD_REMOVE_ACK_COMMIT,
504 19 => HtlcState::SENT_REMOVE_ACK_REVOCATION,
505
506 n => panic!("Unmapped HtlcState variant: {}", n),
507 }
508 }
509}
510
511impl<'de> Deserialize<'de> for Amount {
512 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
513 where
514 D: Deserializer<'de>,
515 {
516 use serde::de::Error;
517
518 let any: serde_json::Value = Deserialize::deserialize(deserializer)?;
519
520 let ires: Option<u64> = any.as_u64();
525 let sres: Option<&str> = any.as_str();
527
528 match (ires, sres) {
529 (Some(i), _) => {
530 Ok(Amount::from_msat(i))
532 }
533 (_, Some(s)) => s
534 .try_into()
535 .map_err(|_e| Error::custom("could not parse amount")),
536 (None, _) => {
537 Err(Error::custom("could not parse amount"))
540 }
541 }
542 }
543}
544
545impl Serialize for Amount {
546 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
547 where
548 S: Serializer,
549 {
550 serializer.serialize_str(&format!("{}msat", self.msat))
551 }
552}
553
554impl Serialize for AmountOrAll {
555 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
556 where
557 S: Serializer,
558 {
559 match self {
560 AmountOrAll::Amount(a) => serializer.serialize_str(&format!("{}msat", a.msat)),
561 AmountOrAll::All => serializer.serialize_str("all"),
562 }
563 }
564}
565
566impl Serialize for AmountOrAny {
567 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
568 where
569 S: Serializer,
570 {
571 match self {
572 AmountOrAny::Amount(a) => serializer.serialize_str(&format!("{}msat", a.msat)),
573 AmountOrAny::Any => serializer.serialize_str("any"),
574 }
575 }
576}
577
578impl<'de> Deserialize<'de> for AmountOrAny {
579 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
580 where
581 D: Deserializer<'de>,
582 {
583 let s: String = Deserialize::deserialize(deserializer)?;
584 Ok(match s.to_lowercase().as_ref() {
585 "any" => AmountOrAny::Any,
586 v => AmountOrAny::Amount(
587 v.try_into()
588 .map_err(|_e| serde::de::Error::custom("could not parse amount"))?,
589 ),
590 })
591 }
592}
593
594impl<'de> Deserialize<'de> for AmountOrAll {
595 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
596 where
597 D: Deserializer<'de>,
598 {
599 let s: String = Deserialize::deserialize(deserializer)?;
600 Ok(match s.to_lowercase().as_ref() {
601 "all" => AmountOrAll::All,
602 v => AmountOrAll::Amount(
603 v.try_into()
604 .map_err(|_e| serde::de::Error::custom("could not parse amount"))?,
605 ),
606 })
607 }
608}
609
610impl TryFrom<&str> for Amount {
611 type Error = Error;
612 fn try_from(s: &str) -> Result<Amount> {
613 let number: u64 = s
614 .chars()
615 .map(|c| c.to_digit(10))
616 .take_while(|opt| opt.is_some())
617 .fold(0, |acc, digit| acc * 10 + (digit.unwrap() as u64));
618
619 let s = s.to_lowercase();
620 if s.ends_with("msat") {
621 Ok(Amount::from_msat(number))
622 } else if s.ends_with("sat") {
623 Ok(Amount::from_sat(number))
624 } else if s.ends_with("btc") {
625 Ok(Amount::from_btc(number))
626 } else {
627 Err(anyhow!("Unable to parse amount from string: {}", s))
628 }
629 }
630}
631
632impl From<Amount> for String {
633 fn from(a: Amount) -> String {
634 if a.msat % 1000 == 0 {
637 format!("{}sat", a.msat / 1000)
638 } else {
639 format!("{}msat", a.msat)
640 }
641 }
642}
643
644#[derive(Copy, Clone, Debug, PartialEq)]
645pub enum Feerate {
646 Slow,
647 Normal,
648 Urgent,
649 PerKb(u32),
650 PerKw(u32),
651}
652
653impl TryFrom<&str> for Feerate {
654 type Error = Error;
655 fn try_from(s: &str) -> Result<Feerate> {
656 let number: u32 = s
657 .chars()
658 .map(|c| c.to_digit(10))
659 .take_while(|opt| opt.is_some())
660 .fold(0, |acc, digit| acc * 10 + (digit.unwrap() as u32));
661
662 let s = s.to_lowercase();
663 if s.ends_with("perkw") {
664 Ok(Feerate::PerKw(number))
665 } else if s.ends_with("perkb") {
666 Ok(Feerate::PerKb(number))
667 } else if s == "slow" {
668 Ok(Feerate::Slow)
669 } else if s == "normal" {
670 Ok(Feerate::Normal)
671 } else if s == "urgent" {
672 Ok(Feerate::Urgent)
673 } else {
674 Err(anyhow!("Unable to parse feerate from string: {}", s))
675 }
676 }
677}
678
679impl From<&Feerate> for String {
680 fn from(f: &Feerate) -> String {
681 match f {
682 Feerate::Slow => "slow".to_string(),
683 Feerate::Normal => "normal".to_string(),
684 Feerate::Urgent => "urgent".to_string(),
685 Feerate::PerKb(v) => format!("{}perkb", v),
686 Feerate::PerKw(v) => format!("{}perkw", v),
687 }
688 }
689}
690
691impl<'de> Deserialize<'de> for Feerate {
692 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
693 where
694 D: Deserializer<'de>,
695 {
696 let s: String = Deserialize::deserialize(deserializer)?;
697 let res: Feerate = s
698 .as_str()
699 .try_into()
700 .map_err(|e| serde::de::Error::custom(format!("{}", e)))?;
701 Ok(res)
702 }
703}
704
705impl Serialize for Feerate {
706 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
707 where
708 S: Serializer,
709 {
710 let s: String = self.into();
711 serializer.serialize_str(&s)
712 }
713}
714
715#[cfg(test)]
716mod test {
717 use crate::model::responses::FundchannelResponse;
718
719 use super::*;
720
721 #[test]
722 fn test_amount_serde() {
723 #[derive(Serialize, PartialEq, Debug, Deserialize)]
724 struct T {
725 amount: Amount,
726 }
727
728 let tests = vec![
729 ("{\"amount\": \"10msat\"}", Amount { msat: 10 }, "10msat"),
730 ("{\"amount\": \"42sat\"}", Amount { msat: 42_000 }, "42sat"),
731 (
732 "{\"amount\": \"31337btc\"}",
733 Amount {
734 msat: 3_133_700_000_000_000,
735 },
736 "3133700000000sat",
737 ),
738 ];
739
740 for (req, res, s) in tests.into_iter() {
741 println!("{:?} {:?}", req, res);
742 let parsed: T = serde_json::from_str(req).unwrap();
743 assert_eq!(res, parsed.amount);
744
745 let serialized: String = parsed.amount.into();
746 assert_eq!(s, serialized);
747 }
748 }
749
750 #[test]
751 fn test_amount_all_any() {
752 let t = r#"{"any": "any", "all": "all", "not_any": "42msat", "not_all": "31337msat"}"#;
753
754 #[derive(Serialize, Deserialize, Debug, PartialEq)]
755 struct T {
756 all: AmountOrAll,
757 not_all: AmountOrAll,
758 any: AmountOrAny,
759 not_any: AmountOrAny,
760 }
761
762 let parsed: T = serde_json::from_str(t).unwrap();
763
764 let expected = T {
765 all: AmountOrAll::All,
766 any: AmountOrAny::Any,
767 not_all: AmountOrAll::Amount(Amount { msat: 31337 }),
768 not_any: AmountOrAny::Amount(Amount { msat: 42 }),
769 };
770 assert_eq!(expected, parsed);
771
772 let serialized: String = serde_json::to_string(&parsed).unwrap();
773 assert_eq!(
774 serialized,
775 r#"{"all":"all","not_all":"31337msat","any":"any","not_any":"42msat"}"#
776 );
777 }
778
779 #[test]
780 fn test_parse_feerate() {
781 let tests = vec![
782 ("slow", Feerate::Slow),
783 ("normal", Feerate::Normal),
784 ("urgent", Feerate::Urgent),
785 ("12345perkb", Feerate::PerKb(12345)),
786 ("54321perkw", Feerate::PerKw(54321)),
787 ];
788
789 for (input, output) in tests.into_iter() {
790 let parsed: Feerate = input.try_into().unwrap();
791 assert_eq!(parsed, output);
792 let serialized: String = (&parsed).into();
793 assert_eq!(serialized, input);
794 }
795 }
796
797 #[test]
798 fn test_parse_output_desc() {
799 let a = r#"{"address":"1234msat"}"#;
800 let od = serde_json::from_str(a).unwrap();
801
802 assert_eq!(
803 OutputDesc {
804 address: "address".to_string(),
805 amount: Amount { msat: 1234 }
806 },
807 od
808 );
809 let serialized: String = serde_json::to_string(&od).unwrap();
810 assert_eq!(a, serialized);
811 }
812
813 #[test]
814 fn tlvstream() {
815 let stream = TlvStream {
816 entries: vec![
817 TlvEntry {
818 typ: 31337,
819 value: vec![1, 2, 3, 4, 5],
820 },
821 TlvEntry {
822 typ: 42,
823 value: vec![],
824 },
825 ],
826 };
827
828 let res = serde_json::to_string(&stream).unwrap();
829 assert_eq!(res, "{\"31337\":\"0102030405\",\"42\":\"\"}");
830 }
831
832 #[test]
833 fn test_fundchannel() {
834 let r = serde_json::json!({
835 "tx": "0000000000000000000000000000000000000000000000000000000000000000",
836 "txid": "0000000000000000000000000000000000000000000000000000000000000000",
837 "outnum": 0,
838 "channel_id": "0000000000000000000000000000000000000000000000000000000000000000",
839 "channel_type": {
840 "bits": [1, 3, 5],
841 "names": [
842 "static_remotekey/even",
843 "anchor_outputs/even",
844 "anchors_zero_fee_htlc_tx/even",
845 "scid_alias/even",
846 "zeroconf/even"
847 ]
848 },
849 "close_to": "bc1qd23gerv2mn0qdecrmulsjsmkv8lz6t6m0770tg",
850 "mindepth": 1,
851 });
852
853 let p: FundchannelResponse = serde_json::from_value(r).unwrap();
854 assert_eq!(p.channel_type.unwrap().bits, vec![1, 3, 5]);
855 }
856}
857
858#[derive(Clone, Debug, PartialEq)]
859pub struct OutputDesc {
860 pub address: String,
861 pub amount: Amount,
862}
863
864impl<'de> Deserialize<'de> for OutputDesc {
865 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
866 where
867 D: Deserializer<'de>,
868 {
869 let map: std::collections::HashMap<String, Amount> =
870 Deserialize::deserialize(deserializer)?;
871
872 let (address, amount) = map.iter().next().unwrap();
873
874 Ok(OutputDesc {
875 address: address.to_string(),
876 amount: *amount,
877 })
878 }
879}
880
881impl Serialize for OutputDesc {
882 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
883 where
884 S: Serializer,
885 {
886 use serde::ser::SerializeMap;
887 let mut map = serializer.serialize_map(Some(1))?;
888 map.serialize_key(&self.address)?;
889 map.serialize_value(&self.amount)?;
890 map.end()
891 }
892}
893
894#[derive(Clone, Debug, Serialize, Deserialize)]
895pub struct Routehop {
896 pub id: PublicKey,
897 pub scid: ShortChannelId,
898 pub feebase: Amount,
899 pub feeprop: u32,
900 pub expirydelta: u16,
901}
902
903#[derive(Clone, Debug)]
904pub struct Routehint {
905 pub hops: Vec<Routehop>,
906}
907
908#[derive(Clone, Debug)]
909pub struct RoutehintList {
910 pub hints: Vec<Routehint>,
911}
912
913use serde::ser::SerializeSeq;
914
915impl Serialize for Routehint {
916 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
917 where
918 S: Serializer,
919 {
920 let mut seq = serializer.serialize_seq(Some(self.hops.len()))?;
921 for e in self.hops.iter() {
922 seq.serialize_element(e)?;
923 }
924 seq.end()
925 }
926}
927
928impl Serialize for RoutehintList {
929 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
930 where
931 S: Serializer,
932 {
933 let mut seq = serializer.serialize_seq(Some(self.hints.len()))?;
934 for e in self.hints.iter() {
935 seq.serialize_element(e)?;
936 }
937 seq.end()
938 }
939}
940
941impl<'de> Deserialize<'de> for RoutehintList {
942 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
943 where
944 D: Deserializer<'de>,
945 {
946 let hints: Vec<Routehint> = Vec::deserialize(deserializer)?;
947
948 Ok(RoutehintList { hints })
949 }
950}
951
952impl<'de> Deserialize<'de> for Routehint {
953 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
954 where
955 D: Deserializer<'de>,
956 {
957 let hops: Vec<Routehop> = Vec::deserialize(deserializer)?;
958
959 Ok(Routehint { hops })
960 }
961}
962
963#[derive(Clone, Debug, Serialize, Deserialize)]
964pub struct DecodeRoutehop {
965 pub pubkey: PublicKey,
966 pub short_channel_id: ShortChannelId,
967 pub fee_base_msat: Amount,
968 pub fee_proportional_millionths: u32,
969 pub cltv_expiry_delta: u16,
970}
971
972#[derive(Clone, Debug)]
973pub struct DecodeRoutehint {
974 pub hops: Vec<DecodeRoutehop>,
975}
976
977#[derive(Clone, Debug)]
978pub struct DecodeRoutehintList {
979 pub hints: Vec<DecodeRoutehint>,
980}
981
982impl Serialize for DecodeRoutehint {
983 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
984 where
985 S: Serializer,
986 {
987 let mut seq = serializer.serialize_seq(Some(self.hops.len()))?;
988 for e in self.hops.iter() {
989 seq.serialize_element(e)?;
990 }
991 seq.end()
992 }
993}
994
995impl Serialize for DecodeRoutehintList {
996 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
997 where
998 S: Serializer,
999 {
1000 let mut seq = serializer.serialize_seq(Some(self.hints.len()))?;
1001 for e in self.hints.iter() {
1002 seq.serialize_element(e)?;
1003 }
1004 seq.end()
1005 }
1006}
1007
1008impl<'de> Deserialize<'de> for DecodeRoutehintList {
1009 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1010 where
1011 D: Deserializer<'de>,
1012 {
1013 let hints: Vec<DecodeRoutehint> = Vec::deserialize(deserializer)?;
1014
1015 Ok(DecodeRoutehintList { hints })
1016 }
1017}
1018
1019impl<'de> Deserialize<'de> for DecodeRoutehint {
1020 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1021 where
1022 D: Deserializer<'de>,
1023 {
1024 let hops: Vec<DecodeRoutehop> = Vec::deserialize(deserializer)?;
1025
1026 Ok(DecodeRoutehint { hops })
1027 }
1028}
1029
1030#[derive(Clone, Serialize, Deserialize, Debug)]
1033pub struct RpcError {
1034 pub code: Option<i32>,
1035 pub message: String,
1036 pub data: Option<Value>,
1037}
1038
1039impl Display for RpcError {
1040 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1041 if let Some(code) = self.code {
1042 write!(f, "Error code {}: {}", code, self.message)
1043 } else {
1044 write!(f, "Error: {}", self.message)
1045 }
1046 }
1047}
1048
1049impl std::error::Error for RpcError {}
1050
1051#[derive(Clone, Debug)]
1052pub struct TlvEntry {
1053 pub typ: u64,
1054 pub value: Vec<u8>,
1055}
1056
1057#[derive(Clone, Debug)]
1058pub struct TlvStream {
1059 pub entries: Vec<TlvEntry>,
1060}
1061
1062impl<'de> Deserialize<'de> for TlvStream {
1063 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1064 where
1065 D: Deserializer<'de>,
1066 {
1067 let map: std::collections::HashMap<u64, String> = Deserialize::deserialize(deserializer)?;
1068
1069 let entries = map
1070 .iter()
1071 .map(|(k, v)| TlvEntry {
1072 typ: *k,
1073 value: hex::decode(v).unwrap(),
1074 })
1075 .collect();
1076
1077 Ok(TlvStream { entries })
1078 }
1079}
1080
1081impl Serialize for TlvStream {
1082 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1083 where
1084 S: Serializer,
1085 {
1086 use serde::ser::SerializeMap;
1087
1088 let mut map = serializer.serialize_map(Some(self.entries.len()))?;
1089 for e in &self.entries {
1090 map.serialize_key(&e.typ)?;
1091 map.serialize_value(&hex::encode(&e.value))?;
1092 }
1093 map.end()
1094 }
1095}