Skip to content

Commit 3a6f562

Browse files
committed
Add partial CLN support with potential for others in the future
1 parent 4d75887 commit 3a6f562

File tree

10 files changed

+959
-415
lines changed

10 files changed

+959
-415
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ axum-extra = { version = "0.9.3", features = ["cookie"] }
3434
axum_typed_multipart = "0.11.0"
3535
tempfile = "3.10.1"
3636
tower-http = { version = "0.5.2", features = ["fs", "cors"] }
37+
async-trait = "0.1.81"
3738

3839
[build-dependencies]
3940
configure_me_codegen = "0.4.1"

cln-rs/src/lib.rs

Lines changed: 1 addition & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1 @@
1-
pub mod cln;
2-
3-
// use cln::node_client;
4-
// use cln::{listinvoices_invoices::ListinvoicesInvoicesStatus, node_client::NodeClient};
5-
// use cln::{GetinfoRequest, InvoiceRequest, PayRequest};
6-
7-
// use tonic::transport::{Certificate, Channel, ClientTlsConfig, Endpoint, Identity};
8-
9-
// use std::fs;
10-
// use std::error::Error;
11-
12-
// pub struct CLNClient {
13-
// url: String,
14-
// client: NodeClient<Channel>,
15-
// }
16-
17-
// impl CLNClient {
18-
19-
// pub async fn connect(url: String, cert_path: String, key_path: String, cacert_path: String) -> Result<CLNClient, Box<dyn Error>> {
20-
21-
// let cert_text: Vec<u8> = fs::read(cert_path.clone())?;
22-
// let key_text: Vec<u8> = fs::read(key_path.clone())?;
23-
// let cacert_text: Vec<u8> = fs::read(cacert_path.clone())?;
24-
25-
// let ca_certificate = Certificate::from_pem(&cacert_text);
26-
// let client_identity = Identity::from_pem(&cert_text, &key_text);
27-
28-
29-
// let tls = ClientTlsConfig::new()
30-
// .ca_certificate(ca_certificate)
31-
// .domain_name("example.com");
32-
33-
// let channel = Channel::from_static("https://[::1]:50051")
34-
// .tls_config(tls)?
35-
// .connect()
36-
// .await?;
37-
38-
// let client = NodeClient::new(channel);
39-
40-
// // let tls_config = ClientTlsConfig::new()
41-
// // .domain_name("localhost")
42-
// // .ca_certificate(ca_certificate)
43-
// // .identity(client_identity);
44-
45-
// // let channel = Channel::from_shared(url)?
46-
// // .tls_config(tls_config)?
47-
// // .connect()
48-
// // .await?;
49-
50-
// // let client = NodeClient::new(channel);
51-
52-
// Ok(CLNClient {
53-
// url,
54-
// client
55-
// })
56-
// }
57-
// }
58-
59-
60-
// // pub fn add(left: usize, right: usize) -> usize {
61-
// // left + right
62-
// // }
63-
64-
// // #[cfg(test)]
65-
// // mod tests {
66-
// // use super::*;
67-
68-
// // #[test]
69-
// // fn it_works() {
70-
// // let result = add(2, 2);
71-
// // assert_eq!(result, 4);
72-
// // }
73-
// // }
74-
1+
pub mod cln;

config_spec.toml

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,52 @@ name = "sound_dir"
88
type = "String"
99
doc = "The location to store boost sounds."
1010

11+
[[param]]
12+
name = "listen_port"
13+
type = "u16"
14+
doc = "The port to listen on."
15+
16+
[[param]]
17+
name = "password"
18+
type = "String"
19+
doc = "The password to use to access Helipad."
20+
21+
[[param]]
22+
name = "node_type"
23+
type = "String"
24+
doc = "The type of node to access (LND or CLN)."
25+
26+
[[param]]
27+
name = "lnd_url"
28+
type = "String"
29+
doc = "The url and port of the LND grpc api."
30+
1131
[[param]]
1232
name = "macaroon"
1333
type = "String"
14-
doc = "The location of the macaroon file."
34+
doc = "The location of the LND macaroon file."
1535

1636
[[param]]
1737
name = "cert"
1838
type = "String"
19-
doc = "The location of the tls certificate file."
39+
doc = "The location of the LND tls certificate file."
2040

2141
[[param]]
22-
name = "listen_port"
23-
type = "u16"
24-
doc = "The port to listen on."
42+
name = "cln_url"
43+
type = "String"
44+
doc = "The url and port of the CLN GRPC API (e.g. localhost:3001)."
2545

