diff --git a/bdk-ffi/src/bdk.udl b/bdk-ffi/src/bdk.udl index 8083ae12..560f3a56 100644 --- a/bdk-ffi/src/bdk.udl +++ b/bdk-ffi/src/bdk.udl @@ -15,6 +15,18 @@ interface CalculateFeeError { NegativeFee(i64 fee); }; +[Error] +interface WalletCreationError { + Io(string e); + InvalidMagicBytes(sequence got, sequence expected); + Descriptor(); + Write(); + Load(); + NotInitialized(); + LoadedGenesisDoesNotMatch(); + LoadedNetworkDoesNotMatch(Network expected, Network? got); +}; + // ------------------------------------------------------------------------ // bdk crate - types module // ------------------------------------------------------------------------ @@ -86,7 +98,7 @@ enum ChangeSpendPolicy { }; interface Wallet { - [Throws=Alpha3Error] + [Throws=WalletCreationError] constructor(Descriptor descriptor, Descriptor? change_descriptor, string persistence_backend_path, Network network); AddressInfo get_address(AddressIndex address_index); diff --git a/bdk-ffi/src/error.rs b/bdk-ffi/src/error.rs index 2e284e64..68a13aa5 100644 --- a/bdk-ffi/src/error.rs +++ b/bdk-ffi/src/error.rs @@ -4,11 +4,13 @@ use bdk::chain::tx_graph::CalculateFeeError as BdkCalculateFeeError; use std::fmt; +use bdk::bitcoin::Network; use bdk::descriptor::DescriptorError; use bdk::wallet::error::{BuildFeeBumpError, CreateTxError}; use bdk::wallet::tx_builder::{AddUtxoError, AllowShrinkingError}; use bdk::wallet::{NewError, NewOrLoadError}; -use bdk_file_store::{FileError, IterError}; +use bdk_file_store::FileError as BdkFileError; +use bdk_file_store::IterError; use std::convert::Infallible; #[derive(Debug)] @@ -26,15 +28,83 @@ impl fmt::Display for Alpha3Error { impl std::error::Error for Alpha3Error {} -impl From for Alpha3Error { - fn from(_: FileError) -> Self { - Alpha3Error::Generic +#[derive(Debug)] +pub enum WalletCreationError { + // Errors coming from the FileError enum + Io { + e: String, + }, + InvalidMagicBytes { + got: Vec, + expected: Vec, + }, + + // Errors coming from the NewOrLoadError enum + Descriptor, + Write, + Load, + NotInitialized, + LoadedGenesisDoesNotMatch, + LoadedNetworkDoesNotMatch { + expected: Network, + got: Option, + }, +} + +impl fmt::Display for WalletCreationError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Io { e } => write!(f, "io error trying to read file: {}", e), + Self::InvalidMagicBytes { got, expected } => write!( + f, + "file has invalid magic bytes: expected={:?} got={:?}", + expected, got, + ), + Self::Descriptor => write!(f, "error with descriptor"), + Self::Write => write!(f, "failed to write to persistence"), + Self::Load => write!(f, "failed to load from persistence"), + Self::NotInitialized => { + write!(f, "wallet is not initialized, persistence backend is empty") + } + Self::LoadedGenesisDoesNotMatch => { + write!(f, "loaded genesis hash does not match the expected one") + } + Self::LoadedNetworkDoesNotMatch { expected, got } => { + write!(f, "loaded network type is not {}, got {:?}", expected, got) + } + } } } -impl From> for Alpha3Error { - fn from(_: NewOrLoadError) -> Self { - Alpha3Error::Generic +impl std::error::Error for WalletCreationError {} + +impl From for WalletCreationError { + fn from(error: BdkFileError) -> Self { + match error { + BdkFileError::Io(_) => WalletCreationError::Io { + e: "io error trying to read file".to_string(), + }, + BdkFileError::InvalidMagicBytes { got, expected } => { + WalletCreationError::InvalidMagicBytes { got, expected } + } + } + } +} + +impl From> for WalletCreationError { + fn from(error: NewOrLoadError) -> Self { + match error { + NewOrLoadError::Descriptor(_) => WalletCreationError::Descriptor, + NewOrLoadError::Write(_) => WalletCreationError::Write, + NewOrLoadError::Load(_) => WalletCreationError::Load, + NewOrLoadError::NotInitialized => WalletCreationError::NotInitialized, + NewOrLoadError::LoadedGenesisDoesNotMatch { .. } => { + WalletCreationError::LoadedGenesisDoesNotMatch + } + NewOrLoadError::LoadedNetworkDoesNotMatch { expected, got } => { + WalletCreationError::LoadedNetworkDoesNotMatch { expected, got } + } + } } } diff --git a/bdk-ffi/src/lib.rs b/bdk-ffi/src/lib.rs index ac8c51f1..ce1c4585 100644 --- a/bdk-ffi/src/lib.rs +++ b/bdk-ffi/src/lib.rs @@ -32,6 +32,7 @@ use crate::wallet::TxBuilder; use crate::wallet::Update; use crate::wallet::Wallet; +use crate::error::WalletCreationError; use bdk::bitcoin::Network; use bdk::keys::bip39::WordCount; use bdk::wallet::tx_builder::ChangeSpendPolicy; diff --git a/bdk-ffi/src/wallet.rs b/bdk-ffi/src/wallet.rs index 20bdb47f..8a21f4cc 100644 --- a/bdk-ffi/src/wallet.rs +++ b/bdk-ffi/src/wallet.rs @@ -1,6 +1,6 @@ use crate::bitcoin::{OutPoint, PartiallySignedTransaction, Transaction}; use crate::descriptor::Descriptor; -use crate::error::{Alpha3Error, CalculateFeeError}; +use crate::error::{Alpha3Error, CalculateFeeError, WalletCreationError}; use crate::types::ScriptAmount; use crate::types::{Balance, FeeRate}; use crate::Script; @@ -32,7 +32,7 @@ impl Wallet { change_descriptor: Option>, persistence_backend_path: String, network: Network, - ) -> Result { + ) -> Result { let descriptor = descriptor.as_string_private(); let change_descriptor = change_descriptor.map(|d| d.as_string_private()); let db = Store::::open_or_create_new(MAGIC_BYTES, persistence_backend_path)?;