feat: add mnemonic related error

This commit is contained in:
Matthew 2024-04-17 21:09:09 -05:00
parent 126bc61df6
commit 6ac386c8df
No known key found for this signature in database
GPG Key ID: 8D4FCD82DD54DDD2
4 changed files with 83 additions and 8 deletions

View File

@ -9,6 +9,15 @@ enum Alpha3Error {
"Generic"
};
[Error]
interface Bip39Error {
BadWordCount(u64 word_count);
UnknownWord(u64 index);
BadEntropyBitCount(u64 bit_count);
InvalidChecksum();
AmbiguousLanguages(string languages);
};
[Error]
interface CalculateFeeError {
MissingTxOut(sequence<OutPoint> out_points);
@ -316,10 +325,10 @@ interface BumpFeeTxBuilder {
interface Mnemonic {
constructor(WordCount word_count);
[Name=from_string, Throws=Alpha3Error]
[Name=from_string, Throws=Bip39Error]
constructor(string mnemonic);
[Name=from_entropy, Throws=Alpha3Error]
[Name=from_entropy, Throws=Bip39Error]
constructor(sequence<u8> entropy);
string as_string();

View File

@ -14,7 +14,9 @@ use bdk_file_store::IterError;
use bitcoin_internals::hex::display::DisplayHex;
use bdk::bitcoin::address::ParseError;
use bdk::keys::bip39::Error as BdkBip39Error;
use std::convert::Infallible;
use std::convert::TryInto;
#[derive(Debug, thiserror::Error)]
pub enum Alpha3Error {
@ -63,6 +65,24 @@ pub enum WalletCreationError {
},
}
#[derive(Debug, thiserror::Error)]
pub enum Bip39Error {
#[error("the word count {word_count} is not supported")]
BadWordCount { word_count: u64 },
#[error("unknown word at index {index}")]
UnknownWord { index: u64 },
#[error("entropy bit count {bit_count} is invalid")]
BadEntropyBitCount { bit_count: u64 },
#[error("checksum is invalid")]
InvalidChecksum,
#[error("ambiguous languages detected: {languages}")]
AmbiguousLanguages { languages: String },
}
#[derive(Debug, thiserror::Error)]
pub enum PersistenceError {
#[error("writing to persistence error: {e}")]
@ -392,6 +412,26 @@ impl From<NewOrLoadError<std::io::Error, IterError>> for WalletCreationError {
}
}
impl From<BdkBip39Error> for Bip39Error {
fn from(error: BdkBip39Error) -> Self {
match error {
BdkBip39Error::BadWordCount(word_count) => Bip39Error::BadWordCount {
word_count: word_count.try_into().expect("word count exceeds u64"),
},
BdkBip39Error::UnknownWord(index) => Bip39Error::UnknownWord {
index: index.try_into().expect("index exceeds u64"),
},
BdkBip39Error::BadEntropyBitCount(bit_count) => Bip39Error::BadEntropyBitCount {
bit_count: bit_count.try_into().expect("bit count exceeds u64"),
},
BdkBip39Error::InvalidChecksum => Bip39Error::InvalidChecksum,
BdkBip39Error::AmbiguousLanguages(info) => Bip39Error::AmbiguousLanguages {
languages: format!("{:?}", info),
},
}
}
}
impl From<std::io::Error> for PersistenceError {
fn from(error: std::io::Error) -> Self {
PersistenceError::Write {
@ -581,7 +621,9 @@ impl From<bdk::bitcoin::psbt::ExtractTxError> for ExtractTxError {
}
#[cfg(test)]
mod test {
use crate::error::{CannotConnectError, EsploraError, PersistenceError, WalletCreationError};
use crate::error::{
Bip39Error, CannotConnectError, EsploraError, PersistenceError, WalletCreationError,
};
use crate::CalculateFeeError;
use crate::OutPoint;
use crate::SignerError;
@ -806,4 +848,27 @@ mod test {
assert_eq!(format!("{}", error), "cannot include height: 42");
}
#[test]
fn test_error_bip39() {
let error = Bip39Error::BadWordCount { word_count: 15 };
assert_eq!(format!("{}", error), "the word count 15 is not supported");
let error = Bip39Error::UnknownWord { index: 102 };
assert_eq!(format!("{}", error), "unknown word at index 102");
let error = Bip39Error::BadEntropyBitCount { bit_count: 128 };
assert_eq!(format!("{}", error), "entropy bit count 128 is invalid");
let error = Bip39Error::InvalidChecksum;
assert_eq!(format!("{}", error), "checksum is invalid");
let error = Bip39Error::AmbiguousLanguages {
languages: "English, Spanish".to_string(),
};
assert_eq!(
format!("{}", error),
"ambiguous languages detected: English, Spanish"
);
}
}

View File

@ -1,4 +1,4 @@
use crate::error::Alpha3Error;
use crate::error::{Alpha3Error, Bip39Error};
use bdk::bitcoin::bip32::DerivationPath as BdkDerivationPath;
use bdk::bitcoin::key::Secp256k1;
@ -35,16 +35,16 @@ impl Mnemonic {
Mnemonic { inner: mnemonic }
}
pub(crate) fn from_string(mnemonic: String) -> Result<Self, Alpha3Error> {
pub(crate) fn from_string(mnemonic: String) -> Result<Self, Bip39Error> {
BdkMnemonic::from_str(&mnemonic)
.map(|m| Mnemonic { inner: m })
.map_err(|_| Alpha3Error::Generic)
.map_err(Bip39Error::from)
}
pub(crate) fn from_entropy(entropy: Vec<u8>) -> Result<Self, Alpha3Error> {
pub(crate) fn from_entropy(entropy: Vec<u8>) -> Result<Self, Bip39Error> {
BdkMnemonic::from_entropy(entropy.as_slice())
.map(|m| Mnemonic { inner: m })
.map_err(|_| Alpha3Error::Generic)
.map_err(Bip39Error::from)
}
pub(crate) fn as_string(&self) -> String {

View File

@ -15,6 +15,7 @@ use crate::bitcoin::TxOut;
use crate::descriptor::Descriptor;
use crate::error::AddressError;
use crate::error::Alpha3Error;
use crate::error::Bip39Error;
use crate::error::CalculateFeeError;
use crate::error::CannotConnectError;
use crate::error::DescriptorError;