Skip to main content

cln_rpc/
primitives.rs

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