#[macro_use]
extern crate clap;
#[macro_use]
extern crate amplify;
use std::path::PathBuf;
use std::{fs, io};
use amplify::IoError;
use bitcoin::psbt::serialize::{Deserialize, Serialize};
use bitcoin::psbt::PsbtParseError;
use clap::Parser;
use colored::Colorize;
use commit_verify::EmbedCommitVerify;
use dbc::anchor::PsbtEmbeddedMessage;
use dbc::tapret::PsbtCommitError;
use psbt::Psbt;
#[derive(Parser)]
#[derive(Clone, Eq, PartialEq, Debug)]
#[clap(
author,
version,
name = "dbc",
about = "Command-line tool for deterministic bitcoin commitments"
)]
pub struct Args {
#[clap(subcommand)]
pub command: Command,
}
#[allow(clippy::large_enum_variant)]
#[derive(Subcommand)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub enum Command {
Commit {
psbt_in: PathBuf,
psbt_out: Option<PathBuf>,
},
}
impl Args {
pub fn exec(self) -> Result<(), Error> {
match self.command {
Command::Commit { psbt_in, psbt_out } => {
let psbt_bytes = fs::read(&psbt_in)?;
let mut psbt = Psbt::deserialize(&psbt_bytes)?;
let anchor = psbt.embed_commit(&PsbtEmbeddedMessage)?;
eprintln!("Anchor: {:?}", anchor);
let psbt_bytes = psbt.serialize();
fs::write(psbt_out.unwrap_or(psbt_in), psbt_bytes)?;
}
}
Ok(())
}
}
#[derive(Debug, Display, Error, From)]
#[display(inner)]
pub enum Error {
#[from(io::Error)]
Io(IoError),
#[from]
BitcoinEncoding(bitcoin::consensus::encode::Error),
#[from]
StrictEncoding(strict_encoding::Error),
#[from]
PsbtBase58(PsbtParseError),
#[from]
#[display(inner)]
Commitment(PsbtCommitError),
}
fn main() {
let args = Args::parse();
if let Err(err) = args.exec() {
eprintln!("{}: {}\n", "Error".bright_red(), err);
}
}