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, 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/// An `Amount` that can also be `any`. Useful for cases in which you
140/// want to delegate the Amount selection so someone else, e.g., an
141/// amountless invoice.
142#[derive(Debug, Copy, Clone, PartialEq)]
143pub enum AmountOrAny {
144    Amount(Amount),
145    Any,
146}
147
148/// An amount that can also be `all`. Useful for cases where you want
149/// to delegate the amount computation to the cln node.
150#[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        // Amount fields used to be a string with the unit "msat" or
521        // "sat" as a suffix. The great consolidation in PR #5306
522        // changed that to always be a `u64`, but for backwards
523        // compatibility we need to handle both cases.
524        let ires: Option<u64> = any.as_u64();
525        // TODO(cdecker): Remove string parsing support once the great msat purge is complete
526        let sres: Option<&str> = any.as_str();
527
528        match (ires, sres) {
529            (Some(i), _) => {
530                // Notice that this assumes the field is denominated in `msat`
531                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                // We reuse the integer parsing error as that's the
538                // default after the great msat purge of 2022.
539                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        // Best effort msat to sat conversion, for methods that accept
635        // sats but not msats
636        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/// An error returned by the lightningd RPC consisting of a code and a
1031/// message
1032#[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}