Skip to content

Commit 7dbbb23

Browse files
committed
refactor(wallet)!: Add SignError and use as error type for Wallet::sign() and Wallet::finalize_psbt()
1 parent f883ed5 commit 7dbbb23

File tree

5 files changed

+46
-35
lines changed

5 files changed

+46
-35
lines changed

crates/bdk/src/error.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,14 @@ pub enum Error {
3232
Key(crate::keys::KeyError),
3333
/// Descriptor checksum mismatch
3434
ChecksumMismatch,
35-
/// Signing error
36-
Signer(crate::wallet::signer::SignerError),
3735
/// Requested outpoint doesn't exist in the tx (vout greater than available outputs)
3836
InvalidOutpoint(OutPoint),
3937
/// Error related to the parsing and usage of descriptors
4038
Descriptor(crate::descriptor::error::Error),
4139
/// Miniscript error
4240
Miniscript(miniscript::Error),
43-
/// Miniscript PSBT error
44-
MiniscriptPsbt(MiniscriptPsbtError),
4541
/// BIP32 error
4642
Bip32(bitcoin::bip32::Error),
47-
/// Partially signed bitcoin transaction error
48-
Psbt(bitcoin::psbt::Error),
4943
}
5044

5145
/// Errors returned by miniscript when updating inconsistent PSBTs
@@ -81,17 +75,14 @@ impl fmt::Display for Error {
8175
Self::FeeRateUnavailable => write!(f, "Fee rate unavailable"),
8276
Self::Key(err) => write!(f, "Key error: {}", err),
8377
Self::ChecksumMismatch => write!(f, "Descriptor checksum mismatch"),
84-
Self::Signer(err) => write!(f, "Signer error: {}", err),
8578
Self::InvalidOutpoint(outpoint) => write!(
8679
f,
8780
"Requested outpoint doesn't exist in the tx: {}",
8881
outpoint
8982
),
9083
Self::Descriptor(err) => write!(f, "Descriptor error: {}", err),
9184
Self::Miniscript(err) => write!(f, "Miniscript error: {}", err),
92-
Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {}", err),
9385
Self::Bip32(err) => write!(f, "BIP32 error: {}", err),
94-
Self::Psbt(err) => write!(f, "PSBT error: {}", err),
9586
}
9687
}
9788
}
@@ -113,7 +104,6 @@ macro_rules! impl_error {
113104
}
114105

115106
impl_error!(descriptor::error::Error, Descriptor);
116-
impl_error!(wallet::signer::SignerError, Signer);
117107

