Use bitcoin's base64 feature for Psbts

This commit is contained in:
Riccardo Casatta 2021-06-10 15:14:00 +02:00
parent 12de13b95c
commit fe371f9d92
No known key found for this signature in database
GPG Key ID: FD986A969E450397
5 changed files with 18 additions and 21 deletions

View File

@ -15,7 +15,7 @@ license = "MIT OR Apache-2.0"
bdk-macros = "^0.4" bdk-macros = "^0.4"
log = "^0.4" log = "^0.4"
miniscript = "5.1" miniscript = "5.1"
bitcoin = { version = "^0.26", features = ["use-serde"] } bitcoin = { version = "~0.26.2", features = ["use-serde", "base64"] }
serde = { version = "^1.0", features = ["derive"] } serde = { version = "^1.0", features = ["derive"] }
serde_json = { version = "^1.0" } serde_json = { version = "^1.0" }
rand = "^0.7" rand = "^0.7"
@ -64,7 +64,6 @@ test-md-docs = ["electrum"]
[dev-dependencies] [dev-dependencies]
lazy_static = "1.4" lazy_static = "1.4"
env_logger = "0.7" env_logger = "0.7"
base64 = "^0.11"
clap = "2.33" clap = "2.33"
serial_test = "0.4" serial_test = "0.4"

View File

