diff --git a/Cargo.toml b/Cargo.toml index 8417ac0..f19523d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,18 +11,21 @@ keywords = ["LND", "rpc", "grpc", "tonic", "async"] categories = ["api-bindings", "asynchronous", "cryptography::cryptocurrencies", "network-programming"] license = "MITNFA" +[lib] +doctest = false + [dependencies] -tonic = { version = "0.6.2", features = ["transport", "tls"] } -prost = "0.9.0" -rustls = { version = "0.19.0", features = ["dangerous_configuration"] } -webpki = "0.21.3" -rustls-pemfile = "1.0.0" +tonic = "0.7" +tonic-openssl = { version = "0.2" } +hyper = "0.14" +hyper-openssl = "0.9" +prost = "0.10" +tokio = { version = "1", features = ["full"] } +tokio-stream = { version = "0.1", features = ["net"] } +openssl = "0.10" +tower = "0.4" +pretty_env_logger = "0.4.0" hex = "0.4.3" -tokio = { version = "1.7.1", features = ["fs"] } -tracing = { version = "0.1", features = ["log"], optional = true } [build-dependencies] -tonic-build = "0.5.2" - -[dev-dependencies] -tokio = { version = "1.7.1", features = ["rt-multi-thread"] } +tonic-build = "0.7" diff --git a/README.md b/README.md index 32a11d6..aac179f 100644 --- a/README.md +++ b/README.md @@ -30,19 +30,29 @@ You can find the same example in crate root for your convenience. async fn main() { let mut args = std::env::args_os(); args.next().expect("not even zeroth arg given"); - let address = args.next().expect("missing arguments: address, cert file, macaroon file"); - let cert_file = args.next().expect("missing arguments: cert file, macaroon file"); - let macaroon_file = args.next().expect("missing argument: macaroon file"); + let address = args + .next() + .expect("missing arguments: address, cert file, macaroon file"); + let cert_file = args + .next() + .expect("missing arguments: cert file, macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let macaroon_file = args + .next() + .expect("missing argument: macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); let address = address.into_string().expect("address is not UTF-8"); // Connecting to LND requires only address, cert file, and macaroon file - let mut client = tonic_lnd::connect(address, cert_file, macaroon_file) + let mut client = tonic_lnd::connect_lightning(address, cert_file, macaroon_file) .await .expect("failed to connect"); let info = client // All calls require at least empty parameter - .get_info(tonic_lnd::rpc::GetInfoRequest {}) + .get_info(tonic_lnd::lnrpc::GetInfoRequest {}) .await .expect("failed to get info"); diff --git a/build.rs b/build.rs index b8740b3..7f7d94d 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::path::PathBuf; fn main() -> std::io::Result<()> { println!("cargo:rerun-if-env-changed=LND_REPO_DIR"); @@ -8,17 +8,40 @@ fn main() -> std::io::Result<()> { let mut lnd_rpc_dir = PathBuf::from(lnd_repo_path); lnd_rpc_dir.push("lnrpc"); lnd_rpc_dir_owned = lnd_rpc_dir; - &*lnd_rpc_dir_owned - }, - None => Path::new("vendor"), + lnd_rpc_dir_owned.display().to_string() + } + None => "vendor".to_string(), }; - let lnd_rpc_proto_file = dir.join("lightning.proto"); - println!("cargo:rerun-if-changed={}", lnd_rpc_proto_file.display()); + let protos = vec![ + "autopilotrpc/autopilot.proto", + "chainrpc/chainnotifier.proto", + "devrpc/dev.proto", + "invoicesrpc/invoices.proto", + "lightning.proto", + "lnclipb/lncli.proto", + "neutrinorpc/neutrino.proto", + "peersrpc/peers.proto", + "routerrpc/router.proto", + "signrpc/signer.proto", + "verrpc/verrpc.proto", + "walletrpc/walletkit.proto", + "watchtowerrpc/watchtower.proto", + "wtclientrpc/wtclient.proto", + ]; + + let proto_paths: Vec<_> = protos + .iter() + .map(|proto| { + let mut path = PathBuf::from(&dir); + path.push(proto); + path.display().to_string() + }) + .collect(); tonic_build::configure() .build_client(true) .build_server(false) - .format(false) - .compile(&[&*lnd_rpc_proto_file], &[dir]) + .compile(&proto_paths, &[dir])?; + Ok(()) } diff --git a/examples/addholdinvoice.rs b/examples/addholdinvoice.rs new file mode 100644 index 0000000..c8e2928 --- /dev/null +++ b/examples/addholdinvoice.rs @@ -0,0 +1,40 @@ +// This program accepts three arguments: address, cert file, macaroon file +// The address must start with `https://`! + +#[tokio::main] +async fn main() { + let mut args = std::env::args_os(); + args.next().expect("not even zeroth arg given"); + let address = args + .next() + .expect("missing arguments: address, cert file, macaroon file"); + let cert_file = args + .next() + .expect("missing arguments: cert file, macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let macaroon_file = args + .next() + .expect("missing argument: macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let address = address.into_string().expect("address is not UTF-8"); + + // Connecting to LND requires only address, cert file, macaroon file + let mut invoices_client = tonic_lnd::connect_invoices(address, cert_file, macaroon_file) + .await + .expect("failed to connect"); + + let add_hold_invoice_resp = invoices_client + .add_hold_invoice(tonic_lnd::invoicesrpc::AddHoldInvoiceRequest { + hash: vec![0; 32], + value: 5555, + ..Default::default() + }) + .await + .expect("failed to add hold invoice"); + + // We only print it here, note that in real-life code you may want to call `.into_inner()` on + // the response to get the message. + println!("{:#?}", add_hold_invoice_resp); +} diff --git a/examples/getinfo.rs b/examples/getinfo.rs index ccb6007..a229751 100644 --- a/examples/getinfo.rs +++ b/examples/getinfo.rs @@ -8,19 +8,29 @@ async fn main() { let mut args = std::env::args_os(); args.next().expect("not even zeroth arg given"); - let address = args.next().expect("missing arguments: address, cert file, macaroon file"); - let cert_file = args.next().expect("missing arguments: cert file, macaroon file"); - let macaroon_file = args.next().expect("missing argument: macaroon file"); + let address = args + .next() + .expect("missing arguments: address, cert file, macaroon file"); + let cert_file = args + .next() + .expect("missing arguments: cert file, macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let macaroon_file = args + .next() + .expect("missing argument: macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); let address = address.into_string().expect("address is not UTF-8"); // Connecting to LND requires only address, cert file, and macaroon file - let mut client = tonic_lnd::connect(address, cert_file, macaroon_file) + let mut client = tonic_lnd::connect_lightning(address, cert_file, macaroon_file) .await .expect("failed to connect"); let info = client // All calls require at least empty parameter - .get_info(tonic_lnd::rpc::GetInfoRequest {}) + .get_info(tonic_lnd::lnrpc::GetInfoRequest {}) .await .expect("failed to get info"); diff --git a/examples/subscribe_invoices.rs b/examples/subscribe_invoices.rs index 838e479..3501fee 100644 --- a/examples/subscribe_invoices.rs +++ b/examples/subscribe_invoices.rs @@ -11,17 +11,23 @@ async fn main() { .expect("missing arguments: address, cert file, macaroon file"); let cert_file = args .next() - .expect("missing arguments: cert file, macaroon file"); - let macaroon_file = args.next().expect("missing argument: macaroon file"); + .expect("missing arguments: cert file, macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let macaroon_file = args + .next() + .expect("missing argument: macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); let address = address.into_string().expect("address is not UTF-8"); // Connecting to LND requires only address, cert file, and macaroon file - let mut client = tonic_lnd::connect(address, cert_file, macaroon_file) + let mut client = tonic_lnd::connect_lightning(address, cert_file, macaroon_file) .await .expect("failed to connect"); let mut invoice_stream = client - .subscribe_invoices(tonic_lnd::rpc::InvoiceSubscription { + .subscribe_invoices(tonic_lnd::lnrpc::InvoiceSubscription { add_index: 0, settle_index: 0, }) @@ -34,9 +40,9 @@ async fn main() { .await .expect("Failed to receive invoices") { - if let Some(state) = tonic_lnd::rpc::invoice::InvoiceState::from_i32(invoice.state) { + if let Some(state) = tonic_lnd::lnrpc::invoice::InvoiceState::from_i32(invoice.state) { // If this invoice was Settled we can do something with it - if state == tonic_lnd::rpc::invoice::InvoiceState::Settled { + if state == tonic_lnd::lnrpc::invoice::InvoiceState::Settled { println!("{:?}", invoice); } } diff --git a/src/error.rs b/src/error.rs index 62f5386..bec0daa 100644 --- a/src/error.rs +++ b/src/error.rs @@ -13,19 +13,16 @@ pub struct ConnectError { impl From for ConnectError { fn from(value: InternalConnectError) -> Self { - ConnectError { - internal: value, - } + ConnectError { internal: value } } } #[derive(Debug)] pub(crate) enum InternalConnectError { - ReadFile { file: PathBuf, error: std::io::Error, }, - ParseCert { file: PathBuf, error: std::io::Error, }, - InvalidAddress { address: String, error: Box, }, - TlsConfig(tonic::transport::Error), - Connect { address: String, error: tonic::transport::Error, } + ReadFile { + file: PathBuf, + error: std::io::Error, + }, } impl fmt::Display for ConnectError { @@ -34,10 +31,6 @@ impl fmt::Display for ConnectError { match &self.internal { ReadFile { file, .. } => write!(f, "failed to read file {}", file.display()), - ParseCert { file, .. } => write!(f, "failed to parse certificate {}", file.display()), - InvalidAddress { address, .. } => write!(f, "invalid address {}", address), - TlsConfig(_) => write!(f, "failed to configure TLS"), - Connect { address, .. } => write!(f, "failed to connect to {}", address), } } } @@ -48,10 +41,6 @@ impl std::error::Error for ConnectError { match &self.internal { ReadFile { error, .. } => Some(error), - ParseCert { error, .. } => Some(error), - InvalidAddress { error, .. } => Some(&**error), - TlsConfig(error) => Some(error), - Connect { error, .. } => Some(error), } } } diff --git a/src/lib.rs b/src/lib.rs index d8c72ec..002a04c 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,48 +1,49 @@ // include_str! is not supported in attributes yet #![doc = r###" -Rust implementation of LND RPC client using async GRPC library `tonic`. - +Rust implementation of LND RPC client using async GRPC library `tonic-openssl`. ## About - **Warning: this crate is in early development and may have unknown problems! Review it before using with mainnet funds!** - This crate implements LND GRPC using [`tonic`](https://docs.rs/tonic/) and [`prost`](https://docs.rs/prost/). Apart from being up-to-date at the time of writing (:D) it also allows `aync` usage. It contains vendored `rpc.proto` file so LND source code is not *required* but accepts an environment variable `LND_REPO_DIR` which overrides the vendored `rpc.proto` file. This can be used to test new features in non-released `lnd`. (Actually, the motivating project using this library is that case. :)) - ## Usage - There's no setup needed beyond adding the crate to your `Cargo.toml`. If you need to change the `rpc.proto` input set the environment variable `LND_REPO_DIR` to the directory with cloned `lnd` during build. - Here's an example of retrieving information from LND (`getinfo` call). You can find the same example in crate root for your convenience. - ```rust // This program accepts three arguments: address, cert file, macaroon file -// The address must start with `https://`! - #[tokio::main] async fn main() { let mut args = std::env::args_os(); args.next().expect("not even zeroth arg given"); - let address = args.next().expect("missing arguments: address, cert file, macaroon file"); - let cert_file = args.next().expect("missing arguments: cert file, macaroon file"); - let macaroon_file = args.next().expect("missing argument: macaroon file"); + let address = args + .next() + .expect("missing arguments: address, cert file, macaroon file"); + let cert_file = args + .next() + .expect("missing arguments: cert file, macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); + let macaroon_file = args + .next() + .expect("missing argument: macaroon file") + .into_string() + .expect("cert_file is not UTF-8"); let address = address.into_string().expect("address is not UTF-8"); // Connecting to LND requires only address, cert file, and macaroon file - let mut client = tonic_lnd::connect(address, cert_file, macaroon_file) + let mut client = tonic_lnd::connect_lightning(address, cert_file, macaroon_file) .await .expect("failed to connect"); let info = client // All calls require at least empty parameter - .get_info(tonic_lnd::rpc::GetInfoRequest {}) + .get_info(tonic_lnd::lnrpc::GetInfoRequest {}) .await .expect("failed to get info"); @@ -51,54 +52,139 @@ async fn main() { println!("{:#?}", info); } ``` - ## MSRV - Undetermined yet, please make suggestions. - ## License - MITNFA "###] -/// This is part of public interface so it's re-exported. -pub extern crate tonic; - -use std::path::{Path, PathBuf}; -use std::convert::TryInto; -pub use error::ConnectError; use error::InternalConnectError; +use hyper::client::connect::HttpConnector; +use hyper::{client::ResponseFuture, Body, Client, Request, Response, Uri}; +use hyper_openssl::HttpsConnector; +use openssl::{ + ssl::{SslConnector, SslMethod}, + x509::X509, +}; +use std::path::{Path, PathBuf}; +use std::{error::Error, task::Poll}; +use tonic::body::BoxBody; +use tonic_openssl::ALPN_H2_WIRE; +use tower::Service; -#[cfg(feature = "tracing")] -use tracing; - -/// The client returned by `connect` function -/// -/// This is a convenience type which you most likely want to use instead of raw client. -pub type Client = rpc::lightning_client::LightningClient>; +pub mod autopilotrpc { + tonic::include_proto!("autopilotrpc"); +} -/// [`tonic::Status`] is re-exported as `Error` for convenience. -pub type Error = tonic::Status; +pub mod chainrpc { + tonic::include_proto!("chainrpc"); +} -mod error; +pub mod devrpc { + tonic::include_proto!("devrpc"); +} -macro_rules! try_map_err { - ($result:expr, $mapfn:expr) => { - match $result { - Ok(value) => value, - Err(error) => return Err($mapfn(error).into()), - } - } +pub mod invoicesrpc { + tonic::include_proto!("invoicesrpc"); } -/// Messages and other types generated by `tonic`/`prost` -/// -/// This is the go-to module you will need to look in to find documentation on various message -/// types. However it may be better to start from methods on the [`LightningClient`](rpc::lightning_client::LightningClient) type. -pub mod rpc { +pub mod lnrpc { tonic::include_proto!("lnrpc"); } +pub mod lnclipb { + tonic::include_proto!("lnclipb"); +} + +pub mod neutrinorpc { + tonic::include_proto!("neutrinorpc"); +} + +pub mod peersrpc { + tonic::include_proto!("peersrpc"); +} + +pub mod routerrpc { + tonic::include_proto!("routerrpc"); +} + +pub mod signrpc { + tonic::include_proto!("signrpc"); +} + +pub mod verrpc { + tonic::include_proto!("verrpc"); +} + +pub mod walletrpc { + tonic::include_proto!("walletrpc"); +} + +pub mod watchtowerrpc { + tonic::include_proto!("watchtowerrpc"); +} + +pub mod wtclientrpc { + tonic::include_proto!("wtclientrpc"); +} + +/// [`tonic::Status`] is re-exported as `LndClientError` for convenience. +pub type LndClientError = tonic::Status; + +pub type LndAutopilotClient = crate::autopilotrpc::autopilot_client::AutopilotClient< + tonic::codegen::InterceptedService, +>; + +pub type LndChainClient = crate::chainrpc::chain_notifier_client::ChainNotifierClient< + tonic::codegen::InterceptedService, +>; + +pub type LndDevClient = crate::devrpc::dev_client::DevClient< + tonic::codegen::InterceptedService, +>; + +pub type LndInvoicesClient = crate::invoicesrpc::invoices_client::InvoicesClient< + tonic::codegen::InterceptedService, +>; + +pub type LndLightningClient = crate::lnrpc::lightning_client::LightningClient< + tonic::codegen::InterceptedService, +>; + +pub type LndNeutrinoClient = crate::neutrinorpc::neutrino_kit_client::NeutrinoKitClient< + tonic::codegen::InterceptedService, +>; + +pub type LndPeersClient = crate::peersrpc::peers_client::PeersClient< + tonic::codegen::InterceptedService, +>; + +pub type LndRouterClient = crate::routerrpc::router_client::RouterClient< + tonic::codegen::InterceptedService, +>; + +pub type LndSignerClient = crate::signrpc::signer_client::SignerClient< + tonic::codegen::InterceptedService, +>; + +pub type LndVersionerClient = crate::verrpc::versioner_client::VersionerClient< + tonic::codegen::InterceptedService, +>; + +pub type LndWalletClient = crate::walletrpc::wallet_kit_client::WalletKitClient< + tonic::codegen::InterceptedService, +>; + +pub type LndWatchtowerClient = crate::watchtowerrpc::watchtower_client::WatchtowerClient< + tonic::codegen::InterceptedService, +>; + +pub type LndWtcClient = crate::wtclientrpc::watchtower_client_client::WatchtowerClientClient< + tonic::codegen::InterceptedService, +>; + +mod error; + /// Supplies requests with macaroon #[derive(Clone)] pub struct MacaroonInterceptor { @@ -106,105 +192,274 @@ pub struct MacaroonInterceptor { } impl tonic::service::Interceptor for MacaroonInterceptor { - fn call(&mut self, mut request: tonic::Request<()>) -> Result, Error> { - request - .metadata_mut() - .insert("macaroon", tonic::metadata::MetadataValue::from_str(&self.macaroon).expect("hex produced non-ascii")); + fn call( + &mut self, + mut request: tonic::Request<()>, + ) -> Result, LndClientError> { + request.metadata_mut().insert( + "macaroon", + #[allow(deprecated)] + tonic::metadata::MetadataValue::from_str(&self.macaroon) + .expect("hex produced non-ascii"), + ); Ok(request) } } -async fn load_macaroon(path: impl AsRef + Into) -> Result { - let macaroon = tokio::fs::read(&path) - .await - .map_err(|error| InternalConnectError::ReadFile { file: path.into(), error, })?; +async fn load_macaroon( + path: impl AsRef + Into, +) -> Result { + let macaroon = + tokio::fs::read(&path) + .await + .map_err(|error| InternalConnectError::ReadFile { + file: path.into(), + error, + })?; Ok(hex::encode(&macaroon)) } -/// Connects to LND using given address and credentials -/// -/// This function does all required processing of the cert file and macaroon file, so that you -/// don't have to. The address must begin with "https://", though. -/// -/// This is considered the recommended way to connect to LND. An alternative function to use -/// already-read certificate or macaroon data is currently **not** provided to discourage such use. -/// LND occasionally changes that data which would lead to errors and in turn in worse application. -/// -/// If you have a motivating use case for use of direct data feel free to open an issue and -/// explain. -#[cfg_attr(feature = "tracing", tracing::instrument(name = "Connecting to LND"))] -pub async fn connect(address: A, cert_file: CP, macaroon_file: MP) -> Result where A: TryInto + std::fmt::Debug + ToString, >::Error: std::error::Error + Send + Sync + 'static, CP: AsRef + Into + std::fmt::Debug, MP: AsRef + Into + std::fmt::Debug { - let address_str = address.to_string(); - let conn = try_map_err!(address - .try_into(), |error| InternalConnectError::InvalidAddress { address: address_str.clone(), error: Box::new(error), }) - .tls_config(tls::config(cert_file).await?) - .map_err(InternalConnectError::TlsConfig)? - .connect() - .await - .map_err(|error| InternalConnectError::Connect { address: address_str, error, })?; +async fn get_channel( + lnd_address: String, + lnd_tls_cert_path: String, +) -> Result> { + let pem = tokio::fs::read(lnd_tls_cert_path).await.ok(); + let uri = lnd_address.parse::().unwrap(); + let channel = MyChannel::new(pem, uri).await?; + Ok(channel) +} - let macaroon = load_macaroon(macaroon_file).await?; +async fn get_macaroon_interceptor( + lnd_macaroon_path: String, +) -> Result> { + // TODO: don't use unwrap. + let macaroon = load_macaroon(lnd_macaroon_path).await.unwrap(); + Ok(MacaroonInterceptor { macaroon }) +} - let interceptor = MacaroonInterceptor { macaroon, }; +pub async fn connect_autopilot( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::autopilotrpc::autopilot_client::AutopilotClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) +} - Ok(rpc::lightning_client::LightningClient::with_interceptor(conn, interceptor)) +pub async fn connect_chain_notifier( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::chainrpc::chain_notifier_client::ChainNotifierClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) } -mod tls { - use std::path::{Path, PathBuf}; - use rustls::{RootCertStore, Certificate, TLSError, ServerCertVerified}; - use webpki::DNSNameRef; - use crate::error::{ConnectError, InternalConnectError}; +pub async fn connect_dev( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::devrpc::dev_client::DevClient::with_interceptor(channel, interceptor); + Ok(client) +} - pub(crate) async fn config(path: impl AsRef + Into) -> Result { - let mut tls_config = rustls::ClientConfig::new(); - tls_config.dangerous().set_certificate_verifier(std::sync::Arc::new(CertVerifier::load(path).await?)); - tls_config.set_protocols(&["h2".into()]); - Ok(tonic::transport::ClientTlsConfig::new() - .rustls_client_config(tls_config)) - } +pub async fn connect_invoices( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::invoicesrpc::invoices_client::InvoicesClient::with_interceptor(channel, interceptor); + Ok(client) +} - pub(crate) struct CertVerifier { - certs: Vec> - } +pub async fn connect_lightning( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::lnrpc::lightning_client::LightningClient::with_interceptor(channel, interceptor); + Ok(client) +} + +pub async fn connect_neutrino( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::neutrinorpc::neutrino_kit_client::NeutrinoKitClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) +} + +pub async fn connect_peers( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::peersrpc::peers_client::PeersClient::with_interceptor(channel, interceptor); + Ok(client) +} + +pub async fn connect_router( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::routerrpc::router_client::RouterClient::with_interceptor(channel, interceptor); + Ok(client) +} + +pub async fn connect_signer( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::signrpc::signer_client::SignerClient::with_interceptor(channel, interceptor); + Ok(client) +} + +pub async fn connect_versioner( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::verrpc::versioner_client::VersionerClient::with_interceptor(channel, interceptor); + Ok(client) +} + +pub async fn connect_wallet( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::walletrpc::wallet_kit_client::WalletKitClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) +} - impl CertVerifier { - pub(crate) async fn load(path: impl AsRef + Into) -> Result { - let contents = try_map_err!(tokio::fs::read(&path).await, - |error| InternalConnectError::ReadFile { file: path.into(), error }); - let mut reader = &*contents; +pub async fn connect_watchtower( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = crate::watchtowerrpc::watchtower_client::WatchtowerClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) +} - let certs = try_map_err!(rustls_pemfile::certs(&mut reader), - |error| InternalConnectError::ParseCert { file: path.into(), error }); +pub async fn connect_wtc( + lnd_address: String, + lnd_tls_cert_path: String, + lnd_macaroon_path: String, +) -> Result> { + let channel = get_channel(lnd_address, lnd_tls_cert_path).await?; + let interceptor = get_macaroon_interceptor(lnd_macaroon_path).await?; + let client = + crate::wtclientrpc::watchtower_client_client::WatchtowerClientClient::with_interceptor( + channel, + interceptor, + ); + Ok(client) +} - #[cfg(feature = "tracing")] { - tracing::debug!("Certificates loaded (Count: {})", certs.len()); +#[derive(Clone)] +pub struct MyChannel { + uri: Uri, + client: MyClient, +} + +#[derive(Clone)] +enum MyClient { + ClearText(Client), + Tls(Client, BoxBody>), +} + +impl MyChannel { + pub async fn new(certificate: Option>, uri: Uri) -> Result> { + let mut http = HttpConnector::new(); + http.enforce_http(false); + let client = match certificate { + None => MyClient::ClearText(Client::builder().http2_only(true).build(http)), + Some(pem) => { + let ca = X509::from_pem(&pem[..])?; + let mut connector = SslConnector::builder(SslMethod::tls())?; + connector.cert_store_mut().add_cert(ca)?; + connector.set_alpn_protos(ALPN_H2_WIRE)?; + let mut https = HttpsConnector::with_connector(http, connector)?; + https.set_callback(|c, _| { + c.set_verify_hostname(false); + Ok(()) + }); + MyClient::Tls(Client::builder().http2_only(true).build(https)) } + }; - Ok(CertVerifier { - certs: certs, - }) - } + Ok(Self { client, uri }) } +} - impl rustls::ServerCertVerifier for CertVerifier { - fn verify_server_cert(&self, _roots: &RootCertStore, presented_certs: &[Certificate], _dns_name: DNSNameRef<'_>, _ocsp_response: &[u8]) -> Result { - - if self.certs.len() != presented_certs.len() { - return Err(TLSError::General(format!("Mismatched number of certificates (Expected: {}, Presented: {})", self.certs.len(), presented_certs.len()))); - } - - for (c, p) in self.certs.iter().zip(presented_certs.iter()) { - if *p.0 != **c { - return Err(TLSError::General(format!("Server certificates do not match ours"))); - } else { - #[cfg(feature = "tracing")] { - tracing::trace!("Confirmed certificate match"); - } - } - } +impl Service> for MyChannel { + type Response = Response; + type Error = hyper::Error; + type Future = ResponseFuture; + + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Ok(()).into() + } - Ok(ServerCertVerified::assertion()) + fn call(&mut self, mut req: Request) -> Self::Future { + let uri = Uri::builder() + .scheme(self.uri.scheme().unwrap().clone()) + .authority(self.uri.authority().unwrap().clone()) + .path_and_query(req.uri().path_and_query().unwrap().clone()) + .build() + .unwrap(); + *req.uri_mut() = uri; + match &self.client { + MyClient::ClearText(client) => client.request(req), + MyClient::Tls(client) => client.request(req), } } } diff --git a/vendor/autopilotrpc/autopilot.proto b/vendor/autopilotrpc/autopilot.proto new file mode 100644 index 0000000..67d0f9e --- /dev/null +++ b/vendor/autopilotrpc/autopilot.proto @@ -0,0 +1,80 @@ +syntax = "proto3"; + +package autopilotrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/autopilotrpc"; + +// Autopilot is a service that can be used to get information about the current +// state of the daemon's autopilot agent, and also supply it with information +// that can be used when deciding where to open channels. +service Autopilot { + /* + Status returns whether the daemon's autopilot agent is active. + */ + rpc Status (StatusRequest) returns (StatusResponse); + + /* + ModifyStatus is used to modify the status of the autopilot agent, like + enabling or disabling it. + */ + rpc ModifyStatus (ModifyStatusRequest) returns (ModifyStatusResponse); + + /* + QueryScores queries all available autopilot heuristics, in addition to any + active combination of these heruristics, for the scores they would give to + the given nodes. + */ + rpc QueryScores (QueryScoresRequest) returns (QueryScoresResponse); + + /* + SetScores attempts to set the scores used by the running autopilot agent, + if the external scoring heuristic is enabled. + */ + rpc SetScores (SetScoresRequest) returns (SetScoresResponse); +} + +message StatusRequest { +} + +message StatusResponse { + // Indicates whether the autopilot is active or not. + bool active = 1; +} + +message ModifyStatusRequest { + // Whether the autopilot agent should be enabled or not. + bool enable = 1; +} + +message ModifyStatusResponse { +} + +message QueryScoresRequest { + repeated string pubkeys = 1; + + // If set, we will ignore the local channel state when calculating scores. + bool ignore_local_state = 2; +} + +message QueryScoresResponse { + message HeuristicResult { + string heuristic = 1; + map scores = 2; + } + + repeated HeuristicResult results = 1; +} + +message SetScoresRequest { + // The name of the heuristic to provide scores to. + string heuristic = 1; + + /* + A map from hex-encoded public keys to scores. Scores must be in the range + [0.0, 1.0]. + */ + map scores = 2; +} + +message SetScoresResponse { +} diff --git a/vendor/chainrpc/chainnotifier.proto b/vendor/chainrpc/chainnotifier.proto new file mode 100644 index 0000000..4045d81 --- /dev/null +++ b/vendor/chainrpc/chainnotifier.proto @@ -0,0 +1,188 @@ +syntax = "proto3"; + +package chainrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/chainrpc"; + +// ChainNotifier is a service that can be used to get information about the +// chain backend by registering notifiers for chain events. +service ChainNotifier { + /* + RegisterConfirmationsNtfn is a synchronous response-streaming RPC that + registers an intent for a client to be notified once a confirmation request + has reached its required number of confirmations on-chain. + + A confirmation request must have a valid output script. It is also possible + to give a transaction ID. If the transaction ID is not set, a notification + is sent once the output script confirms. If the transaction ID is also set, + a notification is sent once the output script confirms in the given + transaction. + */ + rpc RegisterConfirmationsNtfn (ConfRequest) returns (stream ConfEvent); + + /* + RegisterSpendNtfn is a synchronous response-streaming RPC that registers an + intent for a client to be notification once a spend request has been spent + by a transaction that has confirmed on-chain. + + A client can specify whether the spend request should be for a particular + outpoint or for an output script by specifying a zero outpoint. + */ + rpc RegisterSpendNtfn (SpendRequest) returns (stream SpendEvent); + + /* + RegisterBlockEpochNtfn is a synchronous response-streaming RPC that + registers an intent for a client to be notified of blocks in the chain. The + stream will return a hash and height tuple of a block for each new/stale + block in the chain. It is the client's responsibility to determine whether + the tuple returned is for a new or stale block in the chain. + + A client can also request a historical backlog of blocks from a particular + point. This allows clients to be idempotent by ensuring that they do not + missing processing a single block within the chain. + */ + rpc RegisterBlockEpochNtfn (BlockEpoch) returns (stream BlockEpoch); +} + +message ConfRequest { + /* + The transaction hash for which we should request a confirmation notification + for. If set to a hash of all zeros, then the confirmation notification will + be requested for the script instead. + */ + bytes txid = 1; + + /* + An output script within a transaction with the hash above which will be used + by light clients to match block filters. If the transaction hash is set to a + hash of all zeros, then a confirmation notification will be requested for + this script instead. + */ + bytes script = 2; + + /* + The number of desired confirmations the transaction/output script should + reach before dispatching a confirmation notification. + */ + uint32 num_confs = 3; + + /* + The earliest height in the chain for which the transaction/output script + could have been included in a block. This should in most cases be set to the + broadcast height of the transaction/output script. + */ + uint32 height_hint = 4; +} + +message ConfDetails { + // The raw bytes of the confirmed transaction. + bytes raw_tx = 1; + + // The hash of the block in which the confirmed transaction was included in. + bytes block_hash = 2; + + // The height of the block in which the confirmed transaction was included + // in. + uint32 block_height = 3; + + // The index of the confirmed transaction within the transaction. + uint32 tx_index = 4; +} + +message Reorg { + // TODO(wilmer): need to know how the client will use this first. +} + +message ConfEvent { + oneof event { + /* + An event that includes the confirmation details of the request + (txid/ouput script). + */ + ConfDetails conf = 1; + + /* + An event send when the transaction of the request is reorged out of the + chain. + */ + Reorg reorg = 2; + } +} + +message Outpoint { + // The hash of the transaction. + bytes hash = 1; + + // The index of the output within the transaction. + uint32 index = 2; +} + +message SpendRequest { + /* + The outpoint for which we should request a spend notification for. If set to + a zero outpoint, then the spend notification will be requested for the + script instead. A zero or nil outpoint is not supported for Taproot spends + because the output script cannot reliably be computed from the witness alone + and the spent output script is not always available in the rescan context. + So an outpoint must _always_ be specified when registering a spend + notification for a Taproot output. + */ + Outpoint outpoint = 1; + + /* + The output script for the outpoint above. This will be used by light clients + to match block filters. If the outpoint is set to a zero outpoint, then a + spend notification will be requested for this script instead. + */ + bytes script = 2; + + /* + The earliest height in the chain for which the outpoint/output script could + have been spent. This should in most cases be set to the broadcast height of + the outpoint/output script. + */ + uint32 height_hint = 3; + + // TODO(wilmer): extend to support num confs on spending tx. +} + +message SpendDetails { + // The outpoint was that spent. + Outpoint spending_outpoint = 1; + + // The raw bytes of the spending transaction. + bytes raw_spending_tx = 2; + + // The hash of the spending transaction. + bytes spending_tx_hash = 3; + + // The input of the spending transaction that fulfilled the spend request. + uint32 spending_input_index = 4; + + // The height at which the spending transaction was included in a block. + uint32 spending_height = 5; +} + +message SpendEvent { + oneof event { + /* + An event that includes the details of the spending transaction of the + request (outpoint/output script). + */ + SpendDetails spend = 1; + + /* + An event sent when the spending transaction of the request was + reorged out of the chain. + */ + Reorg reorg = 2; + } +} + +message BlockEpoch { + // The hash of the block. + bytes hash = 1; + + // The height of the block. + uint32 height = 2; +} diff --git a/vendor/devrpc/dev.proto b/vendor/devrpc/dev.proto new file mode 100644 index 0000000..50ed70f --- /dev/null +++ b/vendor/devrpc/dev.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +import "lightning.proto"; + +package devrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/devrpc"; + +service Dev { + /* + ImportGraph imports a ChannelGraph into the graph database. Should only be + used for development. + */ + rpc ImportGraph (lnrpc.ChannelGraph) returns (ImportGraphResponse); +} + +message ImportGraphResponse { +} diff --git a/vendor/invoicesrpc/invoices.proto b/vendor/invoicesrpc/invoices.proto new file mode 100644 index 0000000..f98c64a --- /dev/null +++ b/vendor/invoicesrpc/invoices.proto @@ -0,0 +1,175 @@ +syntax = "proto3"; + +import "lightning.proto"; + +package invoicesrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/invoicesrpc"; + +// Invoices is a service that can be used to create, accept, settle and cancel +// invoices. +service Invoices { + /* + SubscribeSingleInvoice returns a uni-directional stream (server -> client) + to notify the client of state transitions of the specified invoice. + Initially the current invoice state is always sent out. + */ + rpc SubscribeSingleInvoice (SubscribeSingleInvoiceRequest) + returns (stream lnrpc.Invoice); + + /* + CancelInvoice cancels a currently open invoice. If the invoice is already + canceled, this call will succeed. If the invoice is already settled, it will + fail. + */ + rpc CancelInvoice (CancelInvoiceMsg) returns (CancelInvoiceResp); + + /* + AddHoldInvoice creates a hold invoice. It ties the invoice to the hash + supplied in the request. + */ + rpc AddHoldInvoice (AddHoldInvoiceRequest) returns (AddHoldInvoiceResp); + + /* + SettleInvoice settles an accepted invoice. If the invoice is already + settled, this call will succeed. + */ + rpc SettleInvoice (SettleInvoiceMsg) returns (SettleInvoiceResp); + + /* + LookupInvoiceV2 attempts to look up at invoice. An invoice can be refrenced + using either its payment hash, payment address, or set ID. + */ + rpc LookupInvoiceV2 (LookupInvoiceMsg) returns (lnrpc.Invoice); +} + +message CancelInvoiceMsg { + // Hash corresponding to the (hold) invoice to cancel. When using + // REST, this field must be encoded as base64. + bytes payment_hash = 1; +} +message CancelInvoiceResp { +} + +message AddHoldInvoiceRequest { + /* + An optional memo to attach along with the invoice. Used for record keeping + purposes for the invoice's creator, and will also be set in the description + field of the encoded payment request if the description_hash field is not + being used. + */ + string memo = 1; + + // The hash of the preimage + bytes hash = 2; + + /* + The value of this invoice in satoshis + + The fields value and value_msat are mutually exclusive. + */ + int64 value = 3; + + /* + The value of this invoice in millisatoshis + + The fields value and value_msat are mutually exclusive. + */ + int64 value_msat = 10; + + /* + Hash (SHA-256) of a description of the payment. Used if the description of + payment (memo) is too long to naturally fit within the description field + of an encoded payment request. + */ + bytes description_hash = 4; + + // Payment request expiry time in seconds. Default is 3600 (1 hour). + int64 expiry = 5; + + // Fallback on-chain address. + string fallback_addr = 6; + + // Delta to use for the time-lock of the CLTV extended to the final hop. + uint64 cltv_expiry = 7; + + /* + Route hints that can each be individually used to assist in reaching the + invoice's destination. + */ + repeated lnrpc.RouteHint route_hints = 8; + + // Whether this invoice should include routing hints for private channels. + bool private = 9; +} + +message AddHoldInvoiceResp { + /* + A bare-bones invoice for a payment within the Lightning Network. With the + details of the invoice, the sender has all the data necessary to send a + payment to the recipient. + */ + string payment_request = 1; + + /* + The "add" index of this invoice. Each newly created invoice will increment + this index making it monotonically increasing. Callers to the + SubscribeInvoices call can use this to instantly get notified of all added + invoices with an add_index greater than this one. + */ + uint64 add_index = 2; + + /* + The payment address of the generated invoice. This value should be used + in all payments for this invoice as we require it for end to end + security. + */ + bytes payment_addr = 3; +} + +message SettleInvoiceMsg { + // Externally discovered pre-image that should be used to settle the hold + // invoice. + bytes preimage = 1; +} + +message SettleInvoiceResp { +} + +message SubscribeSingleInvoiceRequest { + reserved 1; + + // Hash corresponding to the (hold) invoice to subscribe to. When using + // REST, this field must be encoded as base64url. + bytes r_hash = 2; +} + +enum LookupModifier { + // The default look up modifier, no look up behavior is changed. + DEFAULT = 0; + + /* + Indicates that when a look up is done based on a set_id, then only that set + of HTLCs related to that set ID should be returned. + */ + HTLC_SET_ONLY = 1; + + /* + Indicates that when a look up is done using a payment_addr, then no HTLCs + related to the payment_addr should be returned. This is useful when one + wants to be able to obtain the set of associated setIDs with a given + invoice, then look up the sub-invoices "projected" by that set ID. + */ + HTLC_SET_BLANK = 2; +} + +message LookupInvoiceMsg { + oneof invoice_ref { + // When using REST, this field must be encoded as base64. + bytes payment_hash = 1; + bytes payment_addr = 2; + bytes set_id = 3; + } + + LookupModifier lookup_modifier = 4; +} diff --git a/vendor/lightning.proto b/vendor/lightning.proto index 7e28702..0476d21 100644 --- a/vendor/lightning.proto +++ b/vendor/lightning.proto @@ -686,7 +686,11 @@ message Transaction { // A label that was optionally set on transaction broadcast. string label = 10; + + // PreviousOutpoints/Inputs of this transaction. + repeated PreviousOutPoint previous_outpoints = 12; } + message GetTransactionsRequest { /* The height from which to list transactions, inclusive. If this value is @@ -975,6 +979,13 @@ message ChannelAcceptResponse { The number of confirmations we require before we consider the channel open. */ uint32 min_accept_depth = 10; + + /* + Whether the responder wants this to be a zero-conf channel. This will fail + if either side does not have the scid-alias feature bit set. The minimum + depth field must be zero if this is true. + */ + bool zero_conf = 11; } message ChannelPoint { @@ -1007,6 +1018,15 @@ message OutPoint { uint32 output_index = 3; } +message PreviousOutPoint { + // The outpoint in format txid:n. + string outpoint = 1; + + // Denotes if the outpoint is controlled by the internal wallet. + // The flag will only detect p2wkh, np2wkh and p2tr inputs as its own. + bool is_our_output = 2; +} + message LightningAddress { // The identity pubkey of the Lightning node. string pubkey = 1; @@ -2101,6 +2121,17 @@ message OpenChannelRequest { the remote peer supports explicit channel negotiation. */ CommitmentType commitment_type = 18; + + /* + If this is true, then a zero-conf channel open will be attempted. + */ + bool zero_conf = 19; + + /* + If this is true, then an option-scid-alias channel-type open will be + attempted. + */ + bool scid_alias = 20; } message OpenStatusUpdate { oneof update { @@ -2554,6 +2585,9 @@ message WalletBalanceResponse { // other usage. int64 locked_balance = 5; + // The amount of reserve required. + int64 reserved_balance_anchor_chan = 6; + // A mapping of each wallet account's name to its balance. map account_balance = 4; } @@ -4382,7 +4416,8 @@ message RPCMessage { /* The full canonical gRPC name of the message type (in the format - .TypeName, for example lnrpc.GetInfoRequest). + .TypeName, for example lnrpc.GetInfoRequest). In case of an + error being returned from lnd, this simply contains the string "error". */ string type_name = 3; @@ -4391,6 +4426,13 @@ message RPCMessage { format. */ bytes serialized = 4; + + /* + Indicates that the response from lnd was an error, not a gRPC response. If + this is set to true then the type_name contains the string "error" and + serialized contains the error string. + */ + bool is_error = 5; } message RPCMiddlewareResponse { @@ -4467,18 +4509,16 @@ message InterceptFeedback { string error = 1; /* - A boolean indicating that the gRPC response should be replaced/overwritten. - As its name suggests, this can only be used as a feedback to an intercepted - response RPC message and is ignored for feedback on any other message. This - boolean is needed because in protobuf an empty message is serialized as a - 0-length or nil byte slice and we wouldn't be able to distinguish between + A boolean indicating that the gRPC message should be replaced/overwritten. + This boolean is needed because in protobuf an empty message is serialized as + a 0-length or nil byte slice and we wouldn't be able to distinguish between an empty replacement message and the "don't replace anything" case. */ bool replace_response = 2; /* If the replace_response field is set to true, this field must contain the - binary serialized gRPC response message in the protobuf format. + binary serialized gRPC message in the protobuf format. */ bytes replacement_serialized = 3; } diff --git a/vendor/lnclipb/lncli.proto b/vendor/lnclipb/lncli.proto new file mode 100644 index 0000000..981dc25 --- /dev/null +++ b/vendor/lnclipb/lncli.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +import "verrpc/verrpc.proto"; + +package lnclipb; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/lnclipb"; + +message VersionResponse { + // The version information for lncli. + verrpc.Version lncli = 1; + + // The version information for lnd. + verrpc.Version lnd = 2; +}; diff --git a/vendor/neutrinorpc/neutrino.proto b/vendor/neutrinorpc/neutrino.proto new file mode 100644 index 0000000..3887148 --- /dev/null +++ b/vendor/neutrinorpc/neutrino.proto @@ -0,0 +1,210 @@ +syntax = "proto3"; + +package neutrinorpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/neutrinorpc"; + +// NeutrinoKit is a service that can be used to get information about the +// current state of the neutrino instance, fetch blocks and add/remove peers. +service NeutrinoKit { + /* + Status returns the status of the light client neutrino instance, + along with height and hash of the best block, and a list of connected + peers. + */ + rpc Status (StatusRequest) returns (StatusResponse); + + /* + AddPeer adds a new peer that has already been connected to the server. + */ + rpc AddPeer (AddPeerRequest) returns (AddPeerResponse); + + /* + DisconnectPeer disconnects a peer by target address. Both outbound and + inbound nodes will be searched for the target node. An error message will + be returned if the peer was not found. + */ + rpc DisconnectPeer (DisconnectPeerRequest) returns (DisconnectPeerResponse); + + /* + IsBanned returns true if the peer is banned, otherwise false. + */ + rpc IsBanned (IsBannedRequest) returns (IsBannedResponse); + + /* + GetBlockHeader returns a block header with a particular block hash. + */ + rpc GetBlockHeader (GetBlockHeaderRequest) returns (GetBlockHeaderResponse); + + /* + GetBlock returns a block with a particular block hash. + */ + rpc GetBlock (GetBlockRequest) returns (GetBlockResponse); + + /* + GetCFilter returns a compact filter from a block. + */ + rpc GetCFilter (GetCFilterRequest) returns (GetCFilterResponse); +} + +message StatusRequest { +} + +message StatusResponse { + // Indicates whether the neutrino backend is active or not. + bool active = 1; + + // Is fully synced. + bool synced = 2; + + // Best block height. + int32 block_height = 3; + + // Best block hash. + string block_hash = 4; + + // Connected peers. + repeated string peers = 5; +} + +message AddPeerRequest { + // Peer to add. + string peer_addrs = 1; +} + +message AddPeerResponse { +} + +message DisconnectPeerRequest { + // Peer to disconnect. + string peer_addrs = 1; +} + +message DisconnectPeerResponse { +} + +message IsBannedRequest { + // Peer to lookup. + string peer_addrs = 1; +} + +message IsBannedResponse { + bool banned = 1; +} + +message GetBlockHeaderRequest { + // Block hash in hex notation. + string hash = 1; +} + +message GetBlockHeaderResponse { + // The block hash (same as provided). + string hash = 1; + + // The number of confirmations. + int64 confirmations = 2; + + // The block size excluding witness data. + int64 stripped_size = 3; + + // The block size (bytes). + int64 size = 4; + + // The block weight as defined in BIP 141. + int64 weight = 5; + + // The block height or index. + int32 height = 6; + + // The block version. + int32 version = 7; + + // The block version. + string version_hex = 8; + + // The merkle root. + string merkleroot = 9; + + // The block time in seconds since epoch (Jan 1 1970 GMT). + int64 time = 10; + + // The nonce. + uint32 nonce = 11; + + // The bits in hex notation. + string bits = 12; + + // The number of transactions in the block. + int32 ntx = 13; + + // The hash of the previous block. + string previous_block_hash = 14; + + // The raw hex of the block. + bytes raw_hex = 15; +} + +message GetBlockRequest { + // Block hash in hex notation. + string hash = 1; +} + +message GetBlockResponse { + // The block hash (same as provided). + string hash = 1; + + // The number of confirmations. + int64 confirmations = 2; + + // The block size excluding witness data. + int64 stripped_size = 3; + + // The block size (bytes). + int64 size = 4; + + // The block weight as defined in BIP 141. + int64 weight = 5; + + // The block height or index. + int32 height = 6; + + // The block version. + int32 version = 7; + + // The block version. + string version_hex = 8; + + // The merkle root. + string merkleroot = 9; + + // List of transaction ids. + repeated string tx = 10; + + // The block time in seconds since epoch (Jan 1 1970 GMT). + int64 time = 11; + + // The nonce. + uint32 nonce = 12; + + // The bits in hex notation. + string bits = 13; + + // The number of transactions in the block. + int32 ntx = 14; + + // The hash of the previous block. + string previous_block_hash = 15; + + // The raw hex of the block. + bytes raw_hex = 16; +} + +message GetCFilterRequest { + // Block hash in hex notation. + string hash = 1; +} + +message GetCFilterResponse { + // GCS filter. + bytes filter = 1; +} \ No newline at end of file diff --git a/vendor/peersrpc/peers.proto b/vendor/peersrpc/peers.proto new file mode 100644 index 0000000..7af9f0a --- /dev/null +++ b/vendor/peersrpc/peers.proto @@ -0,0 +1,94 @@ +syntax = "proto3"; + +import "lightning.proto"; + +package peersrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/peersrpc"; + +// Peers is a service that can be used to get information and interact +// with the other nodes of the newtwork. +service Peers { + /* lncli: peers updatenodeannouncement + UpdateNodeAnnouncement allows the caller to update the node parameters + and broadcasts a new version of the node announcement to its peers. + */ + rpc UpdateNodeAnnouncement (NodeAnnouncementUpdateRequest) + returns (NodeAnnouncementUpdateResponse); +} + +// UpdateAction is used to determine the kind of action we are referring to. +enum UpdateAction { + // ADD indicates this is an "insertion" kind of action. + ADD = 0; + + // REMOVE indicates this is a "deletion" kind of action. + REMOVE = 1; +} + +enum FeatureSet { + /* + SET_INIT identifies features that should be sent in an Init message to + a remote peer. + */ + SET_INIT = 0; + + /* + SET_LEGACY_GLOBAL identifies features that should be set in the legacy + GlobalFeatures field of an Init message, which maintains backwards + compatibility with nodes that haven't implemented flat features. + */ + SET_LEGACY_GLOBAL = 1; + + /* + SET_NODE_ANN identifies features that should be advertised on node + announcements. + */ + SET_NODE_ANN = 2; + + /* + SET_INVOICE identifies features that should be advertised on invoices + generated by the daemon. + */ + SET_INVOICE = 3; + + /* + SET_INVOICE_AMP identifies the features that should be advertised on + AMP invoices generated by the daemon. + */ + SET_INVOICE_AMP = 4; +} + +message UpdateAddressAction { + // Determines the kind of action. + UpdateAction action = 1; + + // The address used to apply the update action. + string address = 2; +} + +message UpdateFeatureAction { + // Determines the kind of action. + UpdateAction action = 1; + + // The feature bit used to apply the update action. + lnrpc.FeatureBit feature_bit = 2; +} + +message NodeAnnouncementUpdateRequest { + // Set of changes for the features that the node supports. + repeated UpdateFeatureAction feature_updates = 1; + + // Color is the node's color in hex code format. + string color = 2; + + // Alias or nick name of the node. + string alias = 3; + + // Set of changes for the node's known addresses. + repeated UpdateAddressAction address_updates = 4; +} + +message NodeAnnouncementUpdateResponse { + repeated lnrpc.Op ops = 1; +} diff --git a/vendor/routerrpc/router.proto b/vendor/routerrpc/router.proto new file mode 100644 index 0000000..04812b4 --- /dev/null +++ b/vendor/routerrpc/router.proto @@ -0,0 +1,834 @@ +syntax = "proto3"; + +import "lightning.proto"; + +package routerrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/routerrpc"; + +// Router is a service that offers advanced interaction with the router +// subsystem of the daemon. +service Router { + /* + SendPaymentV2 attempts to route a payment described by the passed + PaymentRequest to the final destination. The call returns a stream of + payment updates. + */ + rpc SendPaymentV2 (SendPaymentRequest) returns (stream lnrpc.Payment); + + /* + TrackPaymentV2 returns an update stream for the payment identified by the + payment hash. + */ + rpc TrackPaymentV2 (TrackPaymentRequest) returns (stream lnrpc.Payment); + + /* + EstimateRouteFee allows callers to obtain a lower bound w.r.t how much it + may cost to send an HTLC to the target end destination. + */ + rpc EstimateRouteFee (RouteFeeRequest) returns (RouteFeeResponse); + + /* + Deprecated, use SendToRouteV2. SendToRoute attempts to make a payment via + the specified route. This method differs from SendPayment in that it + allows users to specify a full route manually. This can be used for + things like rebalancing, and atomic swaps. It differs from the newer + SendToRouteV2 in that it doesn't return the full HTLC information. + */ + rpc SendToRoute (SendToRouteRequest) returns (SendToRouteResponse) { + option deprecated = true; + } + + /* + SendToRouteV2 attempts to make a payment via the specified route. This + method differs from SendPayment in that it allows users to specify a full + route manually. This can be used for things like rebalancing, and atomic + swaps. + */ + rpc SendToRouteV2 (SendToRouteRequest) returns (lnrpc.HTLCAttempt); + + /* + ResetMissionControl clears all mission control state and starts with a clean + slate. + */ + rpc ResetMissionControl (ResetMissionControlRequest) + returns (ResetMissionControlResponse); + + /* + QueryMissionControl exposes the internal mission control state to callers. + It is a development feature. + */ + rpc QueryMissionControl (QueryMissionControlRequest) + returns (QueryMissionControlResponse); + + /* + XImportMissionControl is an experimental API that imports the state provided + to the internal mission control's state, using all results which are more + recent than our existing values. These values will only be imported + in-memory, and will not be persisted across restarts. + */ + rpc XImportMissionControl (XImportMissionControlRequest) + returns (XImportMissionControlResponse); + + /* + GetMissionControlConfig returns mission control's current config. + */ + rpc GetMissionControlConfig (GetMissionControlConfigRequest) + returns (GetMissionControlConfigResponse); + + /* + SetMissionControlConfig will set mission control's config, if the config + provided is valid. + */ + rpc SetMissionControlConfig (SetMissionControlConfigRequest) + returns (SetMissionControlConfigResponse); + + /* + QueryProbability returns the current success probability estimate for a + given node pair and amount. + */ + rpc QueryProbability (QueryProbabilityRequest) + returns (QueryProbabilityResponse); + + /* + BuildRoute builds a fully specified route based on a list of hop public + keys. It retrieves the relevant channel policies from the graph in order to + calculate the correct fees and time locks. + */ + rpc BuildRoute (BuildRouteRequest) returns (BuildRouteResponse); + + /* + SubscribeHtlcEvents creates a uni-directional stream from the server to + the client which delivers a stream of htlc events. + */ + rpc SubscribeHtlcEvents (SubscribeHtlcEventsRequest) + returns (stream HtlcEvent); + + /* + Deprecated, use SendPaymentV2. SendPayment attempts to route a payment + described by the passed PaymentRequest to the final destination. The call + returns a stream of payment status updates. + */ + rpc SendPayment (SendPaymentRequest) returns (stream PaymentStatus) { + option deprecated = true; + } + + /* + Deprecated, use TrackPaymentV2. TrackPayment returns an update stream for + the payment identified by the payment hash. + */ + rpc TrackPayment (TrackPaymentRequest) returns (stream PaymentStatus) { + option deprecated = true; + } + + /** + HtlcInterceptor dispatches a bi-directional streaming RPC in which + Forwarded HTLC requests are sent to the client and the client responds with + a boolean that tells LND if this htlc should be intercepted. + In case of interception, the htlc can be either settled, cancelled or + resumed later by using the ResolveHoldForward endpoint. + */ + rpc HtlcInterceptor (stream ForwardHtlcInterceptResponse) + returns (stream ForwardHtlcInterceptRequest); + + /* + UpdateChanStatus attempts to manually set the state of a channel + (enabled, disabled, or auto). A manual "disable" request will cause the + channel to stay disabled until a subsequent manual request of either + "enable" or "auto". + */ + rpc UpdateChanStatus (UpdateChanStatusRequest) + returns (UpdateChanStatusResponse); +} + +message SendPaymentRequest { + // The identity pubkey of the payment recipient + bytes dest = 1; + + /* + Number of satoshis to send. + + The fields amt and amt_msat are mutually exclusive. + */ + int64 amt = 2; + + /* + Number of millisatoshis to send. + + The fields amt and amt_msat are mutually exclusive. + */ + int64 amt_msat = 12; + + // The hash to use within the payment's HTLC + bytes payment_hash = 3; + + /* + The CLTV delta from the current height that should be used to set the + timelock for the final hop. + */ + int32 final_cltv_delta = 4; + + // An optional payment addr to be included within the last hop of the route. + bytes payment_addr = 20; + + /* + A bare-bones invoice for a payment within the Lightning Network. With the + details of the invoice, the sender has all the data necessary to send a + payment to the recipient. The amount in the payment request may be zero. In + that case it is required to set the amt field as well. If no payment request + is specified, the following fields are required: dest, amt and payment_hash. + */ + string payment_request = 5; + + /* + An upper limit on the amount of time we should spend when attempting to + fulfill the payment. This is expressed in seconds. If we cannot make a + successful payment within this time frame, an error will be returned. + This field must be non-zero. + */ + int32 timeout_seconds = 6; + + /* + The maximum number of satoshis that will be paid as a fee of the payment. + If this field is left to the default value of 0, only zero-fee routes will + be considered. This usually means single hop routes connecting directly to + the destination. To send the payment without a fee limit, use max int here. + + The fields fee_limit_sat and fee_limit_msat are mutually exclusive. + */ + int64 fee_limit_sat = 7; + + /* + The maximum number of millisatoshis that will be paid as a fee of the + payment. If this field is left to the default value of 0, only zero-fee + routes will be considered. This usually means single hop routes connecting + directly to the destination. To send the payment without a fee limit, use + max int here. + + The fields fee_limit_sat and fee_limit_msat are mutually exclusive. + */ + int64 fee_limit_msat = 13; + + /* + Deprecated, use outgoing_chan_ids. The channel id of the channel that must + be taken to the first hop. If zero, any channel may be used (unless + outgoing_chan_ids are set). + */ + uint64 outgoing_chan_id = 8 [jstype = JS_STRING, deprecated = true]; + + /* + The channel ids of the channels are allowed for the first hop. If empty, + any channel may be used. + */ + repeated uint64 outgoing_chan_ids = 19; + + /* + The pubkey of the last hop of the route. If empty, any hop may be used. + */ + bytes last_hop_pubkey = 14; + + /* + An optional maximum total time lock for the route. This should not exceed + lnd's `--max-cltv-expiry` setting. If zero, then the value of + `--max-cltv-expiry` is enforced. + */ + int32 cltv_limit = 9; + + /* + Optional route hints to reach the destination through private channels. + */ + repeated lnrpc.RouteHint route_hints = 10; + + /* + An optional field that can be used to pass an arbitrary set of TLV records + to a peer which understands the new records. This can be used to pass + application specific data during the payment attempt. Record types are + required to be in the custom range >= 65536. When using REST, the values + must be encoded as base64. + */ + map dest_custom_records = 11; + + // If set, circular payments to self are permitted. + bool allow_self_payment = 15; + + /* + Features assumed to be supported by the final node. All transitive feature + dependencies must also be set properly. For a given feature bit pair, either + optional or remote may be set, but not both. If this field is nil or empty, + the router will try to load destination features from the graph as a + fallback. + */ + repeated lnrpc.FeatureBit dest_features = 16; + + /* + The maximum number of partial payments that may be use to complete the full + amount. + */ + uint32 max_parts = 17; + + /* + If set, only the final payment update is streamed back. Intermediate updates + that show which htlcs are still in flight are suppressed. + */ + bool no_inflight_updates = 18; + + /* + The largest payment split that should be attempted when making a payment if + splitting is necessary. Setting this value will effectively cause lnd to + split more aggressively, vs only when it thinks it needs to. Note that this + value is in milli-satoshis. + */ + uint64 max_shard_size_msat = 21; + + /* + If set, an AMP-payment will be attempted. + */ + bool amp = 22; + + /* + The time preference for this payment. Set to -1 to optimize for fees + only, to 1 to optimize for reliability only or a value inbetween for a mix. + */ + double time_pref = 23; +} + +message TrackPaymentRequest { + // The hash of the payment to look up. + bytes payment_hash = 1; + + /* + If set, only the final payment update is streamed back. Intermediate updates + that show which htlcs are still in flight are suppressed. + */ + bool no_inflight_updates = 2; +} + +message RouteFeeRequest { + /* + The destination once wishes to obtain a routing fee quote to. + */ + bytes dest = 1; + + /* + The amount one wishes to send to the target destination. + */ + int64 amt_sat = 2; +} + +message RouteFeeResponse { + /* + A lower bound of the estimated fee to the target destination within the + network, expressed in milli-satoshis. + */ + int64 routing_fee_msat = 1; + + /* + An estimate of the worst case time delay that can occur. Note that callers + will still need to factor in the final CLTV delta of the last hop into this + value. + */ + int64 time_lock_delay = 2; +} + +message SendToRouteRequest { + // The payment hash to use for the HTLC. + bytes payment_hash = 1; + + // Route that should be used to attempt to complete the payment. + lnrpc.Route route = 2; + + /* + Whether the payment should be marked as failed when a temporary error is + returned from the given route. Set it to true so the payment won't be + failed unless a terminal error is occurred, such as payment timeout, no + routes, incorrect payment details, or insufficient funds. + */ + bool skip_temp_err = 3; +} + +message SendToRouteResponse { + // The preimage obtained by making the payment. + bytes preimage = 1; + + // The failure message in case the payment failed. + lnrpc.Failure failure = 2; +} + +message ResetMissionControlRequest { +} + +message ResetMissionControlResponse { +} + +message QueryMissionControlRequest { +} + +// QueryMissionControlResponse contains mission control state. +message QueryMissionControlResponse { + reserved 1; + + // Node pair-level mission control state. + repeated PairHistory pairs = 2; +} + +message XImportMissionControlRequest { + // Node pair-level mission control state to be imported. + repeated PairHistory pairs = 1; + + // Whether to force override MC pair history. Note that even with force + // override the failure pair is imported before the success pair and both + // still clamp existing failure/success amounts. + bool force = 2; +} + +message XImportMissionControlResponse { +} + +// PairHistory contains the mission control state for a particular node pair. +message PairHistory { + // The source node pubkey of the pair. + bytes node_from = 1; + + // The destination node pubkey of the pair. + bytes node_to = 2; + + reserved 3, 4, 5, 6; + + PairData history = 7; +} + +message PairData { + // Time of last failure. + int64 fail_time = 1; + + /* + Lowest amount that failed to forward rounded to whole sats. This may be + set to zero if the failure is independent of amount. + */ + int64 fail_amt_sat = 2; + + /* + Lowest amount that failed to forward in millisats. This may be + set to zero if the failure is independent of amount. + */ + int64 fail_amt_msat = 4; + + reserved 3; + + // Time of last success. + int64 success_time = 5; + + // Highest amount that we could successfully forward rounded to whole sats. + int64 success_amt_sat = 6; + + // Highest amount that we could successfully forward in millisats. + int64 success_amt_msat = 7; +} + +message GetMissionControlConfigRequest { +} + +message GetMissionControlConfigResponse { + /* + Mission control's currently active config. + */ + MissionControlConfig config = 1; +} + +message SetMissionControlConfigRequest { + /* + The config to set for mission control. Note that all values *must* be set, + because the full config will be applied. + */ + MissionControlConfig config = 1; +} + +message SetMissionControlConfigResponse { +} + +message MissionControlConfig { + /* + The amount of time mission control will take to restore a penalized node + or channel back to 50% success probability, expressed in seconds. Setting + this value to a higher value will penalize failures for longer, making + mission control less likely to route through nodes and channels that we + have previously recorded failures for. + */ + uint64 half_life_seconds = 1; + + /* + The probability of success mission control should assign to hop in a route + where it has no other information available. Higher values will make mission + control more willing to try hops that we have no information about, lower + values will discourage trying these hops. + */ + float hop_probability = 2; + + /* + The importance that mission control should place on historical results, + expressed as a value in [0;1]. Setting this value to 1 will ignore all + historical payments and just use the hop probability to assess the + probability of success for each hop. A zero value ignores hop probability + completely and relies entirely on historical results, unless none are + available. + */ + float weight = 3; + + /* + The maximum number of payment results that mission control will store. + */ + uint32 maximum_payment_results = 4; + + /* + The minimum time that must have passed since the previously recorded failure + before we raise the failure amount. + */ + uint64 minimum_failure_relax_interval = 5; +} + +message QueryProbabilityRequest { + // The source node pubkey of the pair. + bytes from_node = 1; + + // The destination node pubkey of the pair. + bytes to_node = 2; + + // The amount for which to calculate a probability. + int64 amt_msat = 3; +} + +message QueryProbabilityResponse { + // The success probability for the requested pair. + double probability = 1; + + // The historical data for the requested pair. + PairData history = 2; +} + +message BuildRouteRequest { + /* + The amount to send expressed in msat. If set to zero, the minimum routable + amount is used. + */ + int64 amt_msat = 1; + + /* + CLTV delta from the current height that should be used for the timelock + of the final hop + */ + int32 final_cltv_delta = 2; + + /* + The channel id of the channel that must be taken to the first hop. If zero, + any channel may be used. + */ + uint64 outgoing_chan_id = 3 [jstype = JS_STRING]; + + /* + A list of hops that defines the route. This does not include the source hop + pubkey. + */ + repeated bytes hop_pubkeys = 4; + + // An optional payment addr to be included within the last hop of the route. + bytes payment_addr = 5; +} + +message BuildRouteResponse { + /* + Fully specified route that can be used to execute the payment. + */ + lnrpc.Route route = 1; +} + +message SubscribeHtlcEventsRequest { +} + +/* +HtlcEvent contains the htlc event that was processed. These are served on a +best-effort basis; events are not persisted, delivery is not guaranteed +(in the event of a crash in the switch, forward events may be lost) and +some events may be replayed upon restart. Events consumed from this package +should be de-duplicated by the htlc's unique combination of incoming and +outgoing channel id and htlc id. [EXPERIMENTAL] +*/ +message HtlcEvent { + /* + The short channel id that the incoming htlc arrived at our node on. This + value is zero for sends. + */ + uint64 incoming_channel_id = 1; + + /* + The short channel id that the outgoing htlc left our node on. This value + is zero for receives. + */ + uint64 outgoing_channel_id = 2; + + /* + Incoming id is the index of the incoming htlc in the incoming channel. + This value is zero for sends. + */ + uint64 incoming_htlc_id = 3; + + /* + Outgoing id is the index of the outgoing htlc in the outgoing channel. + This value is zero for receives. + */ + uint64 outgoing_htlc_id = 4; + + /* + The time in unix nanoseconds that the event occurred. + */ + uint64 timestamp_ns = 5; + + enum EventType { + UNKNOWN = 0; + SEND = 1; + RECEIVE = 2; + FORWARD = 3; + } + + /* + The event type indicates whether the htlc was part of a send, receive or + forward. + */ + EventType event_type = 6; + + oneof event { + ForwardEvent forward_event = 7; + ForwardFailEvent forward_fail_event = 8; + SettleEvent settle_event = 9; + LinkFailEvent link_fail_event = 10; + } +} + +message HtlcInfo { + // The timelock on the incoming htlc. + uint32 incoming_timelock = 1; + + // The timelock on the outgoing htlc. + uint32 outgoing_timelock = 2; + + // The amount of the incoming htlc. + uint64 incoming_amt_msat = 3; + + // The amount of the outgoing htlc. + uint64 outgoing_amt_msat = 4; +} + +message ForwardEvent { + // Info contains details about the htlc that was forwarded. + HtlcInfo info = 1; +} + +message ForwardFailEvent { +} + +message SettleEvent { + // The revealed preimage. + bytes preimage = 1; +} + +message LinkFailEvent { + // Info contains details about the htlc that we failed. + HtlcInfo info = 1; + + // FailureCode is the BOLT error code for the failure. + lnrpc.Failure.FailureCode wire_failure = 2; + + /* + FailureDetail provides additional information about the reason for the + failure. This detail enriches the information provided by the wire message + and may be 'no detail' if the wire message requires no additional metadata. + */ + FailureDetail failure_detail = 3; + + // A string representation of the link failure. + string failure_string = 4; +} + +enum FailureDetail { + UNKNOWN = 0; + NO_DETAIL = 1; + ONION_DECODE = 2; + LINK_NOT_ELIGIBLE = 3; + ON_CHAIN_TIMEOUT = 4; + HTLC_EXCEEDS_MAX = 5; + INSUFFICIENT_BALANCE = 6; + INCOMPLETE_FORWARD = 7; + HTLC_ADD_FAILED = 8; + FORWARDS_DISABLED = 9; + INVOICE_CANCELED = 10; + INVOICE_UNDERPAID = 11; + INVOICE_EXPIRY_TOO_SOON = 12; + INVOICE_NOT_OPEN = 13; + MPP_INVOICE_TIMEOUT = 14; + ADDRESS_MISMATCH = 15; + SET_TOTAL_MISMATCH = 16; + SET_TOTAL_TOO_LOW = 17; + SET_OVERPAID = 18; + UNKNOWN_INVOICE = 19; + INVALID_KEYSEND = 20; + MPP_IN_PROGRESS = 21; + CIRCULAR_ROUTE = 22; +} + +enum PaymentState { + /* + Payment is still in flight. + */ + IN_FLIGHT = 0; + + /* + Payment completed successfully. + */ + SUCCEEDED = 1; + + /* + There are more routes to try, but the payment timeout was exceeded. + */ + FAILED_TIMEOUT = 2; + + /* + All possible routes were tried and failed permanently. Or were no + routes to the destination at all. + */ + FAILED_NO_ROUTE = 3; + + /* + A non-recoverable error has occurred. + */ + FAILED_ERROR = 4; + + /* + Payment details incorrect (unknown hash, invalid amt or + invalid final cltv delta) + */ + FAILED_INCORRECT_PAYMENT_DETAILS = 5; + + /* + Insufficient local balance. + */ + FAILED_INSUFFICIENT_BALANCE = 6; +} + +message PaymentStatus { + // Current state the payment is in. + PaymentState state = 1; + + /* + The pre-image of the payment when state is SUCCEEDED. + */ + bytes preimage = 2; + + reserved 3; + + /* + The HTLCs made in attempt to settle the payment [EXPERIMENTAL]. + */ + repeated lnrpc.HTLCAttempt htlcs = 4; +} + +message CircuitKey { + /// The id of the channel that the is part of this circuit. + uint64 chan_id = 1; + + /// The index of the incoming htlc in the incoming channel. + uint64 htlc_id = 2; +} + +message ForwardHtlcInterceptRequest { + /* + The key of this forwarded htlc. It defines the incoming channel id and + the index in this channel. + */ + CircuitKey incoming_circuit_key = 1; + + // The incoming htlc amount. + uint64 incoming_amount_msat = 5; + + // The incoming htlc expiry. + uint32 incoming_expiry = 6; + + /* + The htlc payment hash. This value is not guaranteed to be unique per + request. + */ + bytes payment_hash = 2; + + // The requested outgoing channel id for this forwarded htlc. Because of + // non-strict forwarding, this isn't necessarily the channel over which the + // packet will be forwarded eventually. A different channel to the same peer + // may be selected as well. + uint64 outgoing_requested_chan_id = 7; + + // The outgoing htlc amount. + uint64 outgoing_amount_msat = 3; + + // The outgoing htlc expiry. + uint32 outgoing_expiry = 4; + + // Any custom records that were present in the payload. + map custom_records = 8; + + // The onion blob for the next hop + bytes onion_blob = 9; +} + +/** +ForwardHtlcInterceptResponse enables the caller to resolve a previously hold +forward. The caller can choose either to: +- `Resume`: Execute the default behavior (usually forward). +- `Reject`: Fail the htlc backwards. +- `Settle`: Settle this htlc with a given preimage. +*/ +message ForwardHtlcInterceptResponse { + /** + The key of this forwarded htlc. It defines the incoming channel id and + the index in this channel. + */ + CircuitKey incoming_circuit_key = 1; + + // The resolve action for this intercepted htlc. + ResolveHoldForwardAction action = 2; + + // The preimage in case the resolve action is Settle. + bytes preimage = 3; + + // Encrypted failure message in case the resolve action is Fail. + // + // If failure_message is specified, the failure_code field must be set + // to zero. + bytes failure_message = 4; + + // Return the specified failure code in case the resolve action is Fail. The + // message data fields are populated automatically. + // + // If a non-zero failure_code is specified, failure_message must not be set. + // + // For backwards-compatibility reasons, TEMPORARY_CHANNEL_FAILURE is the + // default value for this field. + lnrpc.Failure.FailureCode failure_code = 5; +} + +enum ResolveHoldForwardAction { + SETTLE = 0; + FAIL = 1; + RESUME = 2; +} + +message UpdateChanStatusRequest { + lnrpc.ChannelPoint chan_point = 1; + + ChanStatusAction action = 2; +} + +enum ChanStatusAction { + ENABLE = 0; + DISABLE = 1; + AUTO = 2; +} + +message UpdateChanStatusResponse { +} diff --git a/vendor/signrpc/signer.proto b/vendor/signrpc/signer.proto new file mode 100644 index 0000000..5ea85dd --- /dev/null +++ b/vendor/signrpc/signer.proto @@ -0,0 +1,640 @@ +syntax = "proto3"; + +package signrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/signrpc"; + +// Signer is a service that gives access to the signing functionality of the +// daemon's wallet. +service Signer { + /* + SignOutputRaw is a method that can be used to generated a signature for a + set of inputs/outputs to a transaction. Each request specifies details + concerning how the outputs should be signed, which keys they should be + signed with, and also any optional tweaks. The return value is a fixed + 64-byte signature (the same format as we use on the wire in Lightning). + + If we are unable to sign using the specified keys, then an error will be + returned. + */ + rpc SignOutputRaw (SignReq) returns (SignResp); + + /* + ComputeInputScript generates a complete InputIndex for the passed + transaction with the signature as defined within the passed SignDescriptor. + This method should be capable of generating the proper input script for both + regular p2wkh/p2tr outputs and p2wkh outputs nested within a regular p2sh + output. + + Note that when using this method to sign inputs belonging to the wallet, + the only items of the SignDescriptor that need to be populated are pkScript + in the TxOut field, the value in that same field, and finally the input + index. + */ + rpc ComputeInputScript (SignReq) returns (InputScriptResp); + + /* + SignMessage signs a message with the key specified in the key locator. The + returned signature is fixed-size LN wire format encoded. + + The main difference to SignMessage in the main RPC is that a specific key is + used to sign the message instead of the node identity private key. + */ + rpc SignMessage (SignMessageReq) returns (SignMessageResp); + + /* + VerifyMessage verifies a signature over a message using the public key + provided. The signature must be fixed-size LN wire format encoded. + + The main difference to VerifyMessage in the main RPC is that the public key + used to sign the message does not have to be a node known to the network. + */ + rpc VerifyMessage (VerifyMessageReq) returns (VerifyMessageResp); + + /* + DeriveSharedKey returns a shared secret key by performing Diffie-Hellman key + derivation between the ephemeral public key in the request and the node's + key specified in the key_desc parameter. Either a key locator or a raw + public key is expected in the key_desc, if neither is supplied, defaults to + the node's identity private key: + P_shared = privKeyNode * ephemeralPubkey + The resulting shared public key is serialized in the compressed format and + hashed with sha256, resulting in the final key length of 256bit. + */ + rpc DeriveSharedKey (SharedKeyRequest) returns (SharedKeyResponse); + + /* + MuSig2CombineKeys (experimental!) is a stateless helper RPC that can be used + to calculate the combined MuSig2 public key from a list of all participating + signers' public keys. This RPC is completely stateless and deterministic and + does not create any signing session. It can be used to determine the Taproot + public key that should be put in an on-chain output once all public keys are + known. A signing session is only needed later when that output should be + _spent_ again. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2CombineKeys (MuSig2CombineKeysRequest) + returns (MuSig2CombineKeysResponse); + + /* + MuSig2CreateSession (experimental!) creates a new MuSig2 signing session + using the local key identified by the key locator. The complete list of all + public keys of all signing parties must be provided, including the public + key of the local signing key. If nonces of other parties are already known, + they can be submitted as well to reduce the number of RPC calls necessary + later on. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2CreateSession (MuSig2SessionRequest) + returns (MuSig2SessionResponse); + + /* + MuSig2RegisterNonces (experimental!) registers one or more public nonces of + other signing participants for a session identified by its ID. This RPC can + be called multiple times until all nonces are registered. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2RegisterNonces (MuSig2RegisterNoncesRequest) + returns (MuSig2RegisterNoncesResponse); + + /* + MuSig2Sign (experimental!) creates a partial signature using the local + signing key that was specified when the session was created. This can only + be called when all public nonces of all participants are known and have been + registered with the session. If this node isn't responsible for combining + all the partial signatures, then the cleanup flag should be set, indicating + that the session can be removed from memory once the signature was produced. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2Sign (MuSig2SignRequest) returns (MuSig2SignResponse); + + /* + MuSig2CombineSig (experimental!) combines the given partial signature(s) + with the local one, if it already exists. Once a partial signature of all + participants is registered, the final signature will be combined and + returned. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2CombineSig (MuSig2CombineSigRequest) + returns (MuSig2CombineSigResponse); + + /* + MuSig2Cleanup (experimental!) allows a caller to clean up a session early in + cases where it's obvious that the signing session won't succeed and the + resources can be released. + + NOTE: The MuSig2 BIP is not final yet and therefore this API must be + considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming + releases. Backward compatibility is not guaranteed! + */ + rpc MuSig2Cleanup (MuSig2CleanupRequest) returns (MuSig2CleanupResponse); +} + +message KeyLocator { + // The family of key being identified. + int32 key_family = 1; + + // The precise index of the key being identified. + int32 key_index = 2; +} + +message KeyDescriptor { + /* + The raw bytes of the public key in the key pair being identified. Either + this or the KeyLocator must be specified. + */ + bytes raw_key_bytes = 1; + + /* + The key locator that identifies which private key to use for signing. + Either this or the raw bytes of the target public key must be specified. + */ + KeyLocator key_loc = 2; +} + +message TxOut { + // The value of the output being spent. + int64 value = 1; + + // The script of the output being spent. + bytes pk_script = 2; +} + +enum SignMethod { + /* + Specifies that a SegWit v0 (p2wkh, np2wkh, p2wsh) input script should be + signed. + */ + SIGN_METHOD_WITNESS_V0 = 0; + + /* + Specifies that a SegWit v1 (p2tr) input should be signed by using the + BIP0086 method (commit to internal key only). + */ + SIGN_METHOD_TAPROOT_KEY_SPEND_BIP0086 = 1; + + /* + Specifies that a SegWit v1 (p2tr) input should be signed by using a given + taproot hash to commit to in addition to the internal key. + */ + SIGN_METHOD_TAPROOT_KEY_SPEND = 2; + + /* + Specifies that a SegWit v1 (p2tr) input should be spent using the script + path and that a specific leaf script should be signed for. + */ + SIGN_METHOD_TAPROOT_SCRIPT_SPEND = 3; +} + +message SignDescriptor { + /* + A descriptor that precisely describes *which* key to use for signing. This + may provide the raw public key directly, or require the Signer to re-derive + the key according to the populated derivation path. + + Note that if the key descriptor was obtained through walletrpc.DeriveKey, + then the key locator MUST always be provided, since the derived keys are not + persisted unlike with DeriveNextKey. + */ + KeyDescriptor key_desc = 1; + + /* + A scalar value that will be added to the private key corresponding to the + above public key to obtain the private key to be used to sign this input. + This value is typically derived via the following computation: + + * derivedKey = privkey + sha256(perCommitmentPoint || pubKey) mod N + */ + bytes single_tweak = 2; + + /* + A private key that will be used in combination with its corresponding + private key to derive the private key that is to be used to sign the target + input. Within the Lightning protocol, this value is typically the + commitment secret from a previously revoked commitment transaction. This + value is in combination with two hash values, and the original private key + to derive the private key to be used when signing. + + * k = (privKey*sha256(pubKey || tweakPub) + + tweakPriv*sha256(tweakPub || pubKey)) mod N + */ + bytes double_tweak = 3; + + /* + The 32 byte input to the taproot tweak derivation that is used to derive + the output key from an internal key: outputKey = internalKey + + tagged_hash("tapTweak", internalKey || tapTweak). + + When doing a BIP 86 spend, this field can be an empty byte slice. + + When doing a normal key path spend, with the output key committing to an + actual script root, then this field should be: the tapscript root hash. + */ + bytes tap_tweak = 10; + + /* + The full script required to properly redeem the output. This field will + only be populated if a p2tr, p2wsh or a p2sh output is being signed. If a + taproot script path spend is being attempted, then this should be the raw + leaf script. + */ + bytes witness_script = 4; + + /* + A description of the output being spent. The value and script MUST be + provided. + */ + TxOut output = 5; + + /* + The target sighash type that should be used when generating the final + sighash, and signature. + */ + uint32 sighash = 7; + + /* + The target input within the transaction that should be signed. + */ + int32 input_index = 8; + + /* + The sign method specifies how the input should be signed. Depending on the + method, either the tap_tweak, witness_script or both need to be specified. + Defaults to SegWit v0 signing to be backward compatible with older RPC + clients. + */ + SignMethod sign_method = 9; +} + +message SignReq { + // The raw bytes of the transaction to be signed. + bytes raw_tx_bytes = 1; + + // A set of sign descriptors, for each input to be signed. + repeated SignDescriptor sign_descs = 2; + + /* + The full list of UTXO information for each of the inputs being spent. This + is required when spending one or more taproot (SegWit v1) outputs. + */ + repeated TxOut prev_outputs = 3; +} + +message SignResp { + /* + A set of signatures realized in a fixed 64-byte format ordered in ascending + input order. + */ + repeated bytes raw_sigs = 1; +} + +message InputScript { + // The serializes witness stack for the specified input. + repeated bytes witness = 1; + + /* + The optional sig script for the specified witness that will only be set if + the input specified is a nested p2sh witness program. + */ + bytes sig_script = 2; +} + +message InputScriptResp { + // The set of fully valid input scripts requested. + repeated InputScript input_scripts = 1; +} + +message SignMessageReq { + /* + The message to be signed. When using REST, this field must be encoded as + base64. + */ + bytes msg = 1; + + // The key locator that identifies which key to use for signing. + KeyLocator key_loc = 2; + + // Double-SHA256 hash instead of just the default single round. + bool double_hash = 3; + + /* + Use the compact (pubkey recoverable) format instead of the raw lnwire + format. This option cannot be used with Schnorr signatures. + */ + bool compact_sig = 4; + + /* + Use Schnorr signature. This option cannot be used with compact format. + */ + bool schnorr_sig = 5; + + /* + The optional Taproot tweak bytes to apply to the private key before creating + a Schnorr signature. The private key is tweaked as described in BIP-341: + privKey + h_tapTweak(internalKey || tapTweak) + */ + bytes schnorr_sig_tap_tweak = 6; +} +message SignMessageResp { + /* + The signature for the given message in the fixed-size LN wire format. + */ + bytes signature = 1; +} + +message VerifyMessageReq { + // The message over which the signature is to be verified. When using + // REST, this field must be encoded as base64. + bytes msg = 1; + + /* + The fixed-size LN wire encoded signature to be verified over the given + message. When using REST, this field must be encoded as base64. + */ + bytes signature = 2; + + /* + The public key the signature has to be valid for. When using REST, this + field must be encoded as base64. If the is_schnorr_sig option is true, then + the public key is expected to be in the 32-byte x-only serialization + according to BIP-340. + */ + bytes pubkey = 3; + + /* + Specifies if the signature is a Schnorr signature. + */ + bool is_schnorr_sig = 4; +} + +message VerifyMessageResp { + // Whether the signature was valid over the given message. + bool valid = 1; +} + +message SharedKeyRequest { + // The ephemeral public key to use for the DH key derivation. + bytes ephemeral_pubkey = 1; + + /* + Deprecated. The optional key locator of the local key that should be used. + If this parameter is not set then the node's identity private key will be + used. + */ + KeyLocator key_loc = 2 [deprecated = true]; + + /* + A key descriptor describes the key used for performing ECDH. Either a key + locator or a raw public key is expected, if neither is supplied, defaults to + the node's identity private key. + */ + KeyDescriptor key_desc = 3; +} + +message SharedKeyResponse { + // The shared public key, hashed with sha256. + bytes shared_key = 1; +} + +message TweakDesc { + /* + Tweak is the 32-byte value that will modify the public key. + */ + bytes tweak = 1; + + /* + Specifies if the target key should be converted to an x-only public key + before tweaking. If true, then the public key will be mapped to an x-only + key before the tweaking operation is applied. + */ + bool is_x_only = 2; +} + +message TaprootTweakDesc { + /* + The root hash of the tapscript tree if a script path is committed to. If + the MuSig2 key put on chain doesn't also commit to a script path (BIP-0086 + key spend only), then this needs to be empty and the key_spend_only field + below must be set to true. This is required because gRPC cannot + differentiate between a zero-size byte slice and a nil byte slice (both + would be serialized the same way). So the extra boolean is required. + */ + bytes script_root = 1; + + /* + Indicates that the above script_root is expected to be empty because this + is a BIP-0086 key spend only commitment where only the internal key is + committed to instead of also including a script root hash. + */ + bool key_spend_only = 2; +} + +message MuSig2CombineKeysRequest { + /* + A list of all public keys (serialized in 32-byte x-only format!) + participating in the signing session. The list will always be sorted + lexicographically internally. This must include the local key which is + described by the above key_loc. + */ + repeated bytes all_signer_pubkeys = 1; + + /* + A series of optional generic tweaks to be applied to the the aggregated + public key. + */ + repeated TweakDesc tweaks = 2; + + /* + An optional taproot specific tweak that must be specified if the MuSig2 + combined key will be used as the main taproot key of a taproot output + on-chain. + */ + TaprootTweakDesc taproot_tweak = 3; +} + +message MuSig2CombineKeysResponse { + /* + The combined public key (in the 32-byte x-only format) with all tweaks + applied to it. If a taproot tweak is specified, this corresponds to the + taproot key that can be put into the on-chain output. + */ + bytes combined_key = 1; + + /* + The raw combined public key (in the 32-byte x-only format) before any tweaks + are applied to it. If a taproot tweak is specified, this corresponds to the + internal key that needs to be put into the witness if the script spend path + is used. + */ + bytes taproot_internal_key = 2; +} + +message MuSig2SessionRequest { + /* + The key locator that identifies which key to use for signing. + */ + KeyLocator key_loc = 1; + + /* + A list of all public keys (serialized in 32-byte x-only format!) + participating in the signing session. The list will always be sorted + lexicographically internally. This must include the local key which is + described by the above key_loc. + */ + repeated bytes all_signer_pubkeys = 2; + + /* + An optional list of all public nonces of other signing participants that + might already be known. + */ + repeated bytes other_signer_public_nonces = 3; + + /* + A series of optional generic tweaks to be applied to the the aggregated + public key. + */ + repeated TweakDesc tweaks = 4; + + /* + An optional taproot specific tweak that must be specified if the MuSig2 + combined key will be used as the main taproot key of a taproot output + on-chain. + */ + TaprootTweakDesc taproot_tweak = 5; +} + +message MuSig2SessionResponse { + /* + The unique ID that represents this signing session. A session can be used + for producing a signature a single time. If the signing fails for any + reason, a new session with the same participants needs to be created. + */ + bytes session_id = 1; + + /* + The combined public key (in the 32-byte x-only format) with all tweaks + applied to it. If a taproot tweak is specified, this corresponds to the + taproot key that can be put into the on-chain output. + */ + bytes combined_key = 2; + + /* + The raw combined public key (in the 32-byte x-only format) before any tweaks + are applied to it. If a taproot tweak is specified, this corresponds to the + internal key that needs to be put into the witness if the script spend path + is used. + */ + bytes taproot_internal_key = 3; + + /* + The two public nonces the local signer uses, combined into a single value + of 66 bytes. Can be split into the two 33-byte points to get the individual + nonces. + */ + bytes local_public_nonces = 4; + + /* + Indicates whether all nonces required to start the signing process are known + now. + */ + bool have_all_nonces = 5; +} + +message MuSig2RegisterNoncesRequest { + /* + The unique ID of the signing session those nonces should be registered with. + */ + bytes session_id = 1; + + /* + A list of all public nonces of other signing participants that should be + registered. + */ + repeated bytes other_signer_public_nonces = 3; +} + +message MuSig2RegisterNoncesResponse { + /* + Indicates whether all nonces required to start the signing process are known + now. + */ + bool have_all_nonces = 1; +} + +message MuSig2SignRequest { + /* + The unique ID of the signing session to use for signing. + */ + bytes session_id = 1; + + /* + The 32-byte SHA256 digest of the message to sign. + */ + bytes message_digest = 2; + + /* + Cleanup indicates that after signing, the session state can be cleaned up, + since another participant is going to be responsible for combining the + partial signatures. + */ + bool cleanup = 3; +} + +message MuSig2SignResponse { + /* + The partial signature created by the local signer. + */ + bytes local_partial_signature = 1; +} + +message MuSig2CombineSigRequest { + /* + The unique ID of the signing session to combine the signatures for. + */ + bytes session_id = 1; + + /* + The list of all other participants' partial signatures to add to the current + session. + */ + repeated bytes other_partial_signatures = 2; +} + +message MuSig2CombineSigResponse { + /* + Indicates whether all partial signatures required to create a final, full + signature are known yet. If this is true, then the final_signature field is + set, otherwise it is empty. + */ + bool have_all_signatures = 1; + + /* + The final, full signature that is valid for the combined public key. + */ + bytes final_signature = 2; +} + +message MuSig2CleanupRequest { + /* + The unique ID of the signing session that should be removed/cleaned up. + */ + bytes session_id = 1; +} + +message MuSig2CleanupResponse { +} \ No newline at end of file diff --git a/vendor/stateservice.proto b/vendor/stateservice.proto new file mode 100644 index 0000000..f871320 --- /dev/null +++ b/vendor/stateservice.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; + +package lnrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc"; + +/* + * Comments in this file will be directly parsed into the API + * Documentation as descriptions of the associated method, message, or field. + * These descriptions should go right above the definition of the object, and + * can be in either block or // comment format. + * + * An RPC method can be matched to an lncli command by placing a line in the + * beginning of the description in exactly the following format: + * lncli: `methodname` + * + * Failure to specify the exact name of the command will cause documentation + * generation to fail. + * + * More information on how exactly the gRPC documentation is generated from + * this proto file can be found here: + * https://github.com/lightninglabs/lightning-api + */ + +// State service is a always running service that exposes the current state of +// the wallet and RPC server. +service State { + // SubscribeState subscribes to the state of the wallet. The current wallet + // state will always be delivered immediately. + rpc SubscribeState (SubscribeStateRequest) + returns (stream SubscribeStateResponse); + + // GetState returns the current wallet state without streaming further + // changes. + rpc GetState (GetStateRequest) returns (GetStateResponse); +} + +enum WalletState { + NON_EXISTING = 0; + LOCKED = 1; + UNLOCKED = 2; + RPC_ACTIVE = 3; + + // SERVER_ACTIVE means that the lnd server is ready to accept calls. + SERVER_ACTIVE = 4; + + WAITING_TO_START = 255; +} + +message SubscribeStateRequest { +} + +message SubscribeStateResponse { + WalletState state = 1; +} + +message GetStateRequest { +} + +message GetStateResponse { + WalletState state = 1; +} diff --git a/vendor/verrpc/verrpc.proto b/vendor/verrpc/verrpc.proto new file mode 100644 index 0000000..6f3120e --- /dev/null +++ b/vendor/verrpc/verrpc.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; + +package verrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/verrpc"; + +// Versioner is a service that can be used to get information about the version +// and build information of the running daemon. +service Versioner { + /* lncli: `version` + GetVersion returns the current version and build information of the running + daemon. + */ + rpc GetVersion (VersionRequest) returns (Version); +} + +message VersionRequest { +} + +message Version { + // A verbose description of the daemon's commit. + string commit = 1; + + // The SHA1 commit hash that the daemon is compiled with. + string commit_hash = 2; + + // The semantic version. + string version = 3; + + // The major application version. + uint32 app_major = 4; + + // The minor application version. + uint32 app_minor = 5; + + // The application patch number. + uint32 app_patch = 6; + + // The application pre-release modifier, possibly empty. + string app_pre_release = 7; + + // The list of build tags that were supplied during compilation. + repeated string build_tags = 8; + + // The version of go that compiled the executable. + string go_version = 9; +} diff --git a/vendor/walletrpc/walletkit.proto b/vendor/walletrpc/walletkit.proto new file mode 100644 index 0000000..2e5f453 --- /dev/null +++ b/vendor/walletrpc/walletkit.proto @@ -0,0 +1,918 @@ +syntax = "proto3"; + +import "lightning.proto"; +import "signrpc/signer.proto"; + +package walletrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/walletrpc"; + +// WalletKit is a service that gives access to the core functionalities of the +// daemon's wallet. +service WalletKit { + /* + ListUnspent returns a list of all utxos spendable by the wallet with a + number of confirmations between the specified minimum and maximum. By + default, all utxos are listed. To list only the unconfirmed utxos, set + the unconfirmed_only to true. + */ + rpc ListUnspent (ListUnspentRequest) returns (ListUnspentResponse); + + /* + LeaseOutput locks an output to the given ID, preventing it from being + available for any future coin selection attempts. The absolute time of the + lock's expiration is returned. The expiration of the lock can be extended by + successive invocations of this RPC. Outputs can be unlocked before their + expiration through `ReleaseOutput`. + */ + rpc LeaseOutput (LeaseOutputRequest) returns (LeaseOutputResponse); + + /* + ReleaseOutput unlocks an output, allowing it to be available for coin + selection if it remains unspent. The ID should match the one used to + originally lock the output. + */ + rpc ReleaseOutput (ReleaseOutputRequest) returns (ReleaseOutputResponse); + + /* + ListLeases lists all currently locked utxos. + */ + rpc ListLeases (ListLeasesRequest) returns (ListLeasesResponse); + + /* + DeriveNextKey attempts to derive the *next* key within the key family + (account in BIP43) specified. This method should return the next external + child within this branch. + */ + rpc DeriveNextKey (KeyReq) returns (signrpc.KeyDescriptor); + + /* + DeriveKey attempts to derive an arbitrary key specified by the passed + KeyLocator. + */ + rpc DeriveKey (signrpc.KeyLocator) returns (signrpc.KeyDescriptor); + + /* + NextAddr returns the next unused address within the wallet. + */ + rpc NextAddr (AddrRequest) returns (AddrResponse); + + /* + ListAccounts retrieves all accounts belonging to the wallet by default. A + name and key scope filter can be provided to filter through all of the + wallet accounts and return only those matching. + */ + rpc ListAccounts (ListAccountsRequest) returns (ListAccountsResponse); + + /* + RequiredReserve returns the minimum amount of satoshis that should be kept + in the wallet in order to fee bump anchor channels if necessary. The value + scales with the number of public anchor channels but is capped at a maximum. + */ + rpc RequiredReserve (RequiredReserveRequest) + returns (RequiredReserveResponse); + + /* + ImportAccount imports an account backed by an account extended public key. + The master key fingerprint denotes the fingerprint of the root key + corresponding to the account public key (also known as the key with + derivation path m/). This may be required by some hardware wallets for + proper identification and signing. + + The address type can usually be inferred from the key's version, but may be + required for certain keys to map them into the proper scope. + + For BIP-0044 keys, an address type must be specified as we intend to not + support importing BIP-0044 keys into the wallet using the legacy + pay-to-pubkey-hash (P2PKH) scheme. A nested witness address type will force + the standard BIP-0049 derivation scheme, while a witness address type will + force the standard BIP-0084 derivation scheme. + + For BIP-0049 keys, an address type must also be specified to make a + distinction between the standard BIP-0049 address schema (nested witness + pubkeys everywhere) and our own BIP-0049Plus address schema (nested pubkeys + externally, witness pubkeys internally). + + NOTE: Events (deposits/spends) for keys derived from an account will only be + detected by lnd if they happen after the import. Rescans to detect past + events will be supported later on. + */ + rpc ImportAccount (ImportAccountRequest) returns (ImportAccountResponse); + + /* + ImportPublicKey imports a public key as watch-only into the wallet. + + NOTE: Events (deposits/spends) for a key will only be detected by lnd if + they happen after the import. Rescans to detect past events will be + supported later on. + */ + rpc ImportPublicKey (ImportPublicKeyRequest) + returns (ImportPublicKeyResponse); + + /* + PublishTransaction attempts to publish the passed transaction to the + network. Once this returns without an error, the wallet will continually + attempt to re-broadcast the transaction on start up, until it enters the + chain. + */ + rpc PublishTransaction (Transaction) returns (PublishResponse); + + /* + SendOutputs is similar to the existing sendmany call in Bitcoind, and + allows the caller to create a transaction that sends to several outputs at + once. This is ideal when wanting to batch create a set of transactions. + */ + rpc SendOutputs (SendOutputsRequest) returns (SendOutputsResponse); + + /* + EstimateFee attempts to query the internal fee estimator of the wallet to + determine the fee (in sat/kw) to attach to a transaction in order to + achieve the confirmation target. + */ + rpc EstimateFee (EstimateFeeRequest) returns (EstimateFeeResponse); + + /* + PendingSweeps returns lists of on-chain outputs that lnd is currently + attempting to sweep within its central batching engine. Outputs with similar + fee rates are batched together in order to sweep them within a single + transaction. + + NOTE: Some of the fields within PendingSweepsRequest are not guaranteed to + remain supported. This is an advanced API that depends on the internals of + the UtxoSweeper, so things may change. + */ + rpc PendingSweeps (PendingSweepsRequest) returns (PendingSweepsResponse); + + /* + BumpFee bumps the fee of an arbitrary input within a transaction. This RPC + takes a different approach than bitcoind's bumpfee command. lnd has a + central batching engine in which inputs with similar fee rates are batched + together to save on transaction fees. Due to this, we cannot rely on + bumping the fee on a specific transaction, since transactions can change at + any point with the addition of new inputs. The list of inputs that + currently exist within lnd's central batching engine can be retrieved + through the PendingSweeps RPC. + + When bumping the fee of an input that currently exists within lnd's central + batching engine, a higher fee transaction will be created that replaces the + lower fee transaction through the Replace-By-Fee (RBF) policy. If it + + This RPC also serves useful when wanting to perform a Child-Pays-For-Parent + (CPFP), where the child transaction pays for its parent's fee. This can be + done by specifying an outpoint within the low fee transaction that is under + the control of the wallet. + + The fee preference can be expressed either as a specific fee rate or a delta + of blocks in which the output should be swept on-chain within. If a fee + preference is not explicitly specified, then an error is returned. + + Note that this RPC currently doesn't perform any validation checks on the + fee preference being provided. For now, the responsibility of ensuring that + the new fee preference is sufficient is delegated to the user. + */ + rpc BumpFee (BumpFeeRequest) returns (BumpFeeResponse); + + /* + ListSweeps returns a list of the sweep transactions our node has produced. + Note that these sweeps may not be confirmed yet, as we record sweeps on + broadcast, not confirmation. + */ + rpc ListSweeps (ListSweepsRequest) returns (ListSweepsResponse); + + /* + LabelTransaction adds a label to a transaction. If the transaction already + has a label the call will fail unless the overwrite bool is set. This will + overwrite the exiting transaction label. Labels must not be empty, and + cannot exceed 500 characters. + */ + rpc LabelTransaction (LabelTransactionRequest) + returns (LabelTransactionResponse); + + /* + FundPsbt creates a fully populated PSBT that contains enough inputs to fund + the outputs specified in the template. There are two ways of specifying a + template: Either by passing in a PSBT with at least one output declared or + by passing in a raw TxTemplate message. + + If there are no inputs specified in the template, coin selection is + performed automatically. If the template does contain any inputs, it is + assumed that full coin selection happened externally and no additional + inputs are added. If the specified inputs aren't enough to fund the outputs + with the given fee rate, an error is returned. + + After either selecting or verifying the inputs, all input UTXOs are locked + with an internal app ID. + + NOTE: If this method returns without an error, it is the caller's + responsibility to either spend the locked UTXOs (by finalizing and then + publishing the transaction) or to unlock/release the locked UTXOs in case of + an error on the caller's side. + */ + rpc FundPsbt (FundPsbtRequest) returns (FundPsbtResponse); + + /* + SignPsbt expects a partial transaction with all inputs and outputs fully + declared and tries to sign all unsigned inputs that have all required fields + (UTXO information, BIP32 derivation information, witness or sig scripts) + set. + If no error is returned, the PSBT is ready to be given to the next signer or + to be finalized if lnd was the last signer. + + NOTE: This RPC only signs inputs (and only those it can sign), it does not + perform any other tasks (such as coin selection, UTXO locking or + input/output/fee value validation, PSBT finalization). Any input that is + incomplete will be skipped. + */ + rpc SignPsbt (SignPsbtRequest) returns (SignPsbtResponse); + + /* + FinalizePsbt expects a partial transaction with all inputs and outputs fully + declared and tries to sign all inputs that belong to the wallet. Lnd must be + the last signer of the transaction. That means, if there are any unsigned + non-witness inputs or inputs without UTXO information attached or inputs + without witness data that do not belong to lnd's wallet, this method will + fail. If no error is returned, the PSBT is ready to be extracted and the + final TX within to be broadcast. + + NOTE: This method does NOT publish the transaction once finalized. It is the + caller's responsibility to either publish the transaction on success or + unlock/release any locked UTXOs in case of an error in this method. + */ + rpc FinalizePsbt (FinalizePsbtRequest) returns (FinalizePsbtResponse); +} + +message ListUnspentRequest { + // The minimum number of confirmations to be included. + int32 min_confs = 1; + + // The maximum number of confirmations to be included. + int32 max_confs = 2; + + // An optional filter to only include outputs belonging to an account. + string account = 3; + + /* + When min_confs and max_confs are zero, setting false implicitly + overrides max_confs to be MaxInt32, otherwise max_confs remains + zero. An error is returned if the value is true and both min_confs + and max_confs are non-zero. (default: false) + */ + bool unconfirmed_only = 4; +} + +message ListUnspentResponse { + // A list of utxos satisfying the specified number of confirmations. + repeated lnrpc.Utxo utxos = 1; +} + +message LeaseOutputRequest { + /* + An ID of 32 random bytes that must be unique for each distinct application + using this RPC which will be used to bound the output lease to. + */ + bytes id = 1; + + // The identifying outpoint of the output being leased. + lnrpc.OutPoint outpoint = 2; + + // The time in seconds before the lock expires. If set to zero, the default + // lock duration is used. + uint64 expiration_seconds = 3; +} + +message LeaseOutputResponse { + /* + The absolute expiration of the output lease represented as a unix timestamp. + */ + uint64 expiration = 1; +} + +message ReleaseOutputRequest { + // The unique ID that was used to lock the output. + bytes id = 1; + + // The identifying outpoint of the output being released. + lnrpc.OutPoint outpoint = 2; +} + +message ReleaseOutputResponse { +} + +message KeyReq { + /* + Is the key finger print of the root pubkey that this request is targeting. + This allows the WalletKit to possibly serve out keys for multiple HD chains + via public derivation. + */ + int32 key_finger_print = 1; + + /* + The target key family to derive a key from. In other contexts, this is + known as the "account". + */ + int32 key_family = 2; +} + +message AddrRequest { + /* + The name of the account to retrieve the next address of. If empty, the + default wallet account is used. + */ + string account = 1; + + /* + The type of address to derive. + */ + AddressType type = 2; + + /* + Whether a change address should be derived. + */ + bool change = 3; +} +message AddrResponse { + /* + The address encoded using a bech32 format. + */ + string addr = 1; +} + +enum AddressType { + UNKNOWN = 0; + WITNESS_PUBKEY_HASH = 1; + NESTED_WITNESS_PUBKEY_HASH = 2; + HYBRID_NESTED_WITNESS_PUBKEY_HASH = 3; + TAPROOT_PUBKEY = 4; +} +message Account { + // The name used to identify the account. + string name = 1; + + /* + The type of addresses the account supports. + AddressType | External Branch | Internal Branch + --------------------------------------------------------------------- + WITNESS_PUBKEY_HASH | P2WPKH | P2WPKH + NESTED_WITNESS_PUBKEY_HASH | NP2WPKH | NP2WPKH + HYBRID_NESTED_WITNESS_PUBKEY_HASH | NP2WPKH | P2WPKH + */ + AddressType address_type = 2; + + /* + The public key backing the account that all keys are derived from + represented as an extended key. This will always be empty for the default + imported account in which single public keys are imported into. + */ + string extended_public_key = 3; + + /* + The fingerprint of the root key from which the account public key was + derived from. This will always be zero for the default imported account in + which single public keys are imported into. The bytes are in big-endian + order. + */ + bytes master_key_fingerprint = 4; + + /* + The derivation path corresponding to the account public key. This will + always be empty for the default imported account in which single public keys + are imported into. + */ + string derivation_path = 5; + + /* + The number of keys derived from the external branch of the account public + key. This will always be zero for the default imported account in which + single public keys are imported into. + */ + uint32 external_key_count = 6; + + /* + The number of keys derived from the internal branch of the account public + key. This will always be zero for the default imported account in which + single public keys are imported into. + */ + uint32 internal_key_count = 7; + + // Whether the wallet stores private keys for the account. + bool watch_only = 8; +} +message ListAccountsRequest { + // An optional filter to only return accounts matching this name. + string name = 1; + + // An optional filter to only return accounts matching this address type. + AddressType address_type = 2; +} +message ListAccountsResponse { + repeated Account accounts = 1; +} + +message RequiredReserveRequest { + // The number of additional channels the user would like to open. + uint32 additional_public_channels = 1; +} + +message RequiredReserveResponse { + // The amount of reserve required. + int64 required_reserve = 1; +} + +message ImportAccountRequest { + // A name to identify the account with. + string name = 1; + + /* + A public key that corresponds to a wallet account represented as an extended + key. It must conform to a derivation path of the form + m/purpose'/coin_type'/account'. + */ + string extended_public_key = 2; + + /* + The fingerprint of the root key (also known as the key with derivation path + m/) from which the account public key was derived from. This may be required + by some hardware wallets for proper identification and signing. The bytes + must be in big-endian order. + */ + bytes master_key_fingerprint = 3; + + /* + An address type is only required when the extended account public key has a + legacy version (xpub, tpub, etc.), such that the wallet cannot detect what + address scheme it belongs to. + */ + AddressType address_type = 4; + + /* + Whether a dry run should be attempted when importing the account. This + serves as a way to confirm whether the account is being imported correctly + by returning the first N addresses for the external and internal branches of + the account. If these addresses match as expected, then it should be safe to + import the account as is. + */ + bool dry_run = 5; +} +message ImportAccountResponse { + // The details of the imported account. + Account account = 1; + + /* + The first N addresses that belong to the external branch of the account. + The external branch is typically used for external non-change addresses. + These are only returned if a dry run was specified within the request. + */ + repeated string dry_run_external_addrs = 2; + + /* + The first N addresses that belong to the internal branch of the account. + The internal branch is typically used for change addresses. These are only + returned if a dry run was specified within the request. + */ + repeated string dry_run_internal_addrs = 3; +} + +message ImportPublicKeyRequest { + // A compressed public key represented as raw bytes. + bytes public_key = 1; + + // The type of address that will be generated from the public key. + AddressType address_type = 2; +} +message ImportPublicKeyResponse { +} + +message Transaction { + /* + The raw serialized transaction. + */ + bytes tx_hex = 1; + + /* + An optional label to save with the transaction. Limited to 500 characters. + */ + string label = 2; +} +message PublishResponse { + /* + If blank, then no error occurred and the transaction was successfully + published. If not the empty string, then a string representation of the + broadcast error. + + TODO(roasbeef): map to a proper enum type + */ + string publish_error = 1; +} + +message SendOutputsRequest { + /* + The number of satoshis per kilo weight that should be used when crafting + this transaction. + */ + int64 sat_per_kw = 1; + + /* + A slice of the outputs that should be created in the transaction produced. + */ + repeated signrpc.TxOut outputs = 2; + + // An optional label for the transaction, limited to 500 characters. + string label = 3; + + // The minimum number of confirmations each one of your outputs used for + // the transaction must satisfy. + int32 min_confs = 4; + + // Whether unconfirmed outputs should be used as inputs for the transaction. + bool spend_unconfirmed = 5; +} +message SendOutputsResponse { + /* + The serialized transaction sent out on the network. + */ + bytes raw_tx = 1; +} + +message EstimateFeeRequest { + /* + The number of confirmations to shoot for when estimating the fee. + */ + int32 conf_target = 1; +} +message EstimateFeeResponse { + /* + The amount of satoshis per kw that should be used in order to reach the + confirmation target in the request. + */ + int64 sat_per_kw = 1; +} + +enum WitnessType { + UNKNOWN_WITNESS = 0; + + /* + A witness that allows us to spend the output of a commitment transaction + after a relative lock-time lockout. + */ + COMMITMENT_TIME_LOCK = 1; + + /* + A witness that allows us to spend a settled no-delay output immediately on a + counterparty's commitment transaction. + */ + COMMITMENT_NO_DELAY = 2; + + /* + A witness that allows us to sweep the settled output of a malicious + counterparty's who broadcasts a revoked commitment transaction. + */ + COMMITMENT_REVOKE = 3; + + /* + A witness that allows us to sweep an HTLC which we offered to the remote + party in the case that they broadcast a revoked commitment state. + */ + HTLC_OFFERED_REVOKE = 4; + + /* + A witness that allows us to sweep an HTLC output sent to us in the case that + the remote party broadcasts a revoked commitment state. + */ + HTLC_ACCEPTED_REVOKE = 5; + + /* + A witness that allows us to sweep an HTLC output that we extended to a + party, but was never fulfilled. This HTLC output isn't directly on the + commitment transaction, but is the result of a confirmed second-level HTLC + transaction. As a result, we can only spend this after a CSV delay. + */ + HTLC_OFFERED_TIMEOUT_SECOND_LEVEL = 6; + + /* + A witness that allows us to sweep an HTLC output that was offered to us, and + for which we have a payment preimage. This HTLC output isn't directly on our + commitment transaction, but is the result of confirmed second-level HTLC + transaction. As a result, we can only spend this after a CSV delay. + */ + HTLC_ACCEPTED_SUCCESS_SECOND_LEVEL = 7; + + /* + A witness that allows us to sweep an HTLC that we offered to the remote + party which lies in the commitment transaction of the remote party. We can + spend this output after the absolute CLTV timeout of the HTLC as passed. + */ + HTLC_OFFERED_REMOTE_TIMEOUT = 8; + + /* + A witness that allows us to sweep an HTLC that was offered to us by the + remote party. We use this witness in the case that the remote party goes to + chain, and we know the pre-image to the HTLC. We can sweep this without any + additional timeout. + */ + HTLC_ACCEPTED_REMOTE_SUCCESS = 9; + + /* + A witness that allows us to sweep an HTLC from the remote party's commitment + transaction in the case that the broadcast a revoked commitment, but then + also immediately attempt to go to the second level to claim the HTLC. + */ + HTLC_SECOND_LEVEL_REVOKE = 10; + + /* + A witness type that allows us to spend a regular p2wkh output that's sent to + an output which is under complete control of the backing wallet. + */ + WITNESS_KEY_HASH = 11; + + /* + A witness type that allows us to sweep an output that sends to a nested P2SH + script that pays to a key solely under our control. + */ + NESTED_WITNESS_KEY_HASH = 12; + + /* + A witness type that allows us to spend our anchor on the commitment + transaction. + */ + COMMITMENT_ANCHOR = 13; +} + +message PendingSweep { + // The outpoint of the output we're attempting to sweep. + lnrpc.OutPoint outpoint = 1; + + // The witness type of the output we're attempting to sweep. + WitnessType witness_type = 2; + + // The value of the output we're attempting to sweep. + uint32 amount_sat = 3; + + /* + Deprecated, use sat_per_vbyte. + The fee rate we'll use to sweep the output, expressed in sat/vbyte. The fee + rate is only determined once a sweeping transaction for the output is + created, so it's possible for this to be 0 before this. + */ + uint32 sat_per_byte = 4 [deprecated = true]; + + // The number of broadcast attempts we've made to sweep the output. + uint32 broadcast_attempts = 5; + + /* + The next height of the chain at which we'll attempt to broadcast the + sweep transaction of the output. + */ + uint32 next_broadcast_height = 6; + + // The requested confirmation target for this output. + uint32 requested_conf_target = 8; + + // Deprecated, use requested_sat_per_vbyte. + // The requested fee rate, expressed in sat/vbyte, for this output. + uint32 requested_sat_per_byte = 9 [deprecated = true]; + + /* + The fee rate we'll use to sweep the output, expressed in sat/vbyte. The fee + rate is only determined once a sweeping transaction for the output is + created, so it's possible for this to be 0 before this. + */ + uint64 sat_per_vbyte = 10; + + // The requested fee rate, expressed in sat/vbyte, for this output. + uint64 requested_sat_per_vbyte = 11; + + /* + Whether this input must be force-swept. This means that it is swept even + if it has a negative yield. + */ + bool force = 7; +} + +message PendingSweepsRequest { +} + +message PendingSweepsResponse { + /* + The set of outputs currently being swept by lnd's central batching engine. + */ + repeated PendingSweep pending_sweeps = 1; +} + +message BumpFeeRequest { + // The input we're attempting to bump the fee of. + lnrpc.OutPoint outpoint = 1; + + // The target number of blocks that the input should be spent within. + uint32 target_conf = 2; + + /* + Deprecated, use sat_per_vbyte. + The fee rate, expressed in sat/vbyte, that should be used to spend the input + with. + */ + uint32 sat_per_byte = 3 [deprecated = true]; + + /* + Whether this input must be force-swept. This means that it is swept even + if it has a negative yield. + */ + bool force = 4; + + /* + The fee rate, expressed in sat/vbyte, that should be used to spend the input + with. + */ + uint64 sat_per_vbyte = 5; +} + +message BumpFeeResponse { +} + +message ListSweepsRequest { + /* + Retrieve the full sweep transaction details. If false, only the sweep txids + will be returned. Note that some sweeps that LND publishes will have been + replaced-by-fee, so will not be included in this output. + */ + bool verbose = 1; +} + +message ListSweepsResponse { + message TransactionIDs { + /* + Reversed, hex-encoded string representing the transaction ids of the + sweeps that our node has broadcast. Note that these transactions may + not have confirmed yet, we record sweeps on broadcast, not confirmation. + */ + repeated string transaction_ids = 1; + } + + oneof sweeps { + lnrpc.TransactionDetails transaction_details = 1; + TransactionIDs transaction_ids = 2; + } +} + +message LabelTransactionRequest { + // The txid of the transaction to label. + bytes txid = 1; + + // The label to add to the transaction, limited to 500 characters. + string label = 2; + + // Whether to overwrite the existing label, if it is present. + bool overwrite = 3; +} + +message LabelTransactionResponse { +} + +message FundPsbtRequest { + oneof template { + /* + Use an existing PSBT packet as the template for the funded PSBT. + + The packet must contain at least one non-dust output. If one or more + inputs are specified, no coin selection is performed. In that case every + input must be an UTXO known to the wallet that has not been locked + before. The sum of all inputs must be sufficiently greater than the sum + of all outputs to pay a miner fee with the specified fee rate. A change + output is added to the PSBT if necessary. + */ + bytes psbt = 1; + + /* + Use the outputs and optional inputs from this raw template. + */ + TxTemplate raw = 2; + } + + oneof fees { + /* + The target number of blocks that the transaction should be confirmed in. + */ + uint32 target_conf = 3; + + /* + The fee rate, expressed in sat/vbyte, that should be used to spend the + input with. + */ + uint64 sat_per_vbyte = 4; + } + + /* + The name of the account to fund the PSBT with. If empty, the default wallet + account is used. + */ + string account = 5; + + // The minimum number of confirmations each one of your outputs used for + // the transaction must satisfy. + int32 min_confs = 6; + + // Whether unconfirmed outputs should be used as inputs for the transaction. + bool spend_unconfirmed = 7; +} +message FundPsbtResponse { + /* + The funded but not yet signed PSBT packet. + */ + bytes funded_psbt = 1; + + /* + The index of the added change output or -1 if no change was left over. + */ + int32 change_output_index = 2; + + /* + The list of lock leases that were acquired for the inputs in the funded PSBT + packet. + */ + repeated UtxoLease locked_utxos = 3; +} + +message TxTemplate { + /* + An optional list of inputs to use. Every input must be an UTXO known to the + wallet that has not been locked before. The sum of all inputs must be + sufficiently greater than the sum of all outputs to pay a miner fee with the + fee rate specified in the parent message. + + If no inputs are specified, coin selection will be performed instead and + inputs of sufficient value will be added to the resulting PSBT. + */ + repeated lnrpc.OutPoint inputs = 1; + + /* + A map of all addresses and the amounts to send to in the funded PSBT. + */ + map outputs = 2; +} + +message UtxoLease { + /* + A 32 byte random ID that identifies the lease. + */ + bytes id = 1; + + // The identifying outpoint of the output being leased. + lnrpc.OutPoint outpoint = 2; + + /* + The absolute expiration of the output lease represented as a unix timestamp. + */ + uint64 expiration = 3; + + /* + The public key script of the leased output. + */ + bytes pk_script = 4; + + /* + The value of the leased output in satoshis. + */ + uint64 value = 5; +} + +message SignPsbtRequest { + /* + The PSBT that should be signed. The PSBT must contain all required inputs, + outputs, UTXO data and custom fields required to identify the signing key. + */ + bytes funded_psbt = 1; +} + +message SignPsbtResponse { + // The signed transaction in PSBT format. + bytes signed_psbt = 1; +} + +message FinalizePsbtRequest { + /* + A PSBT that should be signed and finalized. The PSBT must contain all + required inputs, outputs, UTXO data and partial signatures of all other + signers. + */ + bytes funded_psbt = 1; + + /* + The name of the account to finalize the PSBT with. If empty, the default + wallet account is used. + */ + string account = 5; +} +message FinalizePsbtResponse { + // The fully signed and finalized transaction in PSBT format. + bytes signed_psbt = 1; + + // The fully signed and finalized transaction in the raw wire format. + bytes raw_final_tx = 2; +} + +message ListLeasesRequest { +} + +message ListLeasesResponse { + // The list of currently leased utxos. + repeated UtxoLease locked_utxos = 1; +} diff --git a/vendor/walletunlocker.proto b/vendor/walletunlocker.proto new file mode 100644 index 0000000..55bc31c --- /dev/null +++ b/vendor/walletunlocker.proto @@ -0,0 +1,331 @@ +syntax = "proto3"; + +import "lightning.proto"; + +package lnrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc"; + +/* + * Comments in this file will be directly parsed into the API + * Documentation as descriptions of the associated method, message, or field. + * These descriptions should go right above the definition of the object, and + * can be in either block or // comment format. + * + * An RPC method can be matched to an lncli command by placing a line in the + * beginning of the description in exactly the following format: + * lncli: `methodname` + * + * Failure to specify the exact name of the command will cause documentation + * generation to fail. + * + * More information on how exactly the gRPC documentation is generated from + * this proto file can be found here: + * https://github.com/lightninglabs/lightning-api + */ + +// WalletUnlocker is a service that is used to set up a wallet password for +// lnd at first startup, and unlock a previously set up wallet. +service WalletUnlocker { + /* + GenSeed is the first method that should be used to instantiate a new lnd + instance. This method allows a caller to generate a new aezeed cipher seed + given an optional passphrase. If provided, the passphrase will be necessary + to decrypt the cipherseed to expose the internal wallet seed. + + Once the cipherseed is obtained and verified by the user, the InitWallet + method should be used to commit the newly generated seed, and create the + wallet. + */ + rpc GenSeed (GenSeedRequest) returns (GenSeedResponse); + + /* + InitWallet is used when lnd is starting up for the first time to fully + initialize the daemon and its internal wallet. At the very least a wallet + password must be provided. This will be used to encrypt sensitive material + on disk. + + In the case of a recovery scenario, the user can also specify their aezeed + mnemonic and passphrase. If set, then the daemon will use this prior state + to initialize its internal wallet. + + Alternatively, this can be used along with the GenSeed RPC to obtain a + seed, then present it to the user. Once it has been verified by the user, + the seed can be fed into this RPC in order to commit the new wallet. + */ + rpc InitWallet (InitWalletRequest) returns (InitWalletResponse); + + /* lncli: `unlock` + UnlockWallet is used at startup of lnd to provide a password to unlock + the wallet database. + */ + rpc UnlockWallet (UnlockWalletRequest) returns (UnlockWalletResponse); + + /* lncli: `changepassword` + ChangePassword changes the password of the encrypted wallet. This will + automatically unlock the wallet database if successful. + */ + rpc ChangePassword (ChangePasswordRequest) returns (ChangePasswordResponse); +} + +message GenSeedRequest { + /* + aezeed_passphrase is an optional user provided passphrase that will be used + to encrypt the generated aezeed cipher seed. When using REST, this field + must be encoded as base64. + */ + bytes aezeed_passphrase = 1; + + /* + seed_entropy is an optional 16-bytes generated via CSPRNG. If not + specified, then a fresh set of randomness will be used to create the seed. + When using REST, this field must be encoded as base64. + */ + bytes seed_entropy = 2; +} +message GenSeedResponse { + /* + cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed + cipher seed obtained by the user. This field is optional, as if not + provided, then the daemon will generate a new cipher seed for the user. + Otherwise, then the daemon will attempt to recover the wallet state linked + to this cipher seed. + */ + repeated string cipher_seed_mnemonic = 1; + + /* + enciphered_seed are the raw aezeed cipher seed bytes. This is the raw + cipher text before run through our mnemonic encoding scheme. + */ + bytes enciphered_seed = 2; +} + +message InitWalletRequest { + /* + wallet_password is the passphrase that should be used to encrypt the + wallet. This MUST be at least 8 chars in length. After creation, this + password is required to unlock the daemon. When using REST, this field + must be encoded as base64. + */ + bytes wallet_password = 1; + + /* + cipher_seed_mnemonic is a 24-word mnemonic that encodes a prior aezeed + cipher seed obtained by the user. This may have been generated by the + GenSeed method, or be an existing seed. + */ + repeated string cipher_seed_mnemonic = 2; + + /* + aezeed_passphrase is an optional user provided passphrase that will be used + to encrypt the generated aezeed cipher seed. When using REST, this field + must be encoded as base64. + */ + bytes aezeed_passphrase = 3; + + /* + recovery_window is an optional argument specifying the address lookahead + when restoring a wallet seed. The recovery window applies to each + individual branch of the BIP44 derivation paths. Supplying a recovery + window of zero indicates that no addresses should be recovered, such after + the first initialization of the wallet. + */ + int32 recovery_window = 4; + + /* + channel_backups is an optional argument that allows clients to recover the + settled funds within a set of channels. This should be populated if the + user was unable to close out all channels and sweep funds before partial or + total data loss occurred. If specified, then after on-chain recovery of + funds, lnd begin to carry out the data loss recovery protocol in order to + recover the funds in each channel from a remote force closed transaction. + */ + ChanBackupSnapshot channel_backups = 5; + + /* + stateless_init is an optional argument instructing the daemon NOT to create + any *.macaroon files in its filesystem. If this parameter is set, then the + admin macaroon returned in the response MUST be stored by the caller of the + RPC as otherwise all access to the daemon will be lost! + */ + bool stateless_init = 6; + + /* + extended_master_key is an alternative to specifying cipher_seed_mnemonic and + aezeed_passphrase. Instead of deriving the master root key from the entropy + of an aezeed cipher seed, the given extended master root key is used + directly as the wallet's master key. This allows users to import/use a + master key from another wallet. When doing so, lnd still uses its default + SegWit only (BIP49/84) derivation paths and funds from custom/non-default + derivation paths will not automatically appear in the on-chain wallet. Using + an 'xprv' instead of an aezeed also has the disadvantage that the wallet's + birthday is not known as that is an information that's only encoded in the + aezeed, not the xprv. Therefore a birthday needs to be specified in + extended_master_key_birthday_timestamp or a "safe" default value will be + used. + */ + string extended_master_key = 7; + + /* + extended_master_key_birthday_timestamp is the optional unix timestamp in + seconds to use as the wallet's birthday when using an extended master key + to restore the wallet. lnd will only start scanning for funds in blocks that + are after the birthday which can speed up the process significantly. If the + birthday is not known, this should be left at its default value of 0 in + which case lnd will start scanning from the first SegWit block (481824 on + mainnet). + */ + uint64 extended_master_key_birthday_timestamp = 8; + + /* + watch_only is the third option of initializing a wallet: by importing + account xpubs only and therefore creating a watch-only wallet that does not + contain any private keys. That means the wallet won't be able to sign for + any of the keys and _needs_ to be run with a remote signer that has the + corresponding private keys and can serve signing RPC requests. + */ + WatchOnly watch_only = 9; +} +message InitWalletResponse { + /* + The binary serialized admin macaroon that can be used to access the daemon + after creating the wallet. If the stateless_init parameter was set to true, + this is the ONLY copy of the macaroon and MUST be stored safely by the + caller. Otherwise a copy of this macaroon is also persisted on disk by the + daemon, together with other macaroon files. + */ + bytes admin_macaroon = 1; +} + +message WatchOnly { + /* + The unix timestamp in seconds of when the master key was created. lnd will + only start scanning for funds in blocks that are after the birthday which + can speed up the process significantly. If the birthday is not known, this + should be left at its default value of 0 in which case lnd will start + scanning from the first SegWit block (481824 on mainnet). + */ + uint64 master_key_birthday_timestamp = 1; + + /* + The fingerprint of the root key (also known as the key with derivation path + m/) from which the account public keys were derived from. This may be + required by some hardware wallets for proper identification and signing. The + bytes must be in big-endian order. + */ + bytes master_key_fingerprint = 2; + + /* + The list of accounts to import. There _must_ be an account for all of lnd's + main key scopes: BIP49/BIP84 (m/49'/0'/0', m/84'/0'/0', note that the + coin type is always 0, even for testnet/regtest) and lnd's internal key + scope (m/1017'/'/'), where account is the key family as + defined in `keychain/derivation.go` (currently indices 0 to 9). + */ + repeated WatchOnlyAccount accounts = 3; +} + +message WatchOnlyAccount { + /* + Purpose is the first number in the derivation path, must be either 49, 84 + or 1017. + */ + uint32 purpose = 1; + + /* + Coin type is the second number in the derivation path, this is _always_ 0 + for purposes 49 and 84. It only needs to be set to 1 for purpose 1017 on + testnet or regtest. + */ + uint32 coin_type = 2; + + /* + Account is the third number in the derivation path. For purposes 49 and 84 + at least the default account (index 0) needs to be created but optional + additional accounts are allowed. For purpose 1017 there needs to be exactly + one account for each of the key families defined in `keychain/derivation.go` + (currently indices 0 to 9) + */ + uint32 account = 3; + + /* + The extended public key at depth 3 for the given account. + */ + string xpub = 4; +} + +message UnlockWalletRequest { + /* + wallet_password should be the current valid passphrase for the daemon. This + will be required to decrypt on-disk material that the daemon requires to + function properly. When using REST, this field must be encoded as base64. + */ + bytes wallet_password = 1; + + /* + recovery_window is an optional argument specifying the address lookahead + when restoring a wallet seed. The recovery window applies to each + individual branch of the BIP44 derivation paths. Supplying a recovery + window of zero indicates that no addresses should be recovered, such after + the first initialization of the wallet. + */ + int32 recovery_window = 2; + + /* + channel_backups is an optional argument that allows clients to recover the + settled funds within a set of channels. This should be populated if the + user was unable to close out all channels and sweep funds before partial or + total data loss occurred. If specified, then after on-chain recovery of + funds, lnd begin to carry out the data loss recovery protocol in order to + recover the funds in each channel from a remote force closed transaction. + */ + ChanBackupSnapshot channel_backups = 3; + + /* + stateless_init is an optional argument instructing the daemon NOT to create + any *.macaroon files in its file system. + */ + bool stateless_init = 4; +} +message UnlockWalletResponse { +} + +message ChangePasswordRequest { + /* + current_password should be the current valid passphrase used to unlock the + daemon. When using REST, this field must be encoded as base64. + */ + bytes current_password = 1; + + /* + new_password should be the new passphrase that will be needed to unlock the + daemon. When using REST, this field must be encoded as base64. + */ + bytes new_password = 2; + + /* + stateless_init is an optional argument instructing the daemon NOT to create + any *.macaroon files in its filesystem. If this parameter is set, then the + admin macaroon returned in the response MUST be stored by the caller of the + RPC as otherwise all access to the daemon will be lost! + */ + bool stateless_init = 3; + + /* + new_macaroon_root_key is an optional argument instructing the daemon to + rotate the macaroon root key when set to true. This will invalidate all + previously generated macaroons. + */ + bool new_macaroon_root_key = 4; +} +message ChangePasswordResponse { + /* + The binary serialized admin macaroon that can be used to access the daemon + after rotating the macaroon root key. If both the stateless_init and + new_macaroon_root_key parameter were set to true, this is the ONLY copy of + the macaroon that was created from the new root key and MUST be stored + safely by the caller. Otherwise a copy of this macaroon is also persisted on + disk by the daemon, together with other macaroon files. + */ + bytes admin_macaroon = 1; +} diff --git a/vendor/watchtowerrpc/watchtower.proto b/vendor/watchtowerrpc/watchtower.proto new file mode 100644 index 0000000..f3be621 --- /dev/null +++ b/vendor/watchtowerrpc/watchtower.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package watchtowerrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/watchtowerrpc"; + +// Watchtower is a service that grants access to the watchtower server +// functionality of the daemon. +service Watchtower { + /* lncli: tower info + GetInfo returns general information concerning the companion watchtower + including its public key and URIs where the server is currently + listening for clients. + */ + rpc GetInfo (GetInfoRequest) returns (GetInfoResponse); +} + +message GetInfoRequest { +} + +message GetInfoResponse { + // The public key of the watchtower. + bytes pubkey = 1; + + // The listening addresses of the watchtower. + repeated string listeners = 2; + + // The URIs of the watchtower. + repeated string uris = 3; +} diff --git a/vendor/wtclientrpc/wtclient.proto b/vendor/wtclientrpc/wtclient.proto new file mode 100644 index 0000000..736a4bd --- /dev/null +++ b/vendor/wtclientrpc/wtclient.proto @@ -0,0 +1,193 @@ +syntax = "proto3"; + +package wtclientrpc; + +option go_package = "github.com/lightningnetwork/lnd/lnrpc/wtclientrpc"; + +// WatchtowerClient is a service that grants access to the watchtower client +// functionality of the daemon. +service WatchtowerClient { + /* + AddTower adds a new watchtower reachable at the given address and + considers it for new sessions. If the watchtower already exists, then + any new addresses included will be considered when dialing it for + session negotiations and backups. + */ + rpc AddTower (AddTowerRequest) returns (AddTowerResponse); + + /* + RemoveTower removes a watchtower from being considered for future session + negotiations and from being used for any subsequent backups until it's added + again. If an address is provided, then this RPC only serves as a way of + removing the address from the watchtower instead. + */ + rpc RemoveTower (RemoveTowerRequest) returns (RemoveTowerResponse); + + // ListTowers returns the list of watchtowers registered with the client. + rpc ListTowers (ListTowersRequest) returns (ListTowersResponse); + + // GetTowerInfo retrieves information for a registered watchtower. + rpc GetTowerInfo (GetTowerInfoRequest) returns (Tower); + + // Stats returns the in-memory statistics of the client since startup. + rpc Stats (StatsRequest) returns (StatsResponse); + + // Policy returns the active watchtower client policy configuration. + rpc Policy (PolicyRequest) returns (PolicyResponse); +} + +message AddTowerRequest { + // The identifying public key of the watchtower to add. + bytes pubkey = 1; + + // A network address the watchtower is reachable over. + string address = 2; +} + +message AddTowerResponse { +} + +message RemoveTowerRequest { + // The identifying public key of the watchtower to remove. + bytes pubkey = 1; + + /* + If set, then the record for this address will be removed, indicating that is + is stale. Otherwise, the watchtower will no longer be used for future + session negotiations and backups. + */ + string address = 2; +} + +message RemoveTowerResponse { +} + +message GetTowerInfoRequest { + // The identifying public key of the watchtower to retrieve information for. + bytes pubkey = 1; + + // Whether we should include sessions with the watchtower in the response. + bool include_sessions = 2; +} + +message TowerSession { + /* + The total number of successful backups that have been made to the + watchtower session. + */ + uint32 num_backups = 1; + + /* + The total number of backups in the session that are currently pending to be + acknowledged by the watchtower. + */ + uint32 num_pending_backups = 2; + + // The maximum number of backups allowed by the watchtower session. + uint32 max_backups = 3; + + /* + Deprecated, use sweep_sat_per_vbyte. + The fee rate, in satoshis per vbyte, that will be used by the watchtower for + the justice transaction in the event of a channel breach. + */ + uint32 sweep_sat_per_byte = 4 [deprecated = true]; + + /* + The fee rate, in satoshis per vbyte, that will be used by the watchtower for + the justice transaction in the event of a channel breach. + */ + uint32 sweep_sat_per_vbyte = 5; +} + +message Tower { + // The identifying public key of the watchtower. + bytes pubkey = 1; + + // The list of addresses the watchtower is reachable over. + repeated string addresses = 2; + + // Whether the watchtower is currently a candidate for new sessions. + bool active_session_candidate = 3; + + // The number of sessions that have been negotiated with the watchtower. + uint32 num_sessions = 4; + + // The list of sessions that have been negotiated with the watchtower. + repeated TowerSession sessions = 5; +} + +message ListTowersRequest { + // Whether we should include sessions with the watchtower in the response. + bool include_sessions = 1; +} + +message ListTowersResponse { + // The list of watchtowers available for new backups. + repeated Tower towers = 1; +} + +message StatsRequest { +} + +message StatsResponse { + /* + The total number of backups made to all active and exhausted watchtower + sessions. + */ + uint32 num_backups = 1; + + /* + The total number of backups that are pending to be acknowledged by all + active and exhausted watchtower sessions. + */ + uint32 num_pending_backups = 2; + + /* + The total number of backups that all active and exhausted watchtower + sessions have failed to acknowledge. + */ + uint32 num_failed_backups = 3; + + // The total number of new sessions made to watchtowers. + uint32 num_sessions_acquired = 4; + + // The total number of watchtower sessions that have been exhausted. + uint32 num_sessions_exhausted = 5; +} + +enum PolicyType { + // Selects the policy from the legacy tower client. + LEGACY = 0; + + // Selects the policy from the anchor tower client. + ANCHOR = 1; +} + +message PolicyRequest { + /* + The client type from which to retrieve the active offering policy. + */ + PolicyType policy_type = 1; +} + +message PolicyResponse { + /* + The maximum number of updates each session we negotiate with watchtowers + should allow. + */ + uint32 max_updates = 1; + + /* + Deprecated, use sweep_sat_per_vbyte. + The fee rate, in satoshis per vbyte, that will be used by watchtowers for + justice transactions in response to channel breaches. + */ + uint32 sweep_sat_per_byte = 2 [deprecated = true]; + + /* + The fee rate, in satoshis per vbyte, that will be used by watchtowers for + justice transactions in response to channel breaches. + */ + uint32 sweep_sat_per_vbyte = 3; +}