cln_rpc/
primitives.rs

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