1use {
4 num_derive::FromPrimitive,
5 num_traits::FromPrimitive,
6 solana_msg::msg,
7 solana_program_error::{ProgramError, ToStr},
8 std::convert::TryFrom,
9 thiserror::Error,
10};
11
12#[derive(Clone, Debug, Eq, Error, PartialEq, FromPrimitive)]
14pub enum TokenWrapError {
15 #[error("Wrapped mint account address does not match expected PDA")]
18 WrappedMintMismatch,
19 #[error("Wrapped backpointer account address does not match expected PDA")]
21 BackpointerMismatch,
22 #[error("Wrap amount should be positive")]
24 ZeroWrapAmount,
25 #[error("Wrapped mint authority does not match expected PDA")]
27 MintAuthorityMismatch,
28 #[error("Unwrapped escrow token owner is not set to expected PDA")]
30 EscrowOwnerMismatch,
31
32 #[error("Wrapped mint account owner is not the expected token program")]
35 InvalidWrappedMintOwner,
36 #[error("Wrapped backpointer account owner is not the expected token wrap program")]
38 InvalidBackpointerOwner,
39 #[error("Escrow account address does not match expected ATA")]
41 EscrowMismatch,
42 #[error("The escrow account is in a good state and cannot be recreated")]
44 EscrowInGoodState,
45 #[error("Unwrapped mint does not have the TokenMetadata extension")]
47 UnwrappedMintHasNoMetadata,
48
49 #[error("Metaplex metadata account address does not match expected PDA")]
52 MetaplexMetadataMismatch,
53 #[error("Metadata pointer extension missing on mint")]
55 MetadataPointerMissing,
56 #[error("Metadata pointer is unset (None)")]
58 MetadataPointerUnset,
59 #[error("Provided source metadata account does not match pointer")]
61 MetadataPointerMismatch,
62 #[error("External metadata program returned no data")]
64 ExternalProgramReturnedNoData,
65
66 #[error("Instruction can only be used with spl-token wrapped mints")]
69 NoSyncingToToken2022,
70}
71
72impl From<TokenWrapError> for ProgramError {
73 fn from(e: TokenWrapError) -> Self {
74 ProgramError::Custom(e as u32)
75 }
76}
77
78impl TryFrom<u32> for TokenWrapError {
79 type Error = ProgramError;
80
81 fn try_from(value: u32) -> Result<Self, Self::Error> {
82 TokenWrapError::from_u32(value).ok_or(ProgramError::InvalidArgument)
83 }
84}
85
86impl ToStr for TokenWrapError {
87 fn to_str<E>(&self) -> &'static str
88 where
89 E: 'static + ToStr + TryFrom<u32>,
90 {
91 match self {
92 TokenWrapError::WrappedMintMismatch => "Error: WrappedMintMismatch",
93 TokenWrapError::BackpointerMismatch => "Error: BackpointerMismatch",
94 TokenWrapError::ZeroWrapAmount => "Error: ZeroWrapAmount",
95 TokenWrapError::MintAuthorityMismatch => "Error: MintAuthorityMismatch",
96 TokenWrapError::EscrowOwnerMismatch => "Error: EscrowOwnerMismatch",
97 TokenWrapError::InvalidWrappedMintOwner => "Error: InvalidWrappedMintOwner",
98 TokenWrapError::InvalidBackpointerOwner => "Error: InvalidBackpointerOwner",
99 TokenWrapError::EscrowMismatch => "Error: EscrowMismatch",
100 TokenWrapError::EscrowInGoodState => "Error: EscrowInGoodState",
101 TokenWrapError::UnwrappedMintHasNoMetadata => "Error: UnwrappedMintHasNoMetadata",
102 TokenWrapError::MetaplexMetadataMismatch => "Error: MetaplexMetadataMismatch",
103 TokenWrapError::MetadataPointerMissing => "Error: MetadataPointerMissing",
104 TokenWrapError::MetadataPointerUnset => "Error: MetadataPointerUnset",
105 TokenWrapError::MetadataPointerMismatch => "Error: MetadataPointerMismatch",
106 TokenWrapError::ExternalProgramReturnedNoData => "Error: ExternalProgramReturnedNoData",
107 TokenWrapError::NoSyncingToToken2022 => "Error: NoSyncingToToken2022",
108 }
109 }
110}
111
112pub fn log_error(err: &ProgramError) {
114 msg!(err.to_str::<TokenWrapError>());
115}