Skip to content

Commit

Permalink
Merge pull request #81 from BP-WG/psbt/base64
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky authored Mar 20, 2024
2 parents 40b0d02 + e9f5380 commit 9851b2f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 20 deletions.
13 changes: 10 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions psbt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ bitcoin_hd = { workspace = true }
bitcoin_onchain = { workspace = true }
descriptors = { workspace = true, optional = true }
miniscript_crate = { workspace = true, optional = true }
base64 = "0.21.4"
serde_crate = { package = "serde", version = "1", optional = true }
serde_with = { version = "2.3", features = ["hex"], optional = true }

Expand Down
29 changes: 23 additions & 6 deletions psbt/src/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};
use std::str::FromStr;

use amplify::hex::{FromHex, ToHex};
use base64::Engine;
use bitcoin::util::bip32::{ExtendedPubKey, KeySource};
use bitcoin::{consensus, Transaction, Txid};
use bitcoin_blockchain::locks::LockTime;
Expand Down Expand Up @@ -295,17 +295,34 @@ impl Deserialize for Psbt {

impl Display for Psbt {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.serialize().to_hex())
let engine = base64::engine::GeneralPurpose::new(
&base64::alphabet::STANDARD,
base64::engine::GeneralPurposeConfig::new(),
);
f.write_str(&engine.encode(self.serialize()))
}
}

#[derive(Debug, Display, Error, From)]
#[display(inner)]
pub enum PsbtParseError {
#[from]
Data(consensus::encode::Error),

#[from]
Base64(base64::DecodeError),
}

impl FromStr for Psbt {
type Err = consensus::encode::Error;
type Err = PsbtParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Psbt::deserialize(
&Vec::<u8>::from_hex(s).map_err(|_| Self::Err::ParseFailed("invalid hex encoding"))?,
)
let engine = base64::engine::GeneralPurpose::new(
&base64::alphabet::STANDARD,
base64::engine::GeneralPurposeConfig::new(),
);
let bytes = engine.decode(s)?;
Psbt::deserialize(&bytes).map_err(PsbtParseError::from)
}
}

Expand Down
4 changes: 2 additions & 2 deletions psbt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ mod proprietary;
pub mod sign;

pub use bitcoin::psbt::raw::ProprietaryKey;
pub use bitcoin::psbt::{raw, serialize, Error, PsbtParseError, PsbtSighashType};
pub use bitcoin::psbt::{raw, serialize, Error, PsbtSighashType};
pub use errors::{FeeError, InputMatchError, TxError, TxinError};
pub use global::Psbt;
pub use global::{Psbt, PsbtParseError};
pub use input::Input;
pub use output::Output;
pub(crate) mod v0 {
Expand Down
29 changes: 20 additions & 9 deletions src/bin/btc-cold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,8 @@ impl Args {
let secp = Secp256k1::new();

let data = fs::read(psbt_path)?;
let mut psbt = consensus::encode::deserialize::<PartiallySignedTransaction>(&data)?;
let mut psbt = consensus::encode::deserialize::<PartiallySignedTransaction>(&data)
.map_err(Error::psbt_from_consensus)?;

psbt.finalize_mut(&secp).map_err(VecDisplay::from)?;

Expand Down Expand Up @@ -742,21 +743,21 @@ impl Args {
fn inspect(&self, path: Option<&PathBuf>) -> Result<(), Error> {
let psbt = if let Some(path) = path {
let data = fs::read(path)?;
Psbt::deserialize(&data)?
Psbt::deserialize(&data).map_err(Error::psbt_from_consensus)?
} else {
eprint!("Type in Base58 encoded PSBT and press enter: ");
stdout().flush()?;
let stdin = stdin();
let psbt58 = stdin.lock().lines().next().expect("no PSBT data")?;
Psbt::from_str(psbt58.trim())?
let psbt64 = stdin.lock().lines().next().expect("no PSBT data")?;
Psbt::from_str(psbt64.trim())?
};
println!("\n{}", serde_yaml::to_string(&psbt)?);
Ok(())
}

fn convert(&self, path: &Path) -> Result<(), Error> {
let data = fs::read(path)?;
let psbt = Psbt::deserialize(&data)?;
let psbt = Psbt::deserialize(&data).map_err(Error::psbt_from_consensus)?;
println!("\n{}\n", psbt);
Ok(())
}
Expand Down Expand Up @@ -927,7 +928,10 @@ pub enum Error {
Io(IoError),

#[from]
PsbtEncoding(consensus::encode::Error),
PsbtEncoding(psbt::Error),

#[from]
PsbtParse(PsbtParseError),

#[from]
Miniscript(miniscript::Error),
Expand All @@ -944,9 +948,6 @@ pub enum Error {
#[from]
Yaml(serde_yaml::Error),

#[from]
PsbtBase58(PsbtParseError),

#[from]
PsbtConstruction(construct::Error),

Expand Down Expand Up @@ -981,6 +982,16 @@ pub enum Error {
PsbtProprietaryKey(ProprietaryKeyError),
}

impl Error {
pub fn psbt_from_consensus(e: consensus::encode::Error) -> Error {
match e {
consensus::encode::Error::Psbt(e) => Error::PsbtEncoding(e),
consensus::encode::Error::Io(e) => e.into(),
err => unreachable!("{err:#?}"),
}
}
}

// TODO: Move to amplify crate
#[derive(Debug, From)]
pub struct VecDisplay<T, const PREFIX: bool, const PREFIX_CHAR: char, const JOIN_CHAR: char>(
Expand Down

0 comments on commit 9851b2f

Please sign in to comment.