Merge bitcoindevkit/bdk-ffi#104: Add PSBT deserialize and serialize functions, remove details
c039281ffcbaab8048ff87426a413c953a1e5ece Add PSBT deserialize and serialize functions, remove details (Steve Myers) 1f0b053872889f5dff340035a9e3cd3488688152 Fix bin/generate with no features (Steve Myers) Pull request description: 1. Fix bin/generate with no features 2. Add `PartiallySignedBitcoinTransaction::deserialize` function as named constructor to decode from a string per [BIP 0174] 3. Add `PartiallySignedBitcoinTransaction::serialize` function to encode to a string per [BIP 0174] 4. Remove `PartiallySignedBitcoinTransaction.details` struct field [BIP 0174]:https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki#encoding Fixes #103 Top commit has no ACKs. Tree-SHA512: 0ba34d96625d71434d41573089a150d09fcfb6439648a7eed6e36dcdddd2682c969525b7c6efda898b2f979a7ca6ce51dc2158acf65da7f1f4c554d98b60f4ff
This commit is contained in:
commit
cafa8dacab
@ -131,6 +131,9 @@ interface Wallet {
|
|||||||
interface PartiallySignedBitcoinTransaction {
|
interface PartiallySignedBitcoinTransaction {
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
constructor([ByRef] Wallet wallet, string recipient, u64 amount, float? fee_rate);
|
constructor([ByRef] Wallet wallet, string recipient, u64 amount, float? fee_rate);
|
||||||
|
[Name=deserialize,Throws=BdkError]
|
||||||
|
constructor(string psbt_base64);
|
||||||
|
string serialize();
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary ExtendedKeyInfo {
|
dictionary ExtendedKeyInfo {
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
use std::env;
|
pub const BDK_UDL: &str = "src/bdk.udl";
|
||||||
use std::fs;
|
|
||||||
use std::io::Write;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
const BDK_UDL: &str = "src/bdk.udl";
|
#[cfg(feature = "generate-python")]
|
||||||
|
fn fixup_python_lib_path<O: AsRef<std::path::Path>>(
|
||||||
fn fixup_python_lib_path<O: AsRef<Path>>(
|
|
||||||
out_dir: O,
|
out_dir: O,
|
||||||
lib_name: &str,
|
lib_name: &str,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
use std::fs;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
const LOAD_INDIRECT_DEF: &str = "def loadIndirect():";
|
const LOAD_INDIRECT_DEF: &str = "def loadIndirect():";
|
||||||
|
|
||||||
let bindings_file = out_dir.as_ref().join("bdk.py");
|
let bindings_file = out_dir.as_ref().join("bdk.py");
|
||||||
@ -40,10 +39,19 @@ def _loadIndirectOld():"#,
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "generate-python")]
|
||||||
fn generate_python() -> Result<(), Box<dyn std::error::Error>> {
|
fn generate_python() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
use std::env;
|
||||||
|
|
||||||
let out_path = env::var("GENERATE_PYTHON_BINDINGS_OUT")
|
let out_path = env::var("GENERATE_PYTHON_BINDINGS_OUT")
|
||||||
.map_err(|_| String::from("`GENERATE_PYTHON_BINDINGS_OUT` env variable missing"))?;
|
.map_err(|_| String::from("`GENERATE_PYTHON_BINDINGS_OUT` env variable missing"))?;
|
||||||
uniffi_bindgen::generate_bindings(&format!("{}/{}", env!("CARGO_MANIFEST_DIR"), BDK_UDL), None, vec!["python"], Some(&out_path), false)?;
|
uniffi_bindgen::generate_bindings(
|
||||||
|
&format!("{}/{}", env!("CARGO_MANIFEST_DIR"), BDK_UDL),
|
||||||
|
None,
|
||||||
|
vec!["python"],
|
||||||
|
Some(&out_path),
|
||||||
|
false,
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(name) = env::var("GENERATE_PYTHON_BINDINGS_FIXUP_LIB_PATH").ok() {
|
if let Some(name) = env::var("GENERATE_PYTHON_BINDINGS_FIXUP_LIB_PATH").ok() {
|
||||||
fixup_python_lib_path(&out_path, &name)?;
|
fixup_python_lib_path(&out_path, &name)?;
|
||||||
@ -53,5 +61,7 @@ fn generate_python() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
generate_python()
|
#[cfg(feature = "generate-python")]
|
||||||
|
generate_python()?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
26
src/lib.rs
26
src/lib.rs
@ -12,7 +12,7 @@ use bdk::keys::bip39::{Language, Mnemonic, WordCount};
|
|||||||
use bdk::keys::{DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey};
|
use bdk::keys::{DerivableKey, ExtendedKey, GeneratableKey, GeneratedKey};
|
||||||
use bdk::miniscript::BareCtx;
|
use bdk::miniscript::BareCtx;
|
||||||
use bdk::wallet::AddressIndex;
|
use bdk::wallet::AddressIndex;
|
||||||
use bdk::{BlockTime, Error, FeeRate, SignOptions, Wallet as BdkWallet };
|
use bdk::{BlockTime, Error, FeeRate, SignOptions, Wallet as BdkWallet};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Mutex, MutexGuard};
|
use std::sync::{Mutex, MutexGuard};
|
||||||
@ -155,7 +155,6 @@ impl Progress for BdkProgressHolder {
|
|||||||
|
|
||||||
struct PartiallySignedBitcoinTransaction {
|
struct PartiallySignedBitcoinTransaction {
|
||||||
internal: Mutex<PartiallySignedTransaction>,
|
internal: Mutex<PartiallySignedTransaction>,
|
||||||
details: bdk::TransactionDetails,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartiallySignedBitcoinTransaction {
|
impl PartiallySignedBitcoinTransaction {
|
||||||
@ -168,7 +167,7 @@ impl PartiallySignedBitcoinTransaction {
|
|||||||
let wallet = wallet.get_wallet();
|
let wallet = wallet.get_wallet();
|
||||||
match Address::from_str(&recipient) {
|
match Address::from_str(&recipient) {
|
||||||
Ok(address) => {
|
Ok(address) => {
|
||||||
let (psbt, details) = {
|
let (psbt, _details) = {
|
||||||
let mut builder = wallet.build_tx();
|
let mut builder = wallet.build_tx();
|
||||||
builder.add_recipient(address.script_pubkey(), amount);
|
builder.add_recipient(address.script_pubkey(), amount);
|
||||||
if let Some(sat_per_vb) = fee_rate {
|
if let Some(sat_per_vb) = fee_rate {
|
||||||
@ -178,7 +177,6 @@ impl PartiallySignedBitcoinTransaction {
|
|||||||
};
|
};
|
||||||
Ok(PartiallySignedBitcoinTransaction {
|
Ok(PartiallySignedBitcoinTransaction {
|
||||||
internal: Mutex::new(psbt),
|
internal: Mutex::new(psbt),
|
||||||
details,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(..) => Err(BdkError::Generic(
|
Err(..) => Err(BdkError::Generic(
|
||||||
@ -186,6 +184,18 @@ impl PartiallySignedBitcoinTransaction {
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deserialize(psbt_base64: String) -> Result<Self, Error> {
|
||||||
|
let psbt: PartiallySignedTransaction = PartiallySignedTransaction::from_str(&psbt_base64)?;
|
||||||
|
Ok(PartiallySignedBitcoinTransaction {
|
||||||
|
internal: Mutex::new(psbt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(&self) -> String {
|
||||||
|
let psbt = self.internal.lock().unwrap().clone();
|
||||||
|
psbt.to_string()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WalletHolder<AnyBlockchain> for Wallet {
|
impl WalletHolder<AnyBlockchain> for Wallet {
|
||||||
@ -254,13 +264,11 @@ impl Wallet {
|
|||||||
.sync(BdkProgressHolder { progress_update }, max_address_param)
|
.sync(BdkProgressHolder { progress_update }, max_address_param)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn broadcast(
|
fn broadcast(&self, psbt: &PartiallySignedBitcoinTransaction) -> Result<Transaction, Error> {
|
||||||
&self,
|
|
||||||
psbt: &PartiallySignedBitcoinTransaction,
|
|
||||||
) -> Result<Transaction, Error> {
|
|
||||||
let tx = psbt.internal.lock().unwrap().clone().extract_tx();
|
let tx = psbt.internal.lock().unwrap().clone().extract_tx();
|
||||||
self.get_wallet().broadcast(&tx)?;
|
self.get_wallet().broadcast(&tx)?;
|
||||||
Ok(Transaction::from(&psbt.details))
|
let tx_details = self.get_wallet().get_tx(&tx.txid(), true)?;
|
||||||
|
Ok(Transaction::from(&tx_details.unwrap()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user