2646
[[param]]
27-
name = "password"
47+
name = "cln_cert_path"
2848
type = "String"
29-
doc = "The password to use to access Helipad."
49+
doc = "The location of the CLN client certificate."
3050

3151
[[param]]
32-
name = "lnd_url"
52+
name = "cln_key_path"
53+
type = "String"
54+
doc = "The location of the CLN client key."
55+
56+
[[param]]
57+
name = "cln_cacert_path"
3358
type = "String"
34-
doc = "The url and port of the LND grpc api."
59+
doc = "The location of the CLN CA certificate."

helipad.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ macaroon="/lnd/data/chain/bitcoin/mainnet/admin.macaroon"
2121
cert="/lnd/tls.cert"
2222

2323
##: Overridden by env:LND_URL
24-
lnd_url="https://127.0.0.1:10009"
24+
lnd_url="https://127.0.0.1:10009"
25+
26+
cln_url="https://cln:2105"

src/handler.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ use std::string::String;
2525
use url::Url;
2626
use tempfile::NamedTempFile;
2727

28+
use crate::lnclient;
29+
2830
//Structs and Enums ------------------------------------------------------------------------------------------
2931
#[derive(Debug, Serialize, Deserialize)]
3032
struct JwtClaims {
@@ -406,7 +408,7 @@ pub struct ReplyForm {
406408
#[derive(Debug, Serialize, Deserialize)]
407409
pub struct ReplyResponse {
408410
success: bool,
409-
data: BoostRecord,
411+
payment: lnclient::Payment,
410412
}
411413

412414
pub async fn api_v1_reply(
@@ -461,10 +463,12 @@ pub async fn api_v1_reply(
461463
});
462464

463465
let helipad_config = state.helipad_config.clone();
464-
let lightning = match lightning::connect_to_lnd(helipad_config.node_address, helipad_config.cert_path, helipad_config.macaroon_path).await {
465-
Some(lndconn) => lndconn,
466-
None => {
467-
return (StatusCode::INTERNAL_SERVER_ERROR, "** Error connecting to LND.").into_response();
466+
467+
let lightning = match lnclient::connect(&helipad_config).await {
468+
Ok(conn) => conn,
469+
Err(e) => {
470+
eprintln!("** Error connecting to node: {}", e);
471+
return (StatusCode::INTERNAL_SERVER_ERROR, "** Error connecting to node.").into_response();
468472
}
469473
};
470474

@@ -478,33 +482,27 @@ pub async fn api_v1_reply(
478482

479483
let mut cache = podcastindex::GuidCache::new(1);
480484

481-
let mut boost = match lightning::parse_boost_from_payment(payment, &mut cache).await {
482-
Some(boost) => boost,
483-
None => {
484-
eprintln!("** Error parsing sent boost");
485-
return (StatusCode::INTERNAL_SERVER_ERROR, "** Error parsing sent boost").into_response();
485+
if let Some(mut boost) = lightning::parse_boost_from_payment(&payment, &mut cache).await {
486+
if let Some(pay_info) = boost.payment_info {
487+
boost.payment_info = Some(dbif::PaymentRecord {
488+
reply_to_idx: Some(index),
489+
..pay_info
490+
});
486491
}
487-
};
488-
489-
if let Some(pay_info) = boost.payment_info {
490-
boost.payment_info = Some(dbif::PaymentRecord {
491-
reply_to_idx: Some(index),
492-
..pay_info
493-
});
494-
}
495492

496-
//Give some output
497-
println!("Sent Boost: {:#?}", boost);
493+
//Give some output
494+
println!("Sent Boost: {:#?}", boost);
498495

499-
//Store in the database
500-
match dbif::add_payment_to_db(&state.helipad_config.database_file_path, &boost) {
501-
Ok(_) => println!("New sent boost added."),
502-
Err(e) => eprintln!("Error adding sent boost: {:#?}", e)
496+
//Store in the database
497+
match dbif::add_payment_to_db(&state.helipad_config.database_file_path, &boost) {
498+
Ok(_) => println!("New sent boost added."),
499+
Err(e) => eprintln!("Error adding sent boost: {:#?}", e)
500+
}
503501
}
504502

505503
Json(ReplyResponse {
506504
success: true,
507-
data: boost,
505+
payment: payment,
508506
}).into_response()
509507
}
510508

0 commit comments

Comments
 (0)