Merge bitcoindevkit/bdk-ffi#209: Change TxBuilder.finish() to return new TxBuilderResult

fadb316451af080bf22774a164278cef04acd9cc Change TxBuilder.finish() to return new TxBuilderResult (Steve Myers)

Pull request description:

  ### Description

  Change TxBuilder.finish() to return new TxBuilderResult.

  ### Notes to the reviewers

  This fixes #179 in that it return both PartiallySignedBitcoinTransaction and TransactionDetails encapsulated in a new TxBuilderResult structure. It does not calculate the fee rate which requires #208.

  ### Changelog notice

  - Breaking Changes
    - Changed `TxBuilder.finish()` to return new `TxBuilderResult`.
  - APIs Added
    - Added `TxBuilderResult` with PSBT and TransactionDetails.

  ### Checklists

  #### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  #### New Features:

  * [x] I've added tests for the new feature
  * [x] I've added docs for the new feature

ACKs for top commit:
  thunderbiscuit:
    ACK [fadb316](fadb316451).

Tree-SHA512: b8aafc53ba86bf7ab12ae3d5bb251d1ec5cb54e4b7d6bfc342155d5cd3726d9a6d114591dc740a7467afb8ef402f3d77ad51e273a27865d6e47192291b570af9
This commit is contained in:
Steve Myers 2022-10-19 12:29:46 -05:00
commit 1f914c2b4d
No known key found for this signature in database
GPG Key ID: 8105A46B22C2D051
2 changed files with 33 additions and 8 deletions

View File

@ -217,6 +217,11 @@ interface PartiallySignedBitcoinTransaction {
PartiallySignedBitcoinTransaction combine(PartiallySignedBitcoinTransaction other);
};
dictionary TxBuilderResult {
PartiallySignedBitcoinTransaction psbt;
TransactionDetails transaction_details;
};
interface TxBuilder {
constructor();
@ -253,7 +258,7 @@ interface TxBuilder {
TxBuilder set_recipients(sequence<ScriptAmount> recipients);
[Throws=Error]
PartiallySignedBitcoinTransaction finish([ByRef] Wallet wallet);
TxBuilderResult finish([ByRef] Wallet wallet);
};
interface BumpFeeTxBuilder {

View File

@ -340,7 +340,7 @@ impl fmt::Debug for ProgressHolder {
}
#[derive(Debug)]
struct PartiallySignedBitcoinTransaction {
pub struct PartiallySignedBitcoinTransaction {
internal: Mutex<PartiallySignedTransaction>,
}
@ -528,6 +528,13 @@ enum RbfValue {
Value(u32),
}
/// The result after calling the TxBuilder finish() function. Contains unsigned PSBT and
/// transaction details.
pub struct TxBuilderResult {
pub psbt: Arc<PartiallySignedBitcoinTransaction>,
pub transaction_details: TransactionDetails,
}
/// A transaction builder.
/// After creating the TxBuilder, you set options on it until finally calling finish to consume the builder and generate the transaction.
/// Each method on the TxBuilder returns an instance of a new TxBuilder with the option set/added.
@ -713,7 +720,7 @@ impl TxBuilder {
}
/// Finish building the transaction. Returns the BIP174 PSBT.
fn finish(&self, wallet: &Wallet) -> Result<Arc<PartiallySignedBitcoinTransaction>, Error> {
fn finish(&self, wallet: &Wallet) -> Result<TxBuilderResult, Error> {
let wallet = wallet.get_wallet();
let mut tx_builder = wallet.build_tx();
for (script, amount) in &self.recipients {
@ -761,10 +768,12 @@ impl TxBuilder {
tx_builder
.finish()
.map(|(psbt, _)| PartiallySignedBitcoinTransaction {
internal: Mutex::new(psbt),
.map(|(psbt, tx_details)| TxBuilderResult {
psbt: Arc::new(PartiallySignedBitcoinTransaction {
internal: Mutex::new(psbt),
}),
transaction_details: TransactionDetails::from(&tx_details),
})
.map(Arc::new)
}
}
@ -1058,8 +1067,9 @@ mod test {
assert!(tx_builder.drain_wallet);
assert_eq!(tx_builder.drain_to, Some(drain_to_address));
let psbt = tx_builder.finish(&test_wallet).unwrap();
let psbt = psbt.internal.lock().unwrap().clone();
let tx_builder_result = tx_builder.finish(&test_wallet).unwrap();
let psbt = tx_builder_result.psbt.internal.lock().unwrap().clone();
let tx_details = tx_builder_result.transaction_details;
// confirm one input with 50,000 sats
assert_eq!(psbt.inputs.len(), 1);
@ -1095,6 +1105,16 @@ mod test {
);
let output_value = psbt.unsigned_tx.output.get(0).cloned().unwrap().value;
assert_eq!(output_value, 49_890_u64); // input - fee
assert_eq!(
tx_details.txid,
"312f1733badab22dc26b8dcbc83ba5629fb7b493af802e8abe07d865e49629c5"
);
assert_eq!(tx_details.received, 0);
assert_eq!(tx_details.sent, 50000);
assert!(tx_details.fee.is_some());
assert_eq!(tx_details.fee.unwrap(), 110);
assert!(tx_details.confirmation_time.is_none());
}
fn get_descriptor_secret_key() -> DescriptorSecretKey {