1
2use borsh::{BorshDeserialize, BorshSerialize};
3use serde::{Deserialize, Serialize};
4
5
6#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
7pub struct IdlData {
8 pub name: String,
9 pub version: String,
10 pub instructions: Vec<IdlInstruction>,
11 #[serde(default)]
12 pub accounts: Vec<IdlAccount>,
13 #[serde(default)]
14 pub types: Vec<IdlTypeDef>,
15 #[serde(default)]
16 pub errors: Vec<IdlError>,
17 #[serde(default)]
18 pub constants: Vec<IdlConstant>,
19 #[serde(default)]
20 pub events: Vec<IdlEvent>,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
24pub struct IdlError {
25 pub code: u32,
26 pub name: String,
27 pub msg: String,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
31pub struct IdlConstant {
32 pub name: String,
33 pub constant_type: String,
34 pub value: String,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
38pub struct IdlEvent {
39 pub name: String,
40 #[serde(default)]
41 pub discriminator: Vec<u8>,
42 pub fields: Vec<IdlField>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
46pub struct IdlInstruction {
47 pub name: String,
48 pub accounts: Vec<IdlAccountItem>,
49 pub args: Vec<IdlField>,
50 pub docs: Vec<String>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
54pub struct IdlAccountItem {
55 pub name: String,
56 pub is_mut: bool,
57 pub is_signer: bool,
58 pub is_optional: bool,
59 pub docs: Vec<String>,
60 pub pda: Option<IdlPda>,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
64pub struct IdlPda {
65 pub seeds: Vec<IdlSeed>,
66 #[serde(default)]
67 pub program: String,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
71pub struct IdlSeed {
72 pub kind: String,
73 #[serde(default)]
74 pub path: String,
75 #[serde(default)]
76 pub value: String,
77}
78
79#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
80pub struct IdlAccount {
81 pub name: String,
82 pub fields: Vec<IdlField>,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
86pub struct IdlField {
87 pub name: String,
88 pub field_type: String,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
92pub struct IdlTypeDef {
93 pub name: String,
94 pub kind: String,
95 pub fields: Vec<String>,
96}
97
98
99
100#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
101pub struct ParsedIdl {
102 #[serde(default)]
103 pub address: String,
104 #[serde(default)]
105 pub metadata: IdlMetadata,
106 pub instructions: Vec<Instruction>,
107 #[serde(default)]
108 pub accounts: Vec<AccountDef>,
109 #[serde(default)]
110 pub types: Vec<TypeDef>,
111 #[serde(default)]
112 pub errors: Vec<ErrorDef>,
113 #[serde(default)]
114 pub constants: Vec<ConstantDef>,
115 #[serde(default)]
116 pub events: Vec<EventDef>,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
120pub struct ErrorDef {
121 pub code: u32,
122 pub name: String,
123 #[serde(default)]
124 pub msg: String,
125}
126
127#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
128pub struct ConstantDef {
129 pub name: String,
130 #[serde(rename = "type")]
131 pub constant_type: String,
132 pub value: String,
133}
134
135#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
136pub struct EventDef {
137 pub name: String,
138 #[serde(default)]
139 pub discriminator: Vec<u8>,
140 #[serde(default)]
141 pub fields: Vec<FieldDef>,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize, Default)]
145pub struct IdlMetadata {
146 pub name: String,
147 pub version: String,
148 #[serde(default)]
149 pub spec: String,
150 #[serde(default)]
151 pub description: String,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
155pub struct Instruction {
156 pub name: String,
157 #[serde(default)]
158 pub discriminator: Vec<u8>,
159 pub accounts: Vec<AccountInfo>,
160 pub args: Vec<ArgumentDef>,
161 #[serde(default)]
162 pub docs: Vec<String>,
163}
164
165#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
166pub struct AccountInfo {
167 pub name: String,
168 #[serde(default)]
169 pub writable: bool,
170 #[serde(default)]
171 pub signer: bool,
172 #[serde(default)]
173 pub optional: bool,
174 #[serde(default)]
175 pub address: Option<String>,
176 #[serde(default)]
177 pub pda: Option<PdaConfig>,
178 #[serde(default)]
179 pub docs: Vec<String>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
183pub struct PdaConfig {
184 pub seeds: Vec<PdaSeed>,
185 #[serde(default)]
186 pub program: Option<PdaProgram>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
190pub struct PdaProgram {
191 pub kind: String,
192 #[serde(default)]
193 pub value: Option<Vec<u8>>,
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
197pub struct PdaSeed {
198 pub kind: String,
199 #[serde(default)]
200 pub path: String,
201 #[serde(default)]
202 pub value: Option<Vec<u8>>,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
206pub struct ArgumentDef {
207 pub name: String,
208
209 #[serde(rename = "type")]
210 pub arg_type: IdlType,
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
214#[serde(untagged)]
215pub enum IdlType {
216 Simple(String),
217 Vec {
218 vec: Box<IdlType>
219 },
220 Option {
221 option: Box<IdlType>
222 },
223 Array {
224 array: (Box<IdlType>, usize)
225 },
226 Defined {
227 defined: DefinedType
228 },
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
232#[serde(untagged)]
233pub enum DefinedType {
234 Simple(String),
235 Generic {
236 name: String,
237 #[serde(default)]
238 generics: Vec<IdlType>,
239 },
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
243pub struct AccountDef {
244 pub name: String,
245
246 #[serde(default)]
247 pub discriminator: Vec<u8>,
248}
249
250#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
251pub struct FieldDef {
252 pub name: String,
253
254 #[serde(rename = "type")]
255 pub field_type: IdlType,
256}
257
258#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
259pub struct TypeDef {
260 pub name: String,
261
262 #[serde(rename = "type")]
263 pub type_kind: TypeKind,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
267#[serde(tag = "kind")]
268pub enum TypeKind {
269 #[serde(rename = "struct")]
270 Struct {
271 fields: Vec<FieldDef>
272 },
273
274 #[serde(rename = "enum")]
275 Enum {
276 variants: Vec<EnumVariant>
277 },
278}
279
280#[derive(Debug, Clone, Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
281pub struct EnumVariant {
282 pub name: String,
283
284 #[serde(default)]
285 pub fields: Option<Vec<FieldDef>>,
286}
287
288
289#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
290pub struct TestMetadata {
291 pub instruction_order: Vec<String>,
292 pub account_dependencies: Vec<AccountDependency>,
293 pub pda_init_sequence: Vec<PdaInit>,
294 pub setup_requirements: Vec<SetupRequirement>,
295 pub test_cases: Vec<InstructionTestCases>,
296}
297
298#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
299pub struct AccountDependency {
300 pub account_name: String,
301 pub depends_on: Vec<String>,
302 pub is_pda: bool,
303 pub is_signer: bool,
304 pub is_mut: bool,
305 pub must_be_initialized: bool,
306 pub initialization_order: u8,
307}
308
309#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
310pub struct PdaInit {
311 pub account_name: String,
312 pub seeds: Vec<SeedComponent>,
313 pub program_id: String, pub space: Option<u64>,
315}
316
317#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
318pub struct SeedComponent {
319 pub seed_type: SeedType,
320 pub value: String,
321}
322
323#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
324pub enum SeedType {
325 Static,
326 AccountKey,
327 Argument,
328}
329
330#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
331pub struct SetupRequirement {
332 pub requirement_type: SetupType,
333 pub description: String,
334 pub dependencies: Vec<String>,
335}
336
337#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)]
338pub enum SetupType {
339 CreateKeypair,
340 FundAccount,
341 InitializePda,
342 MintTokens,
343 CreateAta,
344}
345
346#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
347pub struct InstructionTestCases {
348 pub instruction_name: String,
349 pub arguments: Vec<ArgumentInfo>,
350 pub positive_cases: Vec<TestCase>,
351 pub negative_cases: Vec<TestCase>,
352}
353
354#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
355pub struct ArgumentInfo {
356 pub name: String,
357 pub arg_type: ArgumentType,
358 pub constraints: Vec<ArgumentConstraint>,
359 pub is_optional: bool,
360}
361
362#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
363pub enum ArgumentType {
364 U8,
365 U16,
366 U32,
367 U64,
368 U128,
369 I8,
370 I16,
371 I32,
372 I64,
373 I128,
374 Bool,
375 String { max_length: Option<u32> },
376 Pubkey,
377 Vec {
378 inner_type: Box<ArgumentType>,
379 max_length: Option<u32>,
380 },
381 Option { inner_type: Box<ArgumentType> },
382 Struct { name: String },
383 Enum {
384 name: String,
385 variants: Vec<String>,
386 },
387}
388
389#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
390pub enum ArgumentConstraint {
391 Min { value: i64 },
392 Max { value: i64 },
393 Range { min: i64, max: i64 },
394 NonZero,
395 MaxLength { value: u32 },
396 MinLength { value: u32 },
397 Custom { description: String },
398}
399
400#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
401pub struct TestCase {
402 pub test_type: TestCaseType,
403 pub description: String,
404 pub argument_values: Vec<TestArgumentValue>,
405 pub expected_outcome: ExpectedOutcome,
406}
407
408#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
409pub enum TestCaseType {
410 Positive,
411 NegativeBoundary,
412 NegativeType,
413 NegativeConstraint,
414 NegativeNull,
415 NegativeOverflow,
416}
417
418#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
419pub struct TestArgumentValue {
420 pub argument_name: String,
421 pub value_type: TestValueType,
422}
423
424#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
425#[serde(tag = "variant")]
426pub enum TestValueType {
427 Valid { description: String },
428 Invalid { description: String, reason: String },
429}
430
431#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Serialize, Deserialize)]
432#[serde(tag = "variant")]
433pub enum ExpectedOutcome {
434 Success { state_changes: Vec<String> },
435 Failure {
436 error_code: Option<String>,
437 error_message: String,
438 },
439}
440
441
442
443
444