use crate::esplora::TxSyncError;
use aes::cipher::block_padding::UnpadError;
use bitcoin::Network;
use lightning::ln::peer_handler::PeerHandleError;
use lightning_invoice::payment::PaymentError;
use lightning_invoice::ParseOrSemanticError;
use lightning_rapid_gossip_sync::GraphSyncError;
use std::string::FromUtf8Error;
use thiserror::Error;
#[derive(Error, Debug)]
#[allow(dead_code)]
pub enum MutinyError {
#[error("Mutiny is already running.")]
AlreadyRunning,
#[error("Mutiny is not running.")]
NotRunning,
#[error("Resource Not found.")]
NotFound,
#[error("Funding transaction could not be created.")]
FundingTxCreationFailed,
#[error("Network connection closed.")]
ConnectionFailed,
#[error("The invoice or address is on a different network.")]
IncorrectNetwork(Network),
#[error("An invoice must not get payed twice.")]
NonUniquePaymentHash,
#[error("Payment timed out.")]
PaymentTimeout,
#[error("The given invoice is invalid.")]
InvoiceInvalid,
#[error("Failed to create invoice.")]
InvoiceCreationFailed,
#[error("Channel reserve amount is too high.")]
ReserveAmountError,
#[error("We do not have enough balance to pay the given amount.")]
InsufficientBalance,
#[error("Failed to call on the given LNURL.")]
LnUrlFailure,
#[error("Failed to make a request to the LSP.")]
LspGenericError,
#[error("Failed to request channel from LSP due to funding error.")]
LspFundingError,
#[error("Failed to request channel from LSP due to amount being too high.")]
LspAmountTooHighError,
#[error("Failed to have a connection to the LSP node.")]
LspConnectionError,
#[error("Subscription Client Not Configured")]
SubscriptionClientNotConfigured,
#[error("Invalid Arguments were given")]
InvalidArgumentsError,
#[error("Failed to find route.")]
RoutingFailed,
#[error("Failed to parse the given peer information.")]
PeerInfoParseFailed,
#[error("Failed to create channel.")]
ChannelCreationFailed,
#[error("Failed to close channel.")]
ChannelClosingFailed,
#[error("Failed to persist data.")]
PersistenceFailed {
#[from]
source: MutinyStorageError,
},
#[error("Failed to read data from storage.")]
ReadError { source: MutinyStorageError },
#[error("Failed to decode lightning data.")]
LnDecodeError,
#[error("Failed to generate seed")]
SeedGenerationFailed,
#[error("Invalid mnemonic")]
InvalidMnemonic,
#[error("Failed to conduct wallet operation.")]
WalletOperationFailed,
#[error("Failed to sign given transaction.")]
WalletSigningFailed,
#[error("Failed to conduct chain access operation.")]
ChainAccessFailed,
#[error("Failed to to sync on-chain wallet.")]
WalletSyncError,
#[error("Failed to execute a rapid gossip sync function")]
RapidGossipSyncError,
#[error("Failed to execute a dlc function")]
DLCManagerError,
#[error("The given node pubkey is invalid.")]
PubkeyInvalid,
#[error("Called incorrect lnurl function.")]
IncorrectLnUrlFunction,
#[error("Satoshi amount is invalid")]
BadAmountError,
#[error("Failed to get the bitcoin price.")]
BitcoinPriceError,
#[error("Incorrect password entered.")]
IncorrectPassword,
#[error(transparent)]
Other(#[from] anyhow::Error),
}
#[derive(Error, Debug)]
pub enum MutinyStorageError {
#[error("Failed to serialize or deserialize")]
SerdeError {
#[from]
source: serde_json::Error,
},
#[error("Failed to get lock on memory storage")]
LockError,
#[error("Failed to use indexeddb storage")]
IndexedDBError,
#[error(transparent)]
Other(#[from] anyhow::Error),
}
impl MutinyError {
pub fn read_err(e: MutinyStorageError) -> Self {
MutinyError::ReadError { source: e }
}
pub fn write_err(e: MutinyStorageError) -> Self {
MutinyError::PersistenceFailed { source: e }
}
}
impl From<UnpadError> for MutinyError {
fn from(_e: UnpadError) -> Self {
Self::IncorrectPassword
}
}
impl From<base64::DecodeError> for MutinyError {
fn from(_e: base64::DecodeError) -> Self {
Self::IncorrectPassword
}
}
impl From<FromUtf8Error> for MutinyError {
fn from(_e: FromUtf8Error) -> Self {
Self::IncorrectPassword
}
}
impl From<aes_gcm::Error> for MutinyError {
fn from(_: aes_gcm::Error) -> Self {
Self::IncorrectPassword
}
}
impl From<aes_gcm::aes::cipher::InvalidLength> for MutinyError {
fn from(_: aes_gcm::aes::cipher::InvalidLength) -> Self {
Self::IncorrectPassword
}
}
impl From<bdk::Error> for MutinyError {
fn from(e: bdk::Error) -> Self {
match e {
bdk::Error::Signer(_) => Self::WalletSigningFailed,
bdk::Error::InsufficientFunds { .. } => Self::InsufficientBalance,
_ => Self::WalletOperationFailed,
}
}
}
impl From<bdk::descriptor::error::Error> for MutinyError {
fn from(_: bdk::descriptor::error::Error) -> Self {
Self::WalletOperationFailed
}
}
impl From<bdk::wallet::NewError<MutinyError>> for MutinyError {
fn from(e: bdk::wallet::NewError<MutinyError>) -> Self {
match e {
bdk::wallet::NewError::Persist(e) => e,
bdk::wallet::NewError::Descriptor(e) => e.into(),
}
}
}
impl From<bip39::Error> for MutinyError {
fn from(_e: bip39::Error) -> Self {
Self::InvalidMnemonic
}
}
impl From<bitcoin::util::bip32::Error> for MutinyError {
fn from(_e: bitcoin::util::bip32::Error) -> Self {
Self::InvalidMnemonic
}
}
impl From<url::ParseError> for MutinyError {
fn from(_e: url::ParseError) -> Self {
Self::LnUrlFailure
}
}
impl From<lnurl::Error> for MutinyError {
fn from(_e: lnurl::Error) -> Self {
Self::LnUrlFailure
}
}
impl From<TxSyncError> for MutinyError {
fn from(_e: TxSyncError) -> Self {
MutinyError::ChainAccessFailed
}
}
impl From<lightning::ln::msgs::DecodeError> for MutinyError {
fn from(_e: lightning::ln::msgs::DecodeError) -> Self {
MutinyError::LnDecodeError
}
}
impl From<ParseOrSemanticError> for MutinyError {
fn from(_e: ParseOrSemanticError) -> Self {
Self::InvoiceInvalid
}
}
impl From<PeerHandleError> for MutinyError {
fn from(_e: PeerHandleError) -> Self {
Self::ConnectionFailed
}
}
impl From<PaymentError> for MutinyError {
fn from(e: PaymentError) -> Self {
match e {
PaymentError::Invoice(_) => Self::InvoiceInvalid,
PaymentError::Sending(_) => Self::RoutingFailed,
}
}
}
impl From<GraphSyncError> for MutinyError {
fn from(_e: GraphSyncError) -> Self {
MutinyError::RapidGossipSyncError
}
}
impl From<std::io::Error> for MutinyError {
fn from(e: std::io::Error) -> Self {
MutinyError::PersistenceFailed {
source: MutinyStorageError::Other(e.into()),
}
}
}
impl From<serde_json::Error> for MutinyError {
fn from(_: serde_json::Error) -> Self {
Self::ReadError {
source: MutinyStorageError::Other(anyhow::anyhow!("Failed to deserialize")),
}
}
}
impl<G> From<std::sync::PoisonError<G>> for MutinyStorageError {
fn from(_e: std::sync::PoisonError<G>) -> Self {
MutinyStorageError::LockError
}
}
impl<G> From<std::sync::TryLockError<G>> for MutinyError {
fn from(_e: std::sync::TryLockError<G>) -> Self {
MutinyStorageError::LockError.into()
}
}
impl<G> From<std::sync::TryLockError<G>> for MutinyStorageError {
fn from(_e: std::sync::TryLockError<G>) -> Self {
MutinyStorageError::LockError
}
}
impl From<bitcoin::hashes::hex::Error> for MutinyError {
fn from(_e: bitcoin::hashes::hex::Error) -> Self {
MutinyError::ReadError {
source: MutinyStorageError::Other(anyhow::anyhow!("Failed to decode hex")),
}
}
}
impl From<bitcoin::util::address::Error> for MutinyError {
fn from(_e: bitcoin::util::address::Error) -> Self {
MutinyError::ReadError {
source: MutinyStorageError::Other(anyhow::anyhow!("Failed to decode address")),
}
}
}
impl From<esplora_client::Error> for MutinyError {
fn from(_e: esplora_client::Error) -> Self {
Self::ChainAccessFailed
}
}
impl From<bdk_chain::local_chain::InsertBlockNotMatchingError> for MutinyError {
fn from(_e: bdk_chain::local_chain::InsertBlockNotMatchingError) -> Self {
Self::WalletSyncError
}
}
impl From<bdk::wallet::InsertTxError> for MutinyError {
fn from(_e: bdk::wallet::InsertTxError) -> Self {
Self::WalletSyncError
}
}