1use 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#[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#[derive(Debug, Copy, Clone, PartialEq)]
158pub enum AmountOrAny {
159 Amount(Amount),
160 Any,
161}
162
163#[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 let ires: Option<u64> = any.as_u64();
605 let sres: Option<&str> = any.as_str();
607
608 match (ires, sres) {
609 (Some(i), _) => {
610 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 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 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#[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}