118108
impl From<crate::keys::KeyError> for Error {
119109
fn from(key_error: crate::keys::KeyError) -> Error {
@@ -127,9 +117,7 @@ impl From<crate::keys::KeyError> for Error {
127117
}
128118

129119
impl_error!(miniscript::Error, Miniscript);
130-
impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
131120
impl_error!(bitcoin::bip32::Error, Bip32);
132-
impl_error!(bitcoin::psbt::Error, Psbt);
133121

134122
#[derive(Debug)]
135123
/// Error returned from [`TxBuilder::finish`]
@@ -394,3 +382,27 @@ impl fmt::Display for BuildFeeBumpError {
394382

395383
#[cfg(feature = "std")]
396384
impl std::error::Error for BuildFeeBumpError {}
385+
386+
#[derive(Debug)]
387+
/// Error returned from [`Wallet::sign`]
388+
///
389+
/// [`Wallet::sign`]: wallet::Wallet::sign
390+
pub enum SignError {
391+
/// Signing error
392+
Signer(wallet::signer::SignerError),
393+
/// Miniscript PSBT error
394+
MiniscriptPsbt(MiniscriptPsbtError),
395+
}
396+
397+
#[cfg(feature = "std")]
398+
impl fmt::Display for SignError {
399+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400+
match self {
401+
Self::Signer(err) => write!(f, "Signer error: {}", err),
402+
Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {}", err),
403+
}
404+
}
405+
}
406+
407+
#[cfg(feature = "std")]
408+
impl std::error::Error for SignError {}

crates/bdk/src/wallet/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use crate::descriptor::{
6767
calc_checksum, into_wallet_descriptor_checked, DerivedDescriptor, DescriptorMeta,
6868
ExtendedDescriptor, ExtractPolicy, IntoWalletDescriptor, Policy, XKeyUtils,
6969
};
70-
use crate::error::{BuildFeeBumpError, CreateTxError, Error, MiniscriptPsbtError};
70+
use crate::error::{BuildFeeBumpError, CreateTxError, Error, MiniscriptPsbtError, SignError};
7171
use crate::psbt::PsbtUtils;
7272
use crate::signer::SignerError;
7373
use crate::types::*;
@@ -1702,27 +1702,28 @@ impl<D> Wallet<D> {
17021702
/// # use bitcoin::*;
17031703
/// # use bdk::*;
17041704
/// # use bdk::wallet::ChangeSet;
1705-
/// # use bdk::error::CreateTxError;
1705+
/// # use bdk::error::{CreateTxError, SignError};
17061706
/// # use bdk_chain::PersistBackend;
17071707
/// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
17081708
/// # let mut wallet = doctest_wallet!();
17091709
/// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
17101710
/// let mut psbt = {
17111711
/// let mut builder = wallet.build_tx();
17121712
/// builder.add_recipient(to_address.script_pubkey(), 50_000);
1713-
/// builder.finish().expect("psbt")
1713+
/// builder.finish()?
17141714
/// };
17151715
/// let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
17161716
/// assert!(finalized, "we should have signed all the inputs");
1717-
/// # Ok::<(), bdk::Error>(())
1717+
/// # Ok::<(),anyhow::Error>(())
17181718
pub fn sign(
17191719
&self,
17201720
psbt: &mut psbt::PartiallySignedTransaction,
17211721
sign_options: SignOptions,
1722-
) -> Result<bool, Error> {
1722+
) -> Result<bool, SignError> {
17231723
// This adds all the PSBT metadata for the inputs, which will help us later figure out how
17241724
// to derive our keys
1725-
self.update_psbt_with_descriptor(psbt)?;
1725+
self.update_psbt_with_descriptor(psbt)
1726+
.map_err(SignError::MiniscriptPsbt)?;
17261727

17271728
// If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones)
17281729
// has the `non_witness_utxo`
@@ -1734,7 +1735,7 @@ impl<D> Wallet<D> {
17341735
.filter(|i| i.tap_internal_key.is_none() && i.tap_merkle_root.is_none())
17351736
.any(|i| i.non_witness_utxo.is_none())
17361737
{
1737-
return Err(Error::Signer(signer::SignerError::MissingNonWitnessUtxo));
1738+
return Err(SignError::Signer(SignerError::MissingNonWitnessUtxo));
17381739
}
17391740

17401741
// If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
@@ -1747,7 +1748,7 @@ impl<D> Wallet<D> {
17471748
|| i.sighash_type == Some(TapSighashType::Default.into())
17481749
})
17491750
{
1750-
return Err(Error::Signer(signer::SignerError::NonStandardSighash));
1751+
return Err(SignError::Signer(SignerError::NonStandardSighash));
17511752
}
17521753

17531754
for signer in self
@@ -1756,7 +1757,9 @@ impl<D> Wallet<D> {
17561757
.iter()
17571758
.chain(self.change_signers.signers().iter())
17581759
{
1759-
signer.sign_transaction(psbt, &sign_options, &self.secp)?;
1760+
signer
1761+
.sign_transaction(psbt, &sign_options, &self.secp)
1762+
.map_err(SignError::Signer)?;
17601763
}
17611764

17621765
// attempt to finalize
@@ -1800,8 +1803,8 @@ impl<D> Wallet<D> {
18001803
&self,
18011804
psbt: &mut psbt::PartiallySignedTransaction,
18021805
sign_options: SignOptions,
1803-
) -> Result<bool, Error> {
1804-
let chain_tip = self.chain.tip().block_id();
1806+
) -> Result<bool, SignerError> {
1807+
let chain_tip = self.chain.tip().map(|cp| cp.block_id()).unwrap_or_default();
18051808

18061809
let tx = &psbt.unsigned_tx;
18071810
let mut finished = true;
@@ -1810,7 +1813,7 @@ impl<D> Wallet<D> {
18101813
let psbt_input = &psbt
18111814
.inputs
18121815
.get(n)
1813-
.ok_or(Error::Signer(SignerError::InputIndexOutOfRange))?;
1816+
.ok_or(SignerError::Signer(SignerError::InputIndexOutOfRange))?;
18141817
if psbt_input.final_script_sig.is_some() || psbt_input.final_script_witness.is_some() {
18151818
continue;
18161819
}

crates/bdk/tests/wallet.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::str::FromStr;
22

33
use assert_matches::assert_matches;
44
use bdk::descriptor::calc_checksum;
5-
use bdk::error::CreateTxError;
5+
use bdk::error::{CreateTxError, SignError};
66
use bdk::psbt::PsbtUtils;
77
use bdk::signer::{SignOptions, SignerError};
88
use bdk::wallet::coin_selection::{self, LargestFirstCoinSelection};
@@ -2528,7 +2528,7 @@ fn test_sign_nonstandard_sighash() {
25282528
);
25292529
assert_matches!(
25302530
result,
2531-
Err(bdk::Error::Signer(SignerError::NonStandardSighash)),
2531+
Err(SignError::Signer(SignerError::NonStandardSighash)),
25322532
"Signing failed with the wrong error type"
25332533
);
25342534

@@ -2945,7 +2945,7 @@ fn test_taproot_sign_missing_witness_utxo() {
29452945
);
29462946
assert_matches!(
29472947
result,
2948-
Err(bdk::Error::Signer(SignerError::MissingWitnessUtxo)),
2948+
Err(SignError::Signer(SignerError::MissingWitnessUtxo)),
29492949
"Signing should have failed with the correct error because the witness_utxo is missing"
29502950
);
29512951

@@ -3286,7 +3286,7 @@ fn test_taproot_sign_non_default_sighash() {
32863286
);
32873287
assert_matches!(
32883288
result,
3289-
Err(bdk::Error::Signer(SignerError::NonStandardSighash)),
3289+
Err(SignError::Signer(SignerError::NonStandardSighash)),
32903290
"Signing failed with the wrong error type"
32913291
);
32923292

@@ -3304,7 +3304,7 @@ fn test_taproot_sign_non_default_sighash() {
33043304
);
33053305
assert_matches!(
33063306
result,
3307-
Err(bdk::Error::Signer(SignerError::MissingWitnessUtxo)),
3307+
Err(SignError::Signer(SignerError::MissingWitnessUtxo)),
33083308
"Signing failed with the wrong error type"
33093309
);
33103310

example-crates/wallet_esplora_async/src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
2727
Network::Testnet,
2828
)?;
2929

30-
let address = wallet
31-
.try_get_address(AddressIndex::New)
32-
.expect("new address");
30+
let address = wallet.try_get_address(AddressIndex::New)?;
3331
println!("Generated Address: {}", address);
3432

3533
let balance = wallet.get_balance();

example-crates/wallet_esplora_blocking/src/main.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
2626
Network::Testnet,
2727
)?;
2828

29-
let address = wallet
30-
.try_get_address(AddressIndex::New)
31-
.expect("new address");
29+
let address = wallet.try_get_address(AddressIndex::New)?;
3230
println!("Generated Address: {}", address);
3331

3432
let balance = wallet.get_balance();

0 commit comments

Comments
 (0)