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