mirror of
https://github.com/aljazceru/cdk.git
synced 2026-02-23 14:06:56 +01:00
feat: remove fedimint tonic lnd (#831)
* feat: remove fedimint tonic lnd
This commit is contained in:
@@ -93,14 +93,12 @@ instant = { version = "0.1", default-features = false }
|
||||
rand = "0.9.1"
|
||||
regex = "1"
|
||||
home = "0.5.5"
|
||||
tonic = { version = "0.13.1", features = [
|
||||
"channel",
|
||||
"tls-webpki-roots",
|
||||
] }
|
||||
tonic = { version = "0.13.1", features = ["tls-ring", "codegen", "prost", "transport"], default-features = false }
|
||||
prost = "0.13.1"
|
||||
tonic-build = "0.13.1"
|
||||
strum = "0.27.1"
|
||||
strum_macros = "0.27.1"
|
||||
rustls = { version = "0.23.28", default-features = false, features = ["ring"] }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,10 +14,20 @@ readme = "README.md"
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
cdk-common = { workspace = true, features = ["mint"] }
|
||||
fedimint-tonic-lnd = "0.2.0"
|
||||
futures.workspace = true
|
||||
tokio.workspace = true
|
||||
tokio = { workspace = true, default-features = false, features = ["fs"] }
|
||||
tokio-util.workspace = true
|
||||
tracing.workspace = true
|
||||
thiserror.workspace = true
|
||||
serde_json.workspace = true
|
||||
prost.workspace = true
|
||||
tonic = { workspace = true, features = ["transport"] }
|
||||
http = "1.3.1"
|
||||
hyper = { version = "1.6.0", features = ["http2", "client"] }
|
||||
hyper-util = { version = "0.1.14", features = ["client"] }
|
||||
hyper-rustls = { version = "0.27.7", features = ["http2", "tls12"] }
|
||||
rustls.workspace = true
|
||||
rustls-pemfile = "2.2.0"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build.workspace = true
|
||||
|
||||
19
crates/cdk-lnd/build.rs
Normal file
19
crates/cdk-lnd/build.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!("cargo:rerun-if-changed=src/proto/lnrpc.proto");
|
||||
println!("cargo:rerun-if-changed=src/proto/routerrpc.proto");
|
||||
|
||||
// Tell cargo to tell rustc to allow missing docs in generated code
|
||||
println!("cargo:rustc-env=RUSTDOC_ARGS=--allow-missing-docs");
|
||||
|
||||
// Configure tonic build to generate code with documentation
|
||||
tonic_build::configure()
|
||||
.protoc_arg("--experimental_allow_proto3_optional")
|
||||
.type_attribute(".", "#[allow(missing_docs)]")
|
||||
.field_attribute(".", "#[allow(missing_docs)]")
|
||||
.compile_protos(
|
||||
&["src/proto/lnrpc.proto", "src/proto/routerrpc.proto"],
|
||||
&["src/proto"],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
227
crates/cdk-lnd/src/client.rs
Normal file
227
crates/cdk-lnd/src/client.rs
Normal file
@@ -0,0 +1,227 @@
|
||||
//! GRPC Client
|
||||
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use cdk_common::util::hex;
|
||||
use hyper_rustls::HttpsConnectorBuilder;
|
||||
use hyper_util::client::legacy::connect::HttpConnector;
|
||||
use hyper_util::client::legacy::Client as HyperClient;
|
||||
use hyper_util::rt::TokioExecutor;
|
||||
use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
|
||||
use rustls::crypto::ring::default_provider;
|
||||
use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
|
||||
use rustls::{ClientConfig, DigitallySignedStruct, Error as TLSError, SignatureScheme};
|
||||
use tokio::fs;
|
||||
use tonic::body::Body;
|
||||
use tonic::codegen::InterceptedService;
|
||||
use tonic::metadata::MetadataValue;
|
||||
use tonic::service::Interceptor;
|
||||
use tonic::{Request, Status};
|
||||
|
||||
use crate::{lnrpc, routerrpc, Error};
|
||||
|
||||
/// Custom certificate verifier for LND's self-signed certificates
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct LndCertVerifier {
|
||||
certs: Vec<Vec<u8>>,
|
||||
provider: Arc<rustls::crypto::CryptoProvider>,
|
||||
}
|
||||
|
||||
impl LndCertVerifier {
|
||||
pub(crate) async fn load(path: impl AsRef<Path>) -> Result<Self, Error> {
|
||||
let provider = default_provider();
|
||||
|
||||
let contents = fs::read(path).await.map_err(|_| Error::ReadFile)?;
|
||||
let mut reader = std::io::Cursor::new(contents);
|
||||
|
||||
// Parse PEM certificates
|
||||
let certs: Vec<CertificateDer<'static>> =
|
||||
rustls_pemfile::certs(&mut reader).flatten().collect();
|
||||
|
||||
Ok(LndCertVerifier {
|
||||
certs: certs.into_iter().map(|c| c.to_vec()).collect(),
|
||||
provider: Arc::new(provider),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ServerCertVerifier for LndCertVerifier {
|
||||
fn verify_server_cert(
|
||||
&self,
|
||||
end_entity: &CertificateDer<'_>,
|
||||
intermediates: &[CertificateDer<'_>],
|
||||
_server_name: &ServerName,
|
||||
_ocsp_response: &[u8],
|
||||
_now: UnixTime,
|
||||
) -> Result<ServerCertVerified, TLSError> {
|
||||
let mut certs = intermediates
|
||||
.iter()
|
||||
.map(|c| c.as_ref().to_vec())
|
||||
.collect::<Vec<Vec<u8>>>();
|
||||
certs.push(end_entity.as_ref().to_vec());
|
||||
certs.sort();
|
||||
|
||||
let mut our_certs = self.certs.clone();
|
||||
our_certs.sort();
|
||||
|
||||
if self.certs.len() != certs.len() {
|
||||
return Err(TLSError::General(format!(
|
||||
"Mismatched number of certificates (Expected: {}, Presented: {})",
|
||||
self.certs.len(),
|
||||
certs.len()
|
||||
)));
|
||||
}
|
||||
for (c, p) in our_certs.iter().zip(certs.iter()) {
|
||||
if p != c {
|
||||
return Err(TLSError::General(
|
||||
"Server certificates do not match ours".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ServerCertVerified::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls12_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, TLSError> {
|
||||
rustls::crypto::verify_tls12_signature(
|
||||
message,
|
||||
cert,
|
||||
dss,
|
||||
&self.provider.signature_verification_algorithms,
|
||||
)
|
||||
.map(|_| HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn verify_tls13_signature(
|
||||
&self,
|
||||
message: &[u8],
|
||||
cert: &CertificateDer<'_>,
|
||||
dss: &DigitallySignedStruct,
|
||||
) -> Result<HandshakeSignatureValid, TLSError> {
|
||||
rustls::crypto::verify_tls13_signature(
|
||||
message,
|
||||
cert,
|
||||
dss,
|
||||
&self.provider.signature_verification_algorithms,
|
||||
)
|
||||
.map(|_| HandshakeSignatureValid::assertion())
|
||||
}
|
||||
|
||||
fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
|
||||
self.provider
|
||||
.signature_verification_algorithms
|
||||
.supported_schemes()
|
||||
}
|
||||
}
|
||||
|
||||
pub type RouterClient = routerrpc::router_client::RouterClient<
|
||||
InterceptedService<
|
||||
HyperClient<hyper_rustls::HttpsConnector<HttpConnector>, Body>,
|
||||
MacaroonInterceptor,
|
||||
>,
|
||||
>;
|
||||
|
||||
/// The client returned by `connect` function
|
||||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
lightning: lnrpc::lightning_client::LightningClient<
|
||||
InterceptedService<
|
||||
HyperClient<hyper_rustls::HttpsConnector<HttpConnector>, Body>,
|
||||
MacaroonInterceptor,
|
||||
>,
|
||||
>,
|
||||
router: RouterClient,
|
||||
}
|
||||
|
||||
/// Supplies requests with macaroon
|
||||
#[derive(Clone)]
|
||||
pub struct MacaroonInterceptor {
|
||||
macaroon: String,
|
||||
}
|
||||
|
||||
impl Interceptor for MacaroonInterceptor {
|
||||
fn call(&mut self, mut request: Request<()>) -> Result<Request<()>, Status> {
|
||||
request.metadata_mut().insert(
|
||||
"macaroon",
|
||||
MetadataValue::from_str(&self.macaroon)
|
||||
.map_err(|e| Status::internal(format!("Invalid macaroon: {e}")))?,
|
||||
);
|
||||
Ok(request)
|
||||
}
|
||||
}
|
||||
|
||||
async fn load_macaroon(path: impl AsRef<Path>) -> Result<String, Error> {
|
||||
let macaroon = fs::read(path).await.map_err(|_| Error::ReadFile)?;
|
||||
Ok(hex::encode(macaroon))
|
||||
}
|
||||
|
||||
pub async fn connect<P: AsRef<Path>>(
|
||||
address: &str,
|
||||
cert_path: P,
|
||||
macaroon_path: P,
|
||||
) -> Result<Client, Error> {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none() {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
}
|
||||
|
||||
let config = ClientConfig::builder()
|
||||
.dangerous()
|
||||
.with_custom_certificate_verifier(Arc::new(LndCertVerifier::load(cert_path).await?))
|
||||
.with_no_client_auth();
|
||||
|
||||
// Create HTTPS connector
|
||||
let https = HttpsConnectorBuilder::new()
|
||||
.with_tls_config(config)
|
||||
.https_only()
|
||||
.enable_http2()
|
||||
.build();
|
||||
|
||||
// Create hyper client
|
||||
let client = HyperClient::builder(TokioExecutor::new())
|
||||
.http2_only(true)
|
||||
.build(https);
|
||||
|
||||
// Load macaroon
|
||||
let macaroon = load_macaroon(macaroon_path).await?;
|
||||
|
||||
// Create service with macaroon interceptor
|
||||
let service = InterceptedService::new(client, MacaroonInterceptor { macaroon });
|
||||
|
||||
// Create URI for the service
|
||||
let address = address
|
||||
.trim_start_matches("http://")
|
||||
.trim_start_matches("https://");
|
||||
let uri = http::Uri::from_str(&format!("https://{address}"))
|
||||
.map_err(|e| Error::InvalidConfig(format!("Invalid URI: {e}")))?;
|
||||
|
||||
// Create LND client
|
||||
let lightning =
|
||||
lnrpc::lightning_client::LightningClient::with_origin(service.clone(), uri.clone());
|
||||
let router = RouterClient::with_origin(service, uri);
|
||||
|
||||
Ok(Client { lightning, router })
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn lightning(
|
||||
&mut self,
|
||||
) -> &mut lnrpc::lightning_client::LightningClient<
|
||||
InterceptedService<
|
||||
HyperClient<hyper_rustls::HttpsConnector<HttpConnector>, Body>,
|
||||
MacaroonInterceptor,
|
||||
>,
|
||||
> {
|
||||
&mut self.lightning
|
||||
}
|
||||
|
||||
pub fn router(&mut self) -> &mut RouterClient {
|
||||
&mut self.router
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
//! LND Errors
|
||||
|
||||
use fedimint_tonic_lnd::tonic::Status;
|
||||
use thiserror::Error;
|
||||
use tonic::Status;
|
||||
|
||||
/// LND Error
|
||||
#[derive(Debug, Error)]
|
||||
@@ -36,6 +36,9 @@ pub enum Error {
|
||||
/// Errors invalid config
|
||||
#[error("LND invalid config: `{0}`")]
|
||||
InvalidConfig(String),
|
||||
/// Could not read file
|
||||
#[error("Could not read file")]
|
||||
ReadFile,
|
||||
}
|
||||
|
||||
impl From<Error> for cdk_common::payment::Error {
|
||||
@@ -43,3 +46,9 @@ impl From<Error> for cdk_common::payment::Error {
|
||||
Self::Lightning(Box::new(e))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<tonic::transport::Error> for Error {
|
||||
fn from(e: tonic::transport::Error) -> Self {
|
||||
Error::InvalidConfig(format!("Transport error: {e}"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,25 +26,26 @@ use cdk_common::payment::{
|
||||
use cdk_common::util::hex;
|
||||
use cdk_common::{mint, Bolt11Invoice};
|
||||
use error::Error;
|
||||
use fedimint_tonic_lnd::lnrpc::fee_limit::Limit;
|
||||
use fedimint_tonic_lnd::lnrpc::payment::PaymentStatus;
|
||||
use fedimint_tonic_lnd::lnrpc::{FeeLimit, Hop, MppRecord};
|
||||
use fedimint_tonic_lnd::tonic::Code;
|
||||
use fedimint_tonic_lnd::Client;
|
||||
use futures::{Stream, StreamExt};
|
||||
use tokio::sync::Mutex;
|
||||
use lnrpc::fee_limit::Limit;
|
||||
use lnrpc::payment::PaymentStatus;
|
||||
use lnrpc::{FeeLimit, Hop, MppRecord};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::instrument;
|
||||
|
||||
mod client;
|
||||
pub mod error;
|
||||
|
||||
mod proto;
|
||||
pub(crate) use proto::{lnrpc, routerrpc};
|
||||
|
||||
/// Lnd mint backend
|
||||
#[derive(Clone)]
|
||||
pub struct Lnd {
|
||||
address: String,
|
||||
cert_file: PathBuf,
|
||||
macaroon_file: PathBuf,
|
||||
client: Arc<Mutex<Client>>,
|
||||
_address: String,
|
||||
_cert_file: PathBuf,
|
||||
_macaroon_file: PathBuf,
|
||||
lnd_client: client::Client,
|
||||
fee_reserve: FeeReserve,
|
||||
wait_invoice_cancel_token: CancellationToken,
|
||||
wait_invoice_is_active: Arc<AtomicBool>,
|
||||
@@ -86,18 +87,19 @@ impl Lnd {
|
||||
)));
|
||||
}
|
||||
|
||||
let client = fedimint_tonic_lnd::connect(address.to_string(), &cert_file, &macaroon_file)
|
||||
let lnd_client = client::connect(&address, &cert_file, &macaroon_file)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
tracing::error!("Connection error: {}", err.to_string());
|
||||
Error::Connection
|
||||
})?;
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(Self {
|
||||
address,
|
||||
cert_file,
|
||||
macaroon_file,
|
||||
client: Arc::new(Mutex::new(client)),
|
||||
_address: address,
|
||||
_cert_file: cert_file,
|
||||
_macaroon_file: macaroon_file,
|
||||
lnd_client,
|
||||
fee_reserve,
|
||||
wait_invoice_cancel_token: CancellationToken::new(),
|
||||
wait_invoice_is_active: Arc::new(AtomicBool::new(false)),
|
||||
@@ -134,17 +136,14 @@ impl MintPayment for Lnd {
|
||||
async fn wait_any_incoming_payment(
|
||||
&self,
|
||||
) -> Result<Pin<Box<dyn Stream<Item = String> + Send>>, Self::Err> {
|
||||
let mut client =
|
||||
fedimint_tonic_lnd::connect(self.address.clone(), &self.cert_file, &self.macaroon_file)
|
||||
.await
|
||||
.map_err(|_| Error::Connection)?;
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
let stream_req = fedimint_tonic_lnd::lnrpc::InvoiceSubscription {
|
||||
let stream_req = lnrpc::InvoiceSubscription {
|
||||
add_index: 0,
|
||||
settle_index: 0,
|
||||
};
|
||||
|
||||
let stream = client
|
||||
let stream = lnd_client
|
||||
.lightning()
|
||||
.subscribe_invoices(stream_req)
|
||||
.await
|
||||
@@ -283,9 +282,11 @@ impl MintPayment for Lnd {
|
||||
let payer_addr = invoice.payment_secret().0.to_vec();
|
||||
let payment_hash = invoice.payment_hash();
|
||||
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
for attempt in 0..Self::MAX_ROUTE_RETRIES {
|
||||
// Create a request for the routes
|
||||
let route_req = fedimint_tonic_lnd::lnrpc::QueryRoutesRequest {
|
||||
let route_req = lnrpc::QueryRoutesRequest {
|
||||
pub_key: hex::encode(pub_key.serialize()),
|
||||
amt_msat: u64::from(partial_amount_msat) as i64,
|
||||
fee_limit: max_fee.map(|f| {
|
||||
@@ -297,10 +298,7 @@ impl MintPayment for Lnd {
|
||||
};
|
||||
|
||||
// Query the routes
|
||||
let mut routes_response: fedimint_tonic_lnd::lnrpc::QueryRoutesResponse = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
let mut routes_response = lnd_client
|
||||
.lightning()
|
||||
.query_routes(route_req)
|
||||
.await
|
||||
@@ -319,12 +317,9 @@ impl MintPayment for Lnd {
|
||||
};
|
||||
last_hop.mpp_record = Some(mpp_record);
|
||||
|
||||
let payment_response = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
let payment_response = lnd_client
|
||||
.router()
|
||||
.send_to_route_v2(fedimint_tonic_lnd::routerrpc::SendToRouteRequest {
|
||||
.send_to_route_v2(routerrpc::SendToRouteRequest {
|
||||
payment_hash: payment_hash.to_byte_array().to_vec(),
|
||||
route: Some(routes_response.routes[0].clone()),
|
||||
..Default::default()
|
||||
@@ -375,23 +370,21 @@ impl MintPayment for Lnd {
|
||||
Err(Error::PaymentFailed.into())
|
||||
}
|
||||
None => {
|
||||
let pay_req = fedimint_tonic_lnd::lnrpc::SendRequest {
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
let pay_req = lnrpc::SendRequest {
|
||||
payment_request,
|
||||
fee_limit: max_fee.map(|f| {
|
||||
let limit = Limit::Fixed(u64::from(f) as i64);
|
||||
|
||||
FeeLimit { limit: Some(limit) }
|
||||
}),
|
||||
amt_msat: amount_msat as i64,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let payment_response = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
let payment_response = lnd_client
|
||||
.lightning()
|
||||
.send_payment_sync(fedimint_tonic_lnd::tonic::Request::new(pay_req))
|
||||
.send_payment_sync(tonic::Request::new(pay_req))
|
||||
.await
|
||||
.map_err(|err| {
|
||||
tracing::warn!("Lightning payment failed: {}", err);
|
||||
@@ -433,20 +426,19 @@ impl MintPayment for Lnd {
|
||||
) -> Result<CreateIncomingPaymentResponse, Self::Err> {
|
||||
let amount = to_unit(amount, unit, &CurrencyUnit::Msat)?;
|
||||
|
||||
let invoice_request = fedimint_tonic_lnd::lnrpc::Invoice {
|
||||
let invoice_request = lnrpc::Invoice {
|
||||
value_msat: u64::from(amount) as i64,
|
||||
memo: description,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let invoice = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
let invoice = lnd_client
|
||||
.lightning()
|
||||
.add_invoice(fedimint_tonic_lnd::tonic::Request::new(invoice_request))
|
||||
.add_invoice(tonic::Request::new(invoice_request))
|
||||
.await
|
||||
.unwrap()
|
||||
.map_err(|e| payment::Error::Anyhow(anyhow!(e)))?
|
||||
.into_inner();
|
||||
|
||||
let bolt11 = Bolt11Invoice::from_str(&invoice.payment_request)?;
|
||||
@@ -463,19 +455,18 @@ impl MintPayment for Lnd {
|
||||
&self,
|
||||
request_lookup_id: &str,
|
||||
) -> Result<MintQuoteState, Self::Err> {
|
||||
let invoice_request = fedimint_tonic_lnd::lnrpc::PaymentHash {
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
let invoice_request = lnrpc::PaymentHash {
|
||||
r_hash: hex::decode(request_lookup_id).unwrap(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let invoice = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
let invoice = lnd_client
|
||||
.lightning()
|
||||
.lookup_invoice(fedimint_tonic_lnd::tonic::Request::new(invoice_request))
|
||||
.lookup_invoice(tonic::Request::new(invoice_request))
|
||||
.await
|
||||
.unwrap()
|
||||
.map_err(|e| payment::Error::Anyhow(anyhow!(e)))?
|
||||
.into_inner();
|
||||
|
||||
match invoice.state {
|
||||
@@ -496,24 +487,20 @@ impl MintPayment for Lnd {
|
||||
&self,
|
||||
payment_hash: &str,
|
||||
) -> Result<MakePaymentResponse, Self::Err> {
|
||||
let track_request = fedimint_tonic_lnd::routerrpc::TrackPaymentRequest {
|
||||
let mut lnd_client = self.lnd_client.clone();
|
||||
|
||||
let track_request = routerrpc::TrackPaymentRequest {
|
||||
payment_hash: hex::decode(payment_hash).map_err(|_| Error::InvalidHash)?,
|
||||
no_inflight_updates: true,
|
||||
};
|
||||
|
||||
let payment_response = self
|
||||
.client
|
||||
.lock()
|
||||
.await
|
||||
.router()
|
||||
.track_payment_v2(track_request)
|
||||
.await;
|
||||
let payment_response = lnd_client.router().track_payment_v2(track_request).await;
|
||||
|
||||
let mut payment_stream = match payment_response {
|
||||
Ok(stream) => stream.into_inner(),
|
||||
Err(err) => {
|
||||
let err_code = err.code();
|
||||
if err_code == Code::NotFound {
|
||||
if err_code == tonic::Code::NotFound {
|
||||
return Ok(MakePaymentResponse {
|
||||
payment_lookup_id: payment_hash.to_string(),
|
||||
payment_proof: None,
|
||||
@@ -540,7 +527,7 @@ impl MintPayment for Lnd {
|
||||
total_spent: Amount::ZERO,
|
||||
unit: self.settings.unit.clone(),
|
||||
},
|
||||
PaymentStatus::InFlight => {
|
||||
PaymentStatus::InFlight | PaymentStatus::Initiated => {
|
||||
// Continue waiting for the next update
|
||||
continue;
|
||||
}
|
||||
|
||||
5062
crates/cdk-lnd/src/proto/lnrpc.proto
Normal file
5062
crates/cdk-lnd/src/proto/lnrpc.proto
Normal file
File diff suppressed because it is too large
Load Diff
9
crates/cdk-lnd/src/proto/mod.rs
Normal file
9
crates/cdk-lnd/src/proto/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
#[allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]
|
||||
pub(crate) mod lnrpc {
|
||||
tonic::include_proto!("lnrpc");
|
||||
}
|
||||
|
||||
#[allow(clippy::all, clippy::pedantic, clippy::restriction, clippy::nursery)]
|
||||
pub(crate) mod routerrpc {
|
||||
tonic::include_proto!("routerrpc");
|
||||
}
|
||||
1023
crates/cdk-lnd/src/proto/routerrpc.proto
Normal file
1023
crates/cdk-lnd/src/proto/routerrpc.proto
Normal file
File diff suppressed because it is too large
Load Diff
@@ -24,7 +24,7 @@ cdk = { workspace = true, features = [
|
||||
"mint",
|
||||
] }
|
||||
clap.workspace = true
|
||||
tonic.workspace = true
|
||||
tonic = { workspace = true, features = ["transport"] }
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
tokio.workspace = true
|
||||
@@ -33,6 +33,7 @@ serde.workspace = true
|
||||
thiserror.workspace = true
|
||||
prost.workspace = true
|
||||
home.workspace = true
|
||||
rustls.workspace = true
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
|
||||
@@ -94,6 +94,10 @@ async fn main() -> Result<()> {
|
||||
tracing::debug!("Using work dir: {}", work_dir.display());
|
||||
|
||||
let channel = if work_dir.join("tls").is_dir() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none() {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
}
|
||||
|
||||
// TLS directory exists, configure TLS
|
||||
let server_root_ca_cert = std::fs::read_to_string(work_dir.join("tls/ca.pem")).unwrap();
|
||||
let server_root_ca_cert = Certificate::from_pem(server_root_ca_cert);
|
||||
|
||||
@@ -39,7 +39,7 @@ utoipa = { workspace = true, optional = true }
|
||||
futures.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_with.workspace = true
|
||||
tonic.workspace = true
|
||||
tonic = { workspace = true, features = ["router"] }
|
||||
prost.workspace = true
|
||||
tokio-stream.workspace = true
|
||||
tokio-util = { workspace = true, default-features = false }
|
||||
|
||||
@@ -22,7 +22,7 @@ cdk-common = { workspace = true, default-features = false, features = [
|
||||
"mint",
|
||||
"auth",
|
||||
] }
|
||||
tonic = { workspace = true, optional = true }
|
||||
tonic = { workspace = true, optional = true, features = ["router"] }
|
||||
prost = { workspace = true, optional = true }
|
||||
tracing.workspace = true
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ license.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["mint", "wallet", "auth"]
|
||||
wallet = ["dep:reqwest", "cdk-common/wallet"]
|
||||
wallet = ["dep:reqwest", "cdk-common/wallet", "dep:rustls"]
|
||||
mint = ["dep:futures", "dep:reqwest", "cdk-common/mint", "cdk-signatory"]
|
||||
auth = ["dep:jsonwebtoken", "cdk-common/auth", "cdk-common/auth"]
|
||||
# We do not commit to a MSRV with swagger enabled
|
||||
@@ -61,6 +61,7 @@ tokio-tungstenite = { workspace = true, features = [
|
||||
"rustls-tls-native-roots",
|
||||
"connect"
|
||||
] }
|
||||
rustls = { workspace = true, optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
tokio = { workspace = true, features = ["rt", "macros", "sync", "time"] }
|
||||
|
||||
@@ -34,6 +34,11 @@ struct HttpClientCore {
|
||||
|
||||
impl HttpClientCore {
|
||||
fn new() -> Self {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none() {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
}
|
||||
|
||||
Self {
|
||||
inner: Client::new(),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user