vlsd 0.14.0

A Lightning signer that connects to the node using a gRPC protocol
Documentation
use bitcoind_client::BlockExplorerType;
use clap::error::ErrorKind;
use clap::{CommandFactory, Parser};
use config::{parse_args_and_config, HasSignerArgs, SignerArgs, DEFAULT_DIR};
use grpc::signer::make_handler;
use grpc::signer::start_signer;
use http::Uri;
use lightning_signer::bitcoin::Network;
use log::warn;
use recovery::{direct::DirectRecoveryKeys, recover_close, recover_l1};
use std::fs;
use util::abort_on_panic;
use vls_util::observability::init_tracing_subscriber;
use vlsd::*;

#[derive(Parser, Debug)]
#[clap(about, long_about = None)]
struct Args {
    #[clap(
        short,
        long,
        value_parser,
        help = "node RPC endpoint",
        required_unless_present_any(&["recover_to", "git_desc"]),
        value_name = "URL"
    )]
    pub(crate) connect: Option<Uri>,
    #[clap(flatten)]
    pub(crate) signer_args: SignerArgs,
}

impl HasSignerArgs for Args {
    fn signer_args(&self) -> &SignerArgs {
        &self.signer_args
    }
}

#[tokio::main(worker_threads = 2)]
pub async fn main() {
    abort_on_panic();

    let (shutdown_trigger, shutdown_signal) = triggered::trigger();
    let trigger1 = shutdown_trigger.clone();
    ctrlc::set_handler(move || {
        warn!("ctrlc handler triggering shutdown");
        trigger1.trigger();
    })
    .expect("Error setting Ctrl-C handler");

    let bin_name = "vlsd";
    let our_args: Args = parse_args_and_config(bin_name);

    let args = our_args.signer_args;

    let network = args.network;
    let datadir = args.datadir.clone().unwrap_or(format!(
        "{}/{DEFAULT_DIR}",
        dirs::home_dir().expect("Home directory not found").to_str().unwrap()
    ));
    let datapath = format!("{}/{}", datadir, network.to_string());
    fs::create_dir_all(&datapath).expect("mkdir datapath");

    let _tracing_guard = init_tracing_subscriber(&datapath, &bin_name)
        .expect("failed to initalize tracing subscriber");

    tracing::info!("{} git_desc={} starting", bin_name, vls_util::GIT_DESC);

    if let Some(ref address) = args.recover_to {
        let recover_type = match args.recover_type.as_str() {
            "bitcoind" => BlockExplorerType::Bitcoind,
            "esplora" => BlockExplorerType::Esplora,
            _ => panic!("unknown recover type"),
        };
        let (root_handler, _muts) = make_handler(&datadir, &args);
        let node = root_handler.node().clone();
        if address != "none" {
            node.set_allowlist(&[address.to_string()]).expect("add destination to allowlist");
        }
        let keys = DirectRecoveryKeys { node };
        if let Some(max_index) = args.recover_l1_range {
            recover_l1(network, recover_type, args.recover_rpc, &address, keys, max_index).await;
        } else {
            recover_close(network, recover_type, args.recover_rpc, &address, keys).await;
        }
        return;
    }

    if our_args.connect.is_none() {
        Args::command()
            .error(ErrorKind::MissingRequiredArgument, "missing --connect argument")
            .exit();
    }

    let uri = our_args.connect.expect("connect URL");
    if network == Network::Bitcoin && args.integration_test {
        panic!("integration-test mode not supported on mainnet");
    }
    start_signer(&datadir, uri, &args, shutdown_signal).await;
}