use std::convert::Infallible;
use pepper_sync::{error::ScanError, wallet::OutputId};
use zcash_keys::keys::DerivationError;
use zcash_primitives::{consensus::BlockHeight, transaction::TxId};
use zcash_protocol::PoolType;
use super::output::OutputRef;
#[derive(Debug, thiserror::Error)]
pub enum WalletError {
#[error("{0}")]
KeyError(#[from] KeyError),
#[error("{0}")]
MnemonicError(#[from] bip0039::Error),
#[error("Value outside valid range of zatoshis. {0:?}")]
InvalidValue(#[from] zcash_protocol::value::BalanceError),
#[error("Failed to write transaction. {0:?}")]
TransactionWrite(#[from] std::io::Error),
#[error("Wallet block at height {0} not found in the wallet.")]
BlockNotFound(BlockHeight),
#[error("Minimum confirmations must be non-zero.")]
MinimumConfirmationError,
#[error("Failed to scan calculated transaction.")]
CalculatedTxScanError(#[from] ScanError),
#[error("Address parse error. {0}")]
ParseError(#[from] zcash_address::ParseError),
#[error("No sync data. Wallet has never been synced with the block chain.")]
NoSyncData,
}
#[derive(Debug, thiserror::Error)]
pub enum PriceError {
#[error("price error. {0}")]
PriceError(#[from] zingo_price::PriceError),
#[error("price list not initialised. please wait for sync to obtain time of wallet birthday")]
NotInitialised,
}
#[derive(Debug, thiserror::Error)]
pub enum RemovalError {
#[error("transaction is already confirmed.")]
TransactionAlreadyConfirmed,
#[error("transaction not found in wallet.")]
TransactionNotFound,
}
#[derive(Debug, thiserror::Error)]
pub enum SummaryError {
#[error("address parse error. {0}")]
ParseError(#[from] zcash_address::ParseError),
#[error("address parse error. {0}")]
StdParseError(#[from] std::io::Error),
#[error("spend error. {0}")]
SpendError(#[from] SpendError),
}
#[derive(Debug)]
pub enum FeeError {
SpendNotFound { txid: TxId, spend: String },
BalanceError(zcash_protocol::value::BalanceError),
}
impl std::error::Error for FeeError {}
impl std::fmt::Display for FeeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match &self {
Self::SpendNotFound { txid, spend } => {
write!(
f,
"Transparent spend not found for transaction id {txid}. Is the wallet fully synced? \nMissing spend: {spend}"
)
}
Self::BalanceError(e) => write!(f, "{}", e),
}
}
}
impl From<zcash_protocol::value::BalanceError> for FeeError {
fn from(value: zcash_protocol::value::BalanceError) -> Self {
Self::BalanceError(value)
}
}
#[derive(Debug, thiserror::Error)]
pub enum SpendError {
#[error(
"spend not found for transaction id {txid}. is the wallet fully synced?\nmissing spend: {spend}"
)]
SpendNotFound {
pool: PoolType,
txid: TxId,
spend: String,
},
#[error("output has incorrect spending transaction id: {txid}.\noutput id: {output_id}")]
IncorrectSpendingTransaction { output_id: OutputId, txid: TxId },
}
#[derive(Debug, thiserror::Error)]
pub enum BalanceError {
#[error("failed to retrieve full viewing key.")]
NoFullViewingKey,
#[error("conversion failed. {0}")]
ConversionFailed(#[from] crate::utils::error::ConversionError),
}
#[derive(Debug, thiserror::Error)]
pub enum KeyError {
#[error("{0}")]
IoError(#[from] std::io::Error),
#[error("Account ID should be at most 31 bits")]
InvalidAccountId(#[from] zip32::TryFromIntError),
#[error("Key derivation failed")]
KeyDerivationError(#[from] DerivationError),
#[error("Key decoding failed")]
KeyDecodingError,
#[error("Key parsing failed. {0}")]
KeyParseError(#[from] zcash_address::unified::ParseError),
#[error("No spend capability")]
NoSpendCapability,
#[error("No view capability")]
NoViewCapability,
#[error("Outside range of non-hardened child indexes")]
InvalidNonHardenedChildIndex,
#[error("Decoded unified full viewing key does not match current network")]
NetworkMismatch,
#[error("Viewing keys must be imported in the unified format")]
InvalidFormat,
#[error("Unified address must contain a shielded receiver")]
UnifiedAddressError,
}
impl From<bip32::Error> for KeyError {
fn from(value: bip32::Error) -> Self {
Self::KeyDerivationError(DerivationError::Transparent(value))
}
}
#[allow(missing_docs)] #[derive(Debug, thiserror::Error)]
pub enum TransmissionError {
#[error("Transmission failed. {0}")]
TransmissionFailed(String),
#[error("Transaction not found in the wallet: {0}")]
TransactionNotFound(TxId),
#[error(
"Transaction associated with given txid to transmit does not have `Calculated` status: {0}"
)]
IncorrectTransactionStatus(TxId),
#[error("Failed to read transaction.")]
TransactionRead,
#[error("Failed to write transaction.")]
TransactionWrite,
#[error("Conversion failed. {0}")]
ConversionFailed(#[from] crate::utils::error::ConversionError),
#[error("No view capability")]
NoViewCapability,
#[error(
"Server error: txid reported by the server does not match calculated txid.\ncalculated txid:\n{0}\ntxid from server: {1}"
)]
IncorrectTxidFromServer(TxId, TxId),
#[error("Failed to scan transmitted transaction. {0}")]
SyncError(#[from] pepper_sync::error::SyncError<WalletError>),
}
#[allow(missing_docs)] #[derive(Debug, thiserror::Error)]
pub enum CalculateTransactionError<NoteRef> {
#[error("No witness trees. This is viewkey watch, not spendkey wallet.")]
NoSpendCapability,
#[error("Could not load sapling_params: {0}")]
SaplingParams(String),
#[error("Could not find UnifiedSpendKey: {0}")]
UnifiedSpendKey(#[from] crate::wallet::error::KeyError),
#[error("Failed to calculate transaction. {0}")]
Calculation(
zcash_client_backend::data_api::error::Error<
WalletError,
Infallible,
Infallible,
zcash_primitives::transaction::fees::zip317::FeeError,
zcash_primitives::transaction::fees::zip317::FeeError,
NoteRef,
>,
),
#[error("Only tex multistep transactions are supported!")]
NonTexMultiStep,
}
#[derive(Debug, thiserror::Error)]
pub enum ProposeSendError {
#[error("{0}")]
Proposal(
zcash_client_backend::data_api::error::Error<
WalletError,
WalletError,
zcash_client_backend::data_api::wallet::input_selection::GreedyInputSelectorError,
zcash_primitives::transaction::fees::zip317::FeeError,
zcash_primitives::transaction::fees::zip317::FeeError,
OutputRef,
>,
),
#[error("{0}")]
TransactionRequestFailed(#[from] zcash_client_backend::zip321::Zip321Error),
#[error("send all is transferring no value. only enough funds to pay the fees!")]
ZeroValueSendAll,
#[error("failed to calculated balance. {0}")]
BalanceError(#[from] crate::wallet::error::BalanceError),
}
#[allow(missing_docs)] #[derive(Debug, thiserror::Error)]
pub enum ProposeShieldError {
#[error("{0}")]
Receiver(zcash_client_backend::zip321::Zip321Error),
#[error("{0}")]
Component(
zcash_client_backend::data_api::error::Error<
WalletError,
WalletError,
zcash_client_backend::data_api::wallet::input_selection::GreedyInputSelectorError,
zcash_primitives::transaction::fees::zip317::FeeError,
zcash_primitives::transaction::fees::zip317::FeeError,
Infallible,
>,
),
#[error("not enough transparent funds to shield.")]
Insufficient,
#[error("address parse error. {0}")]
AddressParseError(#[from] zcash_address::ParseError),
}