cln_grpc/
pb.rs

1tonic::include_proto!("cln");
2
3#[cfg(feature = "server")]
4pub use cln_rpc::primitives::Sha256;
5#[cfg(feature = "server")]
6mod convert {
7    use super::*;
8    use bitcoin::hashes::Hash;
9    use std::str::FromStr;
10
11    use cln_rpc::primitives::{
12        Amount as JAmount, AmountOrAll as JAmountOrAll, AmountOrAny as JAmountOrAny,
13        Feerate as JFeerate, Outpoint as JOutpoint, OutputDesc as JOutputDesc,
14    };
15
16    impl From<JAmount> for Amount {
17        fn from(a: JAmount) -> Self {
18            Amount { msat: a.msat() }
19        }
20    }
21
22    impl From<Amount> for JAmount {
23        fn from(a: Amount) -> Self {
24            JAmount::from_msat(a.msat)
25        }
26    }
27
28    impl From<JOutpoint> for Outpoint {
29        fn from(a: JOutpoint) -> Self {
30            Outpoint {
31                txid: <Sha256 as AsRef<[u8]>>::as_ref(&a.txid).to_vec(),
32                outnum: a.outnum,
33            }
34        }
35    }
36
37    impl From<Outpoint> for JOutpoint {
38        fn from(a: Outpoint) -> Self {
39            JOutpoint {
40                txid: bitcoin::hashes::sha256::Hash::from_slice(&a.txid).unwrap(),
41                outnum: a.outnum,
42            }
43        }
44    }
45
46    impl From<Feerate> for cln_rpc::primitives::Feerate {
47        fn from(f: Feerate) -> cln_rpc::primitives::Feerate {
48            use feerate::Style;
49            match f.style.unwrap() {
50                Style::Slow(_) => JFeerate::Slow,
51                Style::Normal(_) => JFeerate::Normal,
52                Style::Urgent(_) => JFeerate::Urgent,
53                Style::Perkw(i) => JFeerate::PerKw(i),
54                Style::Perkb(i) => JFeerate::PerKb(i),
55            }
56        }
57    }
58
59    impl From<cln_rpc::primitives::Feerate> for Feerate {
60        fn from(f: cln_rpc::primitives::Feerate) -> Feerate {
61            use feerate::Style;
62            let style = Some(match f {
63                JFeerate::Slow => Style::Slow(true),
64                JFeerate::Normal => Style::Normal(true),
65                JFeerate::Urgent => Style::Urgent(true),
66                JFeerate::PerKb(i) => Style::Perkb(i),
67                JFeerate::PerKw(i) => Style::Perkw(i),
68            });
69            Self { style }
70        }
71    }
72
73    impl From<OutputDesc> for JOutputDesc {
74        fn from(od: OutputDesc) -> JOutputDesc {
75            JOutputDesc {
76                address: od.address,
77                amount: od.amount.unwrap().into(),
78            }
79        }
80    }
81
82    impl From<JOutputDesc> for OutputDesc {
83        fn from(od: JOutputDesc) -> Self {
84            Self {
85                address: od.address,
86                amount: Some(od.amount.into()),
87            }
88        }
89    }
90
91    impl From<JAmountOrAll> for AmountOrAll {
92        fn from(a: JAmountOrAll) -> Self {
93            match a {
94                JAmountOrAll::Amount(a) => AmountOrAll {
95                    value: Some(amount_or_all::Value::Amount(a.into())),
96                },
97                JAmountOrAll::All => AmountOrAll {
98                    value: Some(amount_or_all::Value::All(true)),
99                },
100            }
101        }
102    }
103
104    impl From<AmountOrAll> for JAmountOrAll {
105        fn from(a: AmountOrAll) -> Self {
106            match a.value {
107                Some(amount_or_all::Value::Amount(a)) => JAmountOrAll::Amount(a.into()),
108                Some(amount_or_all::Value::All(_)) => JAmountOrAll::All,
109                None => panic!("AmountOrAll is neither amount nor all: {:?}", a),
110            }
111        }
112    }
113
114    impl From<JAmountOrAny> for AmountOrAny {
115        fn from(a: JAmountOrAny) -> Self {
116            match a {
117                JAmountOrAny::Amount(a) => AmountOrAny {
118                    value: Some(amount_or_any::Value::Amount(a.into())),
119                },
120                JAmountOrAny::Any => AmountOrAny {
121                    value: Some(amount_or_any::Value::Any(true)),
122                },
123            }
124        }
125    }
126    impl From<AmountOrAny> for JAmountOrAny {
127        fn from(a: AmountOrAny) -> Self {
128            match a.value {
129                Some(amount_or_any::Value::Amount(a)) => JAmountOrAny::Amount(a.into()),
130                Some(amount_or_any::Value::Any(_)) => JAmountOrAny::Any,
131                None => panic!("AmountOrAll is neither amount nor any: {:?}", a),
132            }
133        }
134    }
135    impl From<RouteHop> for cln_rpc::primitives::Routehop {
136        fn from(c: RouteHop) -> Self {
137            Self {
138                id: cln_rpc::primitives::PublicKey::from_slice(&c.id).unwrap(),
139                scid: cln_rpc::primitives::ShortChannelId::from_str(&c.scid).unwrap(),
140                feebase: c.feebase.unwrap().into(),
141                feeprop: c.feeprop,
142                expirydelta: c.expirydelta as u16,
143            }
144        }
145    }
146
147    impl From<Routehint> for cln_rpc::primitives::Routehint {
148        fn from(c: Routehint) -> Self {
149            Self {
150                hops: c.hops.into_iter().map(|h| h.into()).collect(),
151            }
152        }
153    }
154
155    impl From<RoutehintList> for cln_rpc::primitives::RoutehintList {
156        fn from(c: RoutehintList) -> Self {
157            Self {
158                hints: c.hints.into_iter().map(|h| h.into()).collect(),
159            }
160        }
161    }
162
163    impl From<cln_rpc::primitives::Routehop> for RouteHop {
164        fn from(c: cln_rpc::primitives::Routehop) -> Self {
165            Self {
166                id: c.id.serialize().to_vec(),
167                feebase: Some(c.feebase.into()),
168                feeprop: c.feeprop,
169                expirydelta: c.expirydelta as u32,
170                scid: c.scid.to_string(),
171            }
172        }
173    }
174
175    impl From<cln_rpc::primitives::Routehint> for Routehint {
176        fn from(c: cln_rpc::primitives::Routehint) -> Self {
177            Self {
178                hops: c.hops.into_iter().map(|h| h.into()).collect(),
179            }
180        }
181    }
182
183    impl From<cln_rpc::primitives::RoutehintList> for RoutehintList {
184        fn from(c: cln_rpc::primitives::RoutehintList) -> Self {
185            Self {
186                hints: c.hints.into_iter().map(|e| e.into()).collect(),
187            }
188        }
189    }
190
191    impl From<DecodeRouteHop> for cln_rpc::primitives::DecodeRoutehop {
192        fn from(c: DecodeRouteHop) -> Self {
193            Self {
194                pubkey: cln_rpc::primitives::PublicKey::from_slice(&c.pubkey).unwrap(),
195                short_channel_id: cln_rpc::primitives::ShortChannelId::from_str(
196                    &c.short_channel_id,
197                )
198                .unwrap(),
199                fee_base_msat: c.fee_base_msat.unwrap().into(),
200                fee_proportional_millionths: c.fee_proportional_millionths,
201                cltv_expiry_delta: c.cltv_expiry_delta as u16,
202            }
203        }
204    }
205
206    impl From<DecodeRoutehint> for cln_rpc::primitives::DecodeRoutehint {
207        fn from(c: DecodeRoutehint) -> Self {
208            Self {
209                hops: c.hops.into_iter().map(|h| h.into()).collect(),
210            }
211        }
212    }
213
214    impl From<DecodeRoutehintList> for cln_rpc::primitives::DecodeRoutehintList {
215        fn from(c: DecodeRoutehintList) -> Self {
216            Self {
217                hints: c.hints.into_iter().map(|h| h.into()).collect(),
218            }
219        }
220    }
221
222    impl From<cln_rpc::primitives::DecodeRoutehop> for DecodeRouteHop {
223        fn from(c: cln_rpc::primitives::DecodeRoutehop) -> Self {
224            Self {
225                pubkey: c.pubkey.serialize().to_vec(),
226                fee_base_msat: Some(c.fee_base_msat.into()),
227                fee_proportional_millionths: c.fee_proportional_millionths,
228                cltv_expiry_delta: c.cltv_expiry_delta as u32,
229                short_channel_id: c.short_channel_id.to_string(),
230            }
231        }
232    }
233
234    impl From<cln_rpc::primitives::DecodeRoutehint> for DecodeRoutehint {
235        fn from(c: cln_rpc::primitives::DecodeRoutehint) -> Self {
236            Self {
237                hops: c.hops.into_iter().map(|h| h.into()).collect(),
238            }
239        }
240    }
241
242    impl From<cln_rpc::primitives::DecodeRoutehintList> for DecodeRoutehintList {
243        fn from(c: cln_rpc::primitives::DecodeRoutehintList) -> Self {
244            Self {
245                hints: c.hints.into_iter().map(|e| e.into()).collect(),
246            }
247        }
248    }
249
250    impl From<TlvStream> for cln_rpc::primitives::TlvStream {
251        fn from(s: TlvStream) -> Self {
252            Self {
253                entries: s.entries.into_iter().map(|e| e.into()).collect(),
254            }
255        }
256    }
257
258    impl From<TlvEntry> for cln_rpc::primitives::TlvEntry {
259        fn from(e: TlvEntry) -> Self {
260            Self {
261                typ: e.r#type,
262                value: e.value,
263            }
264        }
265    }
266
267    impl From<cln_rpc::primitives::TlvStream> for TlvStream {
268        fn from(s: cln_rpc::primitives::TlvStream) -> Self {
269            Self {
270                entries: s.entries.into_iter().map(|e| e.into()).collect(),
271            }
272        }
273    }
274
275    impl From<cln_rpc::primitives::TlvEntry> for TlvEntry {
276        fn from(e: cln_rpc::primitives::TlvEntry) -> Self {
277            Self {
278                r#type: e.typ,
279                value: e.value,
280            }
281        }
282    }
283
284    #[cfg(test)]
285    mod test {
286        use super::*;
287        use serde_json::json;
288
289        #[test]
290        fn test_listpeers() {
291            let j: serde_json::Value = json!({
292              "peers": [
293                {
294                  "id": "0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518",
295                  "connected": true,
296                  "netaddr": [
297                    "127.0.0.1:39152"
298                  ],
299                  "features": "8808226aa2",
300                  "num_channels": 0,
301                  "channels": [
302                    {
303                      "state": "CHANNELD_NORMAL",
304                      "scratch_txid": "fd4659658d235c20c81f96f7bc867c17abbfd20fcdd46c27eaad74ea52eaee90",
305                      "last_tx_fee_msat": "14257000msat",
306                      "feerate": {
307                        "perkw": 11000,
308                        "perkb": 44000
309                      },
310                      "owner": "channeld",
311                      "short_channel_id": "103x2x1",
312                      "direction": 0,
313                      "channel_id": "44b77a6d66ca54f0c365c84b13a95fbde462415a0549228baa25ee1bb1dfef66",
314                      "funding_txid": "67efdfb11bee25aa8b2249055a4162e4bd5fa9134bc865c3f054ca666d7ab744",
315                      "funding_outnum": 1,
316                      "close_to_addr": "bcrt1q9tc6q49l6wrrtp8ul45rj92hsleehwwxty32zu",
317                      "close_to": "00142af1a054bfd3863584fcfd6839155787f39bb9c6",
318                      "private": false,
319                      "opener": "remote",
320                      "features": [
321                        "option_static_remotekey",
322                        "option_anchor_outputs"
323                      ],
324                      "funding": {
325                        "local_msat": "0msat",
326                        "remote_msat": "1000000000msat",
327                        "pushed_msat": "0msat",
328                        "local_funds_msat": "0msat",
329                        "remote_funds_msat": "0msat"
330                      },
331                      "msatoshi_to_us": 0,
332                      "to_us_msat": "0msat",
333                      "msatoshi_to_us_min": 0,
334                      "min_to_us_msat": "0msat",
335                      "msatoshi_to_us_max": 0,
336                      "max_to_us_msat": "0msat",
337                      "msatoshi_total": 1000000000,
338                      "total_msat": "1000000000msat",
339                      "fee_base_msat": "1msat",
340                      "fee_proportional_millionths": 10,
341                      "dust_limit_satoshis": 546,
342                      "dust_limit_msat": "546000msat",
343                      "max_total_htlc_in_msat": "18446744073709551615msat",
344                      "their_channel_reserve_satoshis": 10000,
345                      "their_reserve_msat": "10000000msat",
346                      "our_channel_reserve_satoshis": 10000,
347                      "our_reserve_msat": "10000000msat",
348                      "spendable_msatoshi": 0,
349                      "spendable_msat": "0msat",
350                      "receivable_msatoshi": 853257998,
351                      "receivable_msat": "853257998msat",
352                      "htlc_minimum_msat": 0,
353                      "minimum_htlc_in_msat": "0msat",
354                      "their_to_self_delay": 5,
355                      "our_to_self_delay": 5,
356                      "max_accepted_htlcs": 483,
357                      "state_changes": [
358                        {
359                          "timestamp": "2022-03-25T13:57:33.322Z",
360                          "old_state": "CHANNELD_AWAITING_LOCKIN",
361                          "new_state": "CHANNELD_NORMAL",
362                          "cause": "remote",
363                          "message": "Lockin complete"
364                        }
365                      ],
366                      "status": [
367                        "CHANNELD_NORMAL:Funding transaction locked. Channel announced."
368                      ],
369                      "in_payments_offered": 1,
370                      "in_msatoshi_offered": 100002002,
371                      "in_offered_msat": "100002002msat",
372                      "in_payments_fulfilled": 0,
373                      "in_msatoshi_fulfilled": 0,
374                      "in_fulfilled_msat": "0msat",
375                      "out_payments_offered": 0,
376                      "out_msatoshi_offered": 0,
377                      "out_offered_msat": "0msat",
378                      "out_payments_fulfilled": 0,
379                      "out_msatoshi_fulfilled": 0,
380                      "out_fulfilled_msat": "0msat",
381                      "htlcs": [
382                        {
383                          "direction": "in",
384                          "id": 0,
385                          "msatoshi": 100002002,
386                          "amount_msat": "100002002msat",
387                          "expiry": 131,
388                          "payment_hash": "d17a42c4f7f49648064a0ce7ce848bd92c4c50f24d35fe5c3d1f3a7a9bf474b2",
389                          "state": "RCVD_ADD_ACK_REVOCATION"
390                        }
391                      ]
392                    }
393                  ]
394                },
395                {
396                  "id": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d",
397                  "connected": true,
398                  "netaddr": [
399                    "127.0.0.1:38321"
400                  ],
401                  "features": "8808226aa2",
402                  "num_channels": 0,
403                  "channels": [
404                    {
405                      "state": "CHANNELD_NORMAL",
406                      "scratch_txid": "30530d3f522862773100b7600d8ea8921a5ee84df17a2317326f9aa2c4829326",
407                      "last_tx_fee_msat": "16149000msat",
408                      "feerate": {
409                        "perkw": 11000,
410                        "perkb": 44000
411                      },
412                      "owner": "channeld",
413                      "short_channel_id": "103x1x0",
414                      "direction": 0,
415                      "channel_id": "006a2044fc72fa5c4a54c9fddbf208970a7b3b4fd2aaa70a96abba757c01769e",
416                      "funding_txid": "9e76017c75baab960aa7aad24f3b7b0a9708f2dbfdc9544a5cfa72fc44206a00",
417                      "funding_outnum": 0,
418                      "close_to_addr": "bcrt1qhfmyce4ujce2pyugew2435tlwft6p6w4s3py6d",
419                      "close_to": "0014ba764c66bc9632a09388cb9558d17f7257a0e9d5",
420                      "private": false,
421                      "opener": "local",
422                      "features": [
423                        "option_static_remotekey",
424                        "option_anchor_outputs"
425                      ],
426                      "funding": {
427                        "local_msat": "1000000000msat",
428                        "remote_msat": "0msat",
429                        "pushed_msat": "0msat",
430                        "local_funds_msat": "0msat",
431                        "remote_funds_msat": "0msat"
432                      },
433                      "msatoshi_to_us": 1000000000,
434                      "to_us_msat": "1000000000msat",
435                      "msatoshi_to_us_min": 1000000000,
436                      "min_to_us_msat": "1000000000msat",
437                      "msatoshi_to_us_max": 1000000000,
438                      "max_to_us_msat": "1000000000msat",
439                      "msatoshi_total": 1000000000,
440                      "total_msat": "1000000000msat",
441                      "fee_base_msat": "1msat",
442                      "fee_proportional_millionths": 10,
443                      "dust_limit_satoshis": 546,
444                      "dust_limit_msat": "546000msat",
445                      "max_total_htlc_in_msat": "18446744073709551615msat",
446                      "their_channel_reserve_satoshis": 10000,
447                      "their_reserve_msat": "10000000msat",
448                      "our_channel_reserve_satoshis": 10000,
449                      "our_reserve_msat": "10000000msat",
450                      "spendable_msatoshi": 749473998,
451                      "spendable_msat": "749473998msat",
452                      "receivable_msatoshi": 0,
453                      "receivable_msat": "0msat",
454                      "htlc_minimum_msat": 0,
455                      "minimum_htlc_in_msat": "0msat",
456                      "their_to_self_delay": 5,
457                      "our_to_self_delay": 5,
458                      "max_accepted_htlcs": 483,
459                      "state_changes": [
460                        {
461                          "timestamp": "2022-03-25T13:57:33.325Z",
462                          "old_state": "CHANNELD_AWAITING_LOCKIN",
463                          "new_state": "CHANNELD_NORMAL",
464                          "cause": "user",
465                          "message": "Lockin complete"
466                        }
467                      ],
468                      "status": [
469                        "CHANNELD_NORMAL:Funding transaction locked. Channel announced."
470                      ],
471                      "in_payments_offered": 0,
472                      "in_msatoshi_offered": 0,
473                      "in_offered_msat": "0msat",
474                      "in_payments_fulfilled": 0,
475                      "in_msatoshi_fulfilled": 0,
476                      "in_fulfilled_msat": "0msat",
477                      "out_payments_offered": 2,
478                      "out_msatoshi_offered": 200002002,
479                      "out_offered_msat": "200002002msat",
480                      "out_payments_fulfilled": 0,
481                      "out_msatoshi_fulfilled": 0,
482                      "out_fulfilled_msat": "0msat",
483                      "htlcs": [
484                        {
485                          "direction": "out",
486                          "id": 1,
487                          "msatoshi": 100001001,
488                          "amount_msat": "100001001msat",
489                          "expiry": 125,
490                          "payment_hash": "d17a42c4f7f49648064a0ce7ce848bd92c4c50f24d35fe5c3d1f3a7a9bf474b2",
491                          "state": "SENT_ADD_ACK_REVOCATION"
492                        },
493                        {
494                          "direction": "out",
495                          "id": 0,
496                          "msatoshi": 100001001,
497                          "amount_msat": "100001001msat",
498                          "expiry": 124,
499                          "payment_hash": "d17a42c4f7f49648064a0ce7ce848bd92c4c50f24d35fe5c3d1f3a7a9bf474b2",
500                          "state": "SENT_ADD_ACK_REVOCATION"
501                        }
502                      ]
503                    }
504                  ]
505                }
506              ]
507            });
508            let u: cln_rpc::model::responses::ListpeersResponse =
509                serde_json::from_value(j).unwrap();
510            let _g: ListpeersResponse = u.into();
511        }
512    }
513}