1use light_account_checks::error::AccountError;
2use light_compressed_account::CompressedAccountError;
3use light_hasher::HasherError;
4use light_sdk_types::error::LightSdkTypesError;
5use light_zero_copy::errors::ZeroCopyError;
6use thiserror::Error;
7
8use crate::ProgramError;
9
10pub type Result<T> = std::result::Result<T, LightSdkError>;
11
12#[derive(Debug, Error, PartialEq)]
13pub enum LightSdkError {
14 #[error("Constraint violation")]
15 ConstraintViolation,
16 #[error("Invalid light-system-program ID")]
17 InvalidLightSystemProgram,
18 #[error("Expected accounts in the instruction")]
19 ExpectedAccounts,
20 #[error("Expected address Merkle context to be provided")]
21 ExpectedAddressTreeInfo,
22 #[error("Expected address root index to be provided")]
23 ExpectedAddressRootIndex,
24 #[error("Accounts with a specified input are expected to have data")]
25 ExpectedData,
26 #[error("Accounts with specified data are expected to have a discriminator")]
27 ExpectedDiscriminator,
28 #[error("Accounts with specified data are expected to have a hash")]
29 ExpectedHash,
30 #[error("Expected the `{0}` light account to be provided")]
31 ExpectedLightSystemAccount(String),
32 #[error("`mut` and `close` accounts are expected to have a Merkle context")]
33 ExpectedMerkleContext,
34 #[error("Expected root index to be provided")]
35 ExpectedRootIndex,
36 #[error("Cannot transfer lamports from an account without input")]
37 TransferFromNoInput,
38 #[error("Cannot transfer from an account without lamports")]
39 TransferFromNoLamports,
40 #[error("Account, from which a transfer was attempted, has insufficient amount of lamports")]
41 TransferFromInsufficientLamports,
42 #[error("Integer overflow resulting from too large resulting amount")]
43 TransferIntegerOverflow,
44 #[error("Borsh error.")]
45 Borsh,
46 #[error("Fewer accounts than number of system accounts.")]
47 FewerAccountsThanSystemAccounts,
48 #[error("InvalidCpiSignerAccount")]
49 InvalidCpiSignerAccount,
50 #[error("Missing meta field: {0}")]
51 MissingField(String),
52 #[error("Output state tree index is none. Use an CompressedAccountMeta type with output tree index to initialize or update accounts.")]
53 OutputStateTreeIndexIsNone,
54 #[error("Address is none during initialization")]
55 InitAddressIsNone,
56 #[error("Address is none during initialization with address")]
57 InitWithAddressIsNone,
58 #[error("Output is none during initialization with address")]
59 InitWithAddressOutputIsNone,
60 #[error("Address is none during meta mutation")]
61 MetaMutAddressIsNone,
62 #[error("Input is none during meta mutation")]
63 MetaMutInputIsNone,
64 #[error("Output lamports is none during meta mutation")]
65 MetaMutOutputLamportsIsNone,
66 #[error("Output is none during meta mutation")]
67 MetaMutOutputIsNone,
68 #[error("Address is none during meta close")]
69 MetaCloseAddressIsNone,
70 #[error("Input is none during meta close")]
71 MetaCloseInputIsNone,
72 #[error("CPI accounts index out of bounds: {0}")]
73 CpiAccountsIndexOutOfBounds(usize),
74 #[error("Invalid CPI context account")]
75 InvalidCpiContextAccount,
76 #[error("Invalid SolPool PDA account")]
77 InvalidSolPoolPdaAccount,
78 #[error("CpigAccounts accounts slice starts with an invalid account. It should start with LightSystemProgram SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7.")]
79 InvalidCpiAccountsOffset,
80 #[error("Expected LightAccount to have no data for closure.")]
81 ExpectedNoData,
82 #[error("CPI context must be added before any other accounts (next_index must be 0)")]
83 CpiContextOrderingViolation,
84 #[error("Invalid merkle tree index in CPI accounts")]
85 InvalidMerkleTreeIndex,
86 #[error(
87 "Read-only account cannot use to_account_info(), use to_packed_read_only_account() instead"
88 )]
89 ReadOnlyAccountCannotUseToAccountInfo,
90 #[error("Account is not read-only, cannot use to_packed_read_only_account()")]
91 NotReadOnlyAccount,
92 #[error("Read-only accounts are not supported in write_to_cpi_context operations")]
93 ReadOnlyAccountsNotSupportedInCpiContext,
94 #[error(transparent)]
95 AccountError(#[from] AccountError),
96 #[error(transparent)]
97 Hasher(#[from] HasherError),
98 #[error(transparent)]
99 ZeroCopy(#[from] ZeroCopyError),
100 #[error("Program error: {0}")]
101 ProgramError(#[from] ProgramError),
102 #[error("Compressed account error: {0}")]
103 CompressedAccountError(#[from] CompressedAccountError),
104 #[error("Expected tree info to be provided for init_if_needed")]
105 ExpectedTreeInfo,
106 #[error("ExpectedSelfProgram")]
107 ExpectedSelfProgram,
108 #[error("Expected CPI context to be provided")]
109 ExpectedCpiContext,
110 #[error("Account missing compression_info field")]
111 MissingCompressionInfo,
112 #[error("Cannot access compression_info on packed variant")]
113 PackedVariantCompressionInfo,
114 #[error("CToken variant does not support compression_info operations")]
115 CTokenCompressionInfo,
116 #[error("Unexpected unpacked variant during decompression")]
117 UnexpectedUnpackedVariant,
118}
119
120impl From<LightSdkError> for ProgramError {
121 fn from(e: LightSdkError) -> Self {
122 ProgramError::Custom(e.into())
123 }
124}
125
126impl From<LightSdkTypesError> for LightSdkError {
127 fn from(e: LightSdkTypesError) -> Self {
128 match e {
129 LightSdkTypesError::InitAddressIsNone => LightSdkError::InitAddressIsNone,
130 LightSdkTypesError::InitWithAddressIsNone => LightSdkError::InitWithAddressIsNone,
131 LightSdkTypesError::InitWithAddressOutputIsNone => {
132 LightSdkError::InitWithAddressOutputIsNone
133 }
134 LightSdkTypesError::MetaMutAddressIsNone => LightSdkError::MetaMutAddressIsNone,
135 LightSdkTypesError::MetaMutInputIsNone => LightSdkError::MetaMutInputIsNone,
136 LightSdkTypesError::MetaMutOutputLamportsIsNone => {
137 LightSdkError::MetaMutOutputLamportsIsNone
138 }
139 LightSdkTypesError::MetaMutOutputIsNone => LightSdkError::MetaMutOutputIsNone,
140 LightSdkTypesError::MetaCloseAddressIsNone => LightSdkError::MetaCloseAddressIsNone,
141 LightSdkTypesError::MetaCloseInputIsNone => LightSdkError::MetaCloseInputIsNone,
142 LightSdkTypesError::FewerAccountsThanSystemAccounts => {
143 LightSdkError::FewerAccountsThanSystemAccounts
144 }
145 LightSdkTypesError::CpiAccountsIndexOutOfBounds(index) => {
146 LightSdkError::CpiAccountsIndexOutOfBounds(index)
147 }
148 LightSdkTypesError::InvalidSolPoolPdaAccount => LightSdkError::InvalidSolPoolPdaAccount,
149 LightSdkTypesError::InvalidCpiContextAccount => LightSdkError::InvalidCpiContextAccount,
150 LightSdkTypesError::InvalidCpiAccountsOffset => LightSdkError::InvalidCpiAccountsOffset,
151 LightSdkTypesError::AccountError(e) => LightSdkError::AccountError(e),
152 LightSdkTypesError::Hasher(e) => LightSdkError::Hasher(e),
153 }
154 }
155}
156
157impl From<LightSdkError> for u32 {
158 fn from(e: LightSdkError) -> Self {
159 match e {
160 LightSdkError::ConstraintViolation => 16001,
161 LightSdkError::InvalidLightSystemProgram => 16002,
162 LightSdkError::ExpectedAccounts => 16003,
163 LightSdkError::ExpectedAddressTreeInfo => 16004,
164 LightSdkError::ExpectedAddressRootIndex => 16005,
165 LightSdkError::ExpectedData => 16006,
166 LightSdkError::ExpectedDiscriminator => 16007,
167 LightSdkError::ExpectedHash => 16008,
168 LightSdkError::ExpectedLightSystemAccount(_) => 16009,
169 LightSdkError::ExpectedMerkleContext => 16010,
170 LightSdkError::ExpectedRootIndex => 16011,
171 LightSdkError::TransferFromNoInput => 16012,
172 LightSdkError::TransferFromNoLamports => 16013,
173 LightSdkError::TransferFromInsufficientLamports => 16014,
174 LightSdkError::TransferIntegerOverflow => 16015,
175 LightSdkError::Borsh => 16016,
176 LightSdkError::FewerAccountsThanSystemAccounts => 16017,
177 LightSdkError::InvalidCpiSignerAccount => 16018,
178 LightSdkError::MissingField(_) => 16019,
179 LightSdkError::OutputStateTreeIndexIsNone => 16020,
180 LightSdkError::InitAddressIsNone => 16021,
181 LightSdkError::InitWithAddressIsNone => 16022,
182 LightSdkError::InitWithAddressOutputIsNone => 16023,
183 LightSdkError::MetaMutAddressIsNone => 16024,
184 LightSdkError::MetaMutInputIsNone => 16025,
185 LightSdkError::MetaMutOutputLamportsIsNone => 16026,
186 LightSdkError::MetaMutOutputIsNone => 16027,
187 LightSdkError::MetaCloseAddressIsNone => 16028,
188 LightSdkError::MetaCloseInputIsNone => 16029,
189 LightSdkError::CpiAccountsIndexOutOfBounds(_) => 16031,
190 LightSdkError::InvalidCpiContextAccount => 16032,
191 LightSdkError::InvalidSolPoolPdaAccount => 16033,
192 LightSdkError::InvalidCpiAccountsOffset => 16034,
193 LightSdkError::ExpectedNoData => 16035,
194 LightSdkError::CpiContextOrderingViolation => 16036,
195 LightSdkError::InvalidMerkleTreeIndex => 16037,
196 LightSdkError::ReadOnlyAccountCannotUseToAccountInfo => 16038,
197 LightSdkError::NotReadOnlyAccount => 16039,
198 LightSdkError::ReadOnlyAccountsNotSupportedInCpiContext => 16040,
199 LightSdkError::AccountError(e) => e.into(),
200 LightSdkError::Hasher(e) => e.into(),
201 LightSdkError::ZeroCopy(e) => e.into(),
202 LightSdkError::ProgramError(e) => u64::from(e) as u32,
203 LightSdkError::CompressedAccountError(e) => e.into(),
204 LightSdkError::ExpectedTreeInfo => 16041,
205 LightSdkError::ExpectedSelfProgram => 16042,
206 LightSdkError::ExpectedCpiContext => 16043,
207 LightSdkError::MissingCompressionInfo => 16044,
208 LightSdkError::PackedVariantCompressionInfo => 16045,
209 LightSdkError::CTokenCompressionInfo => 16046,
210 LightSdkError::UnexpectedUnpackedVariant => 16047,
211 }
212 }
213}