Use bitcoin's base64 feature for Psbts
This commit is contained in:
parent
12de13b95c
commit
fe371f9d92
@ -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"
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
11
src/lib.rs
11
src/lib.rs
@ -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())?;
|
||||||
//!
|
//!
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user