@ -1007,7 +1007,6 @@ mod test {
use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor}; use crate::descriptor::{ExtractPolicy, IntoWalletDescriptor};
use super::*; use super::*;
use crate::bitcoin::consensus::deserialize;
use crate::descriptor::derived::AsDerived; use crate::descriptor::derived::AsDerived;
use crate::descriptor::policy::SatisfiableItem::{Multisig, Signature, Thresh}; use crate::descriptor::policy::SatisfiableItem::{Multisig, Signature, Thresh};
use crate::keys::{DescriptorKey, IntoDescriptorKey}; use crate::keys::{DescriptorKey, IntoDescriptorKey};
@ -1475,7 +1474,7 @@ mod test {
let signers_container = Arc::new(SignersContainer::from(keymap)); let signers_container = Arc::new(SignersContainer::from(keymap));
let psbt: Psbt = deserialize(&base64::decode(ALICE_SIGNED_PSBT).unwrap()).unwrap(); let psbt = Psbt::from_str(ALICE_SIGNED_PSBT).unwrap();
let policy_alice_psbt = wallet_desc let policy_alice_psbt = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp) .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
@ -1490,7 +1489,7 @@ mod test {
) )
); );
let psbt: Psbt = deserialize(&base64::decode(BOB_SIGNED_PSBT).unwrap()).unwrap(); let psbt = Psbt::from_str(BOB_SIGNED_PSBT).unwrap();
let policy_bob_psbt = wallet_desc let policy_bob_psbt = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp) .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
.unwrap() .unwrap()
@ -1504,7 +1503,7 @@ mod test {
) )
); );
let psbt: Psbt = deserialize(&base64::decode(ALICE_BOB_SIGNED_PSBT).unwrap()).unwrap(); let psbt = Psbt::from_str(ALICE_BOB_SIGNED_PSBT).unwrap();
let policy_alice_bob_psbt = wallet_desc let policy_alice_bob_psbt = wallet_desc
.extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp) .extract_policy(&signers_container, BuildSatisfaction::Psbt(&psbt), &secp)
.unwrap() .unwrap()
@ -1545,8 +1544,7 @@ mod test {
addr.to_string() addr.to_string()
); );
let psbt: Psbt = let psbt = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED).unwrap();
deserialize(&base64::decode(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED).unwrap()).unwrap();
let build_sat = BuildSatisfaction::PsbtTimelocks { let build_sat = BuildSatisfaction::PsbtTimelocks {
psbt: &psbt, psbt: &psbt,
@ -1584,9 +1582,7 @@ mod test {
); );
//println!("{}", serde_json::to_string(&policy_expired).unwrap()); //println!("{}", serde_json::to_string(&policy_expired).unwrap());
let psbt_signed: Psbt = let psbt_signed = Psbt::from_str(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED).unwrap();
deserialize(&base64::decode(PSBT_POLICY_CONSIDER_TIMELOCK_EXPIRED_SIGNED).unwrap())
.unwrap();
let build_sat_expired_signed = BuildSatisfaction::PsbtTimelocks { let build_sat_expired_signed = BuildSatisfaction::PsbtTimelocks {
psbt: &psbt_signed, psbt: &psbt_signed,

View File

@ -106,6 +106,8 @@ pub enum Error {
Hex(bitcoin::hashes::hex::Error), Hex(bitcoin::hashes::hex::Error),
/// Partially signed bitcoin transaction error /// Partially signed bitcoin transaction error
Psbt(bitcoin::util::psbt::Error), Psbt(bitcoin::util::psbt::Error),
/// Partially signed bitcoin transaction parseerror
PsbtParse(bitcoin::util::psbt::PsbtParseError),
//KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey), //KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey),
//MissingInputUTXO(usize), //MissingInputUTXO(usize),
@ -172,6 +174,7 @@ impl_error!(bitcoin::secp256k1::Error, Secp256k1);
impl_error!(serde_json::Error, Json); impl_error!(serde_json::Error, Json);
impl_error!(bitcoin::hashes::hex::Error, Hex); impl_error!(bitcoin::hashes::hex::Error, Hex);
impl_error!(bitcoin::util::psbt::Error, Psbt); impl_error!(bitcoin::util::psbt::Error, Psbt);
impl_error!(bitcoin::util::psbt::PsbtParseError, PsbtParse);
#[cfg(feature = "electrum")] #[cfg(feature = "electrum")]
impl_error!(electrum_client::Error, Electrum); impl_error!(electrum_client::Error, Electrum);

View File

@ -104,8 +104,6 @@ fn main() -> Result<(), bdk::Error> {
### Example ### Example
```no_run ```no_run
use base64::decode;
use bdk::{FeeRate, Wallet}; use bdk::{FeeRate, Wallet};
use bdk::database::MemoryDatabase; use bdk::database::MemoryDatabase;
use bdk::blockchain::{noop_progress, ElectrumBlockchain}; use bdk::blockchain::{noop_progress, ElectrumBlockchain};
@ -138,7 +136,7 @@ fn main() -> Result<(), bdk::Error> {
}; };
println!("Transaction details: {:#?}", details); println!("Transaction details: {:#?}", details);
println!("Unsigned PSBT: {}", base64::encode(&serialize(&psbt))); println!("Unsigned PSBT: {}", &psbt);
Ok(()) Ok(())
} }
@ -150,8 +148,9 @@ fn main() -> Result<(), bdk::Error> {
//! //!
//! ### Example //! ### Example
//! ```no_run //! ```no_run
//! use base64::decode; //! use std::str::FromStr;
//! use bitcoin::consensus::deserialize; //!
//! use bitcoin::util::psbt::PartiallySignedTransaction as Psbt;
//! //!
//! use bdk::{Wallet, SignOptions}; //! use bdk::{Wallet, SignOptions};
//! use bdk::database::MemoryDatabase; //! use bdk::database::MemoryDatabase;
@ -165,7 +164,7 @@ fn main() -> Result<(), bdk::Error> {
//! )?; //! )?;
//! //!
//! let psbt = "..."; //! let psbt = "...";
//! let mut psbt = deserialize(&base64::decode(psbt).unwrap())?; //! let mut psbt = Psbt::from_str(psbt)?;
//! //!
//! let finalized = wallet.sign(&mut psbt, SignOptions::default())?; //! let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
//! //!

View File

@ -41,12 +41,12 @@ impl PsbtUtils for Psbt {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::bitcoin::consensus::deserialize;
use crate::bitcoin::TxIn; use crate::bitcoin::TxIn;
use crate::psbt::Psbt; use crate::psbt::Psbt;
use crate::wallet::test::{get_funded_wallet, get_test_wpkh}; use crate::wallet::test::{get_funded_wallet, get_test_wpkh};
use crate::wallet::AddressIndex; use crate::wallet::AddressIndex;
use crate::SignOptions; use crate::SignOptions;
use std::str::FromStr;
// from bip 174 // from bip 174
const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA"; const PSBT_STR: &str = "cHNidP8BAKACAAAAAqsJSaCMWvfEm4IS9Bfi8Vqz9cM9zxU4IagTn4d6W3vkAAAAAAD+////qwlJoIxa98SbghL0F+LxWrP1wz3PFTghqBOfh3pbe+QBAAAAAP7///8CYDvqCwAAAAAZdqkUdopAu9dAy+gdmI5x3ipNXHE5ax2IrI4kAAAAAAAAGXapFG9GILVT+glechue4O/p+gOcykWXiKwAAAAAAAEHakcwRAIgR1lmF5fAGwNrJZKJSGhiGDR9iYZLcZ4ff89X0eURZYcCIFMJ6r9Wqk2Ikf/REf3xM286KdqGbX+EhtdVRs7tr5MZASEDXNxh/HupccC1AaZGoqg7ECy0OIEhfKaC3Ibi1z+ogpIAAQEgAOH1BQAAAAAXqRQ1RebjO4MsRwUPJNPuuTycA5SLx4cBBBYAFIXRNTfy4mVAWjTbr6nj3aAfuCMIAAAA";
@ -54,7 +54,7 @@ mod test {
#[test] #[test]
#[should_panic(expected = "InputIndexOutOfRange")] #[should_panic(expected = "InputIndexOutOfRange")]
fn test_psbt_malformed_psbt_input_legacy() { fn test_psbt_malformed_psbt_input_legacy() {
let psbt_bip: Psbt = deserialize(&base64::decode(PSBT_STR).unwrap()).unwrap(); let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
let send_to = wallet.get_address(AddressIndex::New).unwrap(); let send_to = wallet.get_address(AddressIndex::New).unwrap();
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -71,7 +71,7 @@ mod test {
#[test] #[test]
#[should_panic(expected = "InputIndexOutOfRange")] #[should_panic(expected = "InputIndexOutOfRange")]
fn test_psbt_malformed_psbt_input_segwit() { fn test_psbt_malformed_psbt_input_segwit() {
let psbt_bip: Psbt = deserialize(&base64::decode(PSBT_STR).unwrap()).unwrap(); let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
let send_to = wallet.get_address(AddressIndex::New).unwrap(); let send_to = wallet.get_address(AddressIndex::New).unwrap();
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();
@ -103,7 +103,7 @@ mod test {
#[test] #[test]
fn test_psbt_sign_with_finalized() { fn test_psbt_sign_with_finalized() {
let psbt_bip: Psbt = deserialize(&base64::decode(PSBT_STR).unwrap()).unwrap(); let psbt_bip = Psbt::from_str(PSBT_STR).unwrap();
let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); let (wallet, _, _) = get_funded_wallet(get_test_wpkh());
let send_to = wallet.get_address(AddressIndex::New).unwrap(); let send_to = wallet.get_address(AddressIndex::New).unwrap();
let mut builder = wallet.build_tx(); let mut builder = wallet.build_tx();