Skip to content

Commit 59d829e

Browse files
committed
refactor(wallet)!: Add SignError and use as error type for Wallet::sign() and Wallet::finalize_psbt()
1 parent dfcd632 commit 59d829e

File tree

5 files changed

+45
-34
lines changed

5 files changed

+45
-34
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: 14 additions & 11 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::*;
@@ -1430,27 +1430,28 @@ impl<D> Wallet<D> {
14301430
/// # use bitcoin::*;
14311431
/// # use bdk::*;
14321432
/// # use bdk::wallet::ChangeSet;
1433-
/// # use bdk::error::CreateTxError;
1433+
/// # use bdk::error::{CreateTxError, SignError};
14341434
/// # use bdk_chain::PersistBackend;
14351435
/// # let descriptor = "wpkh(tpubD6NzVbkrYhZ4Xferm7Pz4VnjdcDPFyjVu5K4iZXQ4pVN8Cks4pHVowTBXBKRhX64pkRyJZJN5xAKj4UDNnLPb5p2sSKXhewoYx5GbTdUFWq/*)";
14361436
/// # let mut wallet = doctest_wallet!();
14371437
/// # let to_address = Address::from_str("2N4eQYCbKUHCCTUjBJeHcJp9ok6J2GZsTDt").unwrap().assume_checked();
14381438
/// let mut psbt = {
14391439
/// let mut builder = wallet.build_tx();
14401440
/// builder.add_recipient(to_address.script_pubkey(), 50_000);
1441-
/// builder.finish().expect("psbt")
1441+
/// builder.finish()?
14421442
/// };
14431443
/// let finalized = wallet.sign(&mut psbt, SignOptions::default())?;
14441444
/// assert!(finalized, "we should have signed all the inputs");
1445-
/// # Ok::<(), bdk::Error>(())
1445+
/// # Ok::<(),anyhow::Error>(())
14461446
pub fn sign(
14471447
&self,
14481448
psbt: &mut psbt::PartiallySignedTransaction,
14491449
sign_options: SignOptions,
1450-
) -> Result<bool, Error> {
1450+
) -> Result<bool, SignError> {
14511451
// This adds all the PSBT metadata for the inputs, which will help us later figure out how
14521452
// to derive our keys
1453-
self.update_psbt_with_descriptor(psbt)?;
1453+
self.update_psbt_with_descriptor(psbt)
1454+
.map_err(SignError::MiniscriptPsbt)?;
14541455

14551456
// If we aren't allowed to use `witness_utxo`, ensure that every input (except p2tr and finalized ones)
14561457
// has the `non_witness_utxo`
@@ -1462,7 +1463,7 @@ impl<D> Wallet<D> {
14621463
.filter(|i| i.tap_internal_key.is_none() && i.tap_merkle_root.is_none())
14631464
.any(|i| i.non_witness_utxo.is_none())
14641465
{
1465-
return Err(Error::Signer(signer::SignerError::MissingNonWitnessUtxo));
1466+
return Err(SignError::Signer(SignerError::MissingNonWitnessUtxo));
14661467
}
14671468

14681469
// If the user hasn't explicitly opted-in, refuse to sign the transaction unless every input
@@ -1475,7 +1476,7 @@ impl<D> Wallet<D> {
14751476
|| i.sighash_type == Some(TapSighashType::Default.into())
14761477
})
14771478
{
1478-
return Err(Error::Signer(signer::SignerError::NonStandardSighash));
1479+
return Err(SignError::Signer(SignerError::NonStandardSighash));
14791480
}
14801481

14811482
for signer in self
@@ -1484,7 +1485,9 @@ impl<D> Wallet<D> {
14841485
.iter()
14851486
.chain(self.change_signers.signers().iter())
14861487
{
1487-
signer.sign_transaction(psbt, &sign_options, &self.secp)?;
1488+
signer
1489+
.sign_transaction(psbt, &sign_options, &self.secp)
1490+
.map_err(SignError::Signer)?;
14881491
}
14891492

14901493
// attempt to finalize
@@ -1528,7 +1531,7 @@ impl<D> Wallet<D> {
15281531
&self,
15291532
psbt: &mut psbt::PartiallySignedTransaction,
15301533
sign_options: SignOptions,
1531-
) -> Result<bool, Error> {
1534+
) -> Result<bool, SignError> {
15321535
let chain_tip = self.chain.tip().map(|cp| cp.block_id()).unwrap_or_default();
15331536

15341537
let tx = &psbt.unsigned_tx;
@@ -1538,7 +1541,7 @@ impl<D> Wallet<D> {
15381541
let psbt_input = &psbt
15391542
.inputs
15401543
.get(n)
1541-
.ok_or(Error::Signer(SignerError::InputIndexOutOfRange))?;
1544+
.ok_or(SignError::Signer(SignerError::InputIndexOutOfRange))?;
15421545
if psbt_input.final_script_sig.is_some() || psbt_input.final_script_witness.is_some() {
15431546
continue;
15441547
}

crates/bdk/tests/wallet.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use assert_matches::assert_matches;
22
use bdk::descriptor::calc_checksum;
3-
use bdk::error::CreateTxError;
3+
use bdk::error::{CreateTxError, SignError};
44
use bdk::psbt::PsbtUtils;
55
use bdk::signer::{SignOptions, SignerError};
66
use bdk::wallet::coin_selection::{self, LargestFirstCoinSelection};
@@ -2432,7 +2432,7 @@ fn test_sign_nonstandard_sighash() {
24322432
);
24332433
assert_matches!(
24342434
result,
2435-
Err(bdk::Error::Signer(SignerError::NonStandardSighash)),
2435+
Err(SignError::Signer(SignerError::NonStandardSighash)),
24362436
"Signing failed with the wrong error type"
24372437
);
24382438

@@ -2849,7 +2849,7 @@ fn test_taproot_sign_missing_witness_utxo() {
28492849
);
28502850
assert_matches!(
28512851
result,
2852-
Err(bdk::Error::Signer(SignerError::MissingWitnessUtxo)),
2852+
Err(SignError::Signer(SignerError::MissingWitnessUtxo)),
28532853
"Signing should have failed with the correct error because the witness_utxo is missing"
28542854
);
28552855

@@ -3190,7 +3190,7 @@ fn test_taproot_sign_non_default_sighash() {
31903190
);
31913191
assert_matches!(
31923192
result,
3193-
Err(bdk::Error::Signer(SignerError::NonStandardSighash)),
3193+
Err(SignError::Signer(SignerError::NonStandardSighash)),
31943194
"Signing failed with the wrong error type"
31953195
);
31963196

@@ -3208,7 +3208,7 @@ fn test_taproot_sign_non_default_sighash() {
32083208
);
32093209
assert_matches!(
32103210
result,
3211-
Err(bdk::Error::Signer(SignerError::MissingWitnessUtxo)),
3211+
Err(SignError::Signer(SignerError::MissingWitnessUtxo)),
32123212
"Signing failed with the wrong error type"
32133213
);
32143214

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)