lib.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. use anchor_lang::{prelude::*, solana_program::clock::UnixTimestamp};
  2. declare_id!("Newid11111111111111111111111111111111111111");
  3. #[program]
  4. pub mod new_idl {
  5. use super::*;
  6. pub fn no_case_conversion(ctx: Context<NoCaseConversion>, field_name: u8) -> Result<()> {
  7. ctx.accounts.case_conversion_account.field_name = field_name;
  8. emit!(SimpleEvent { field_name });
  9. Ok(())
  10. }
  11. pub fn empty(_ctx: Context<Empty>) -> Result<()> {
  12. Ok(())
  13. }
  14. pub fn primitive_types(
  15. ctx: Context<PrimitiveTypes>,
  16. bool: bool,
  17. i8: i8,
  18. i16: i16,
  19. i32: i32,
  20. i64: i64,
  21. i128: i128,
  22. u8: u8,
  23. u16: u16,
  24. u32: u32,
  25. u64: u64,
  26. u128: u128,
  27. f32: f32,
  28. f64: f64,
  29. pubkey: Pubkey,
  30. ) -> Result<()> {
  31. ctx.accounts.account.bool = bool;
  32. ctx.accounts.account.i8 = i8;
  33. ctx.accounts.account.i16 = i16;
  34. ctx.accounts.account.i32 = i32;
  35. ctx.accounts.account.i64 = i64;
  36. ctx.accounts.account.i128 = i128;
  37. ctx.accounts.account.u8 = u8;
  38. ctx.accounts.account.u16 = u16;
  39. ctx.accounts.account.u32 = u32;
  40. ctx.accounts.account.u64 = u64;
  41. ctx.accounts.account.u128 = u128;
  42. ctx.accounts.account.f32 = f32;
  43. ctx.accounts.account.f64 = f64;
  44. ctx.accounts.account.pubkey = pubkey;
  45. Ok(())
  46. }
  47. pub fn unsized_types(ctx: Context<UnsizedTypes>, string: String, bytes: Vec<u8>) -> Result<()> {
  48. ctx.accounts.account.string = string;
  49. ctx.accounts.account.bytes = bytes;
  50. Ok(())
  51. }
  52. pub fn strct(
  53. ctx: Context<Struct>,
  54. unit: UnitStruct,
  55. named: NamedStruct,
  56. tuple: TupleStruct,
  57. ) -> Result<()> {
  58. ctx.accounts.account.unit = unit;
  59. ctx.accounts.account.named = named;
  60. ctx.accounts.account.tuple = tuple;
  61. Ok(())
  62. }
  63. pub fn enm(ctx: Context<Enum>, full_enum: FullEnum) -> Result<()> {
  64. ctx.accounts.account.full_enum = full_enum;
  65. Ok(())
  66. }
  67. pub fn type_alias(
  68. ctx: Context<TypeAlias>,
  69. alias_u8: AliasU8,
  70. alias_u8_array: AliasU8Array,
  71. alias_struct: AliasStruct,
  72. alias_vec_string: AliasVec<String>,
  73. alias_option_vec_pubkey: AliasOptionVec<Pubkey>,
  74. alias_generic_const: AliasGenericConst<4>,
  75. alias_multiple_generics_mixed: AliasMultipleGenericMixed<bool, 2>,
  76. alias_external: UnixTimestamp,
  77. ) -> Result<()> {
  78. ctx.accounts.account.alias_u8 = alias_u8;
  79. ctx.accounts.account.alias_u8_array = alias_u8_array;
  80. ctx.accounts.account.alias_struct = alias_struct;
  81. ctx.accounts.account.alias_vec_string = alias_vec_string;
  82. ctx.accounts.account.alias_option_vec_pubkey = alias_option_vec_pubkey;
  83. ctx.accounts.account.alias_generic_const = alias_generic_const;
  84. ctx.accounts.account.alias_multiple_generics_mixed = alias_multiple_generics_mixed;
  85. ctx.accounts.account.alias_external = alias_external;
  86. Ok(())
  87. }
  88. pub fn account_and_event_arg_and_field(
  89. ctx: Context<AccountAndEventArgAndField>,
  90. account: AccountAndEventFieldAccount,
  91. ) -> Result<()> {
  92. *ctx.accounts.account = account;
  93. Ok(())
  94. }
  95. pub fn generic(ctx: Context<Generic>, generic_arg: GenericStruct<u16, 4>) -> Result<()> {
  96. ctx.accounts.my_account.field = generic_arg;
  97. Ok(())
  98. }
  99. pub fn full_path(
  100. ctx: Context<FullPath>,
  101. named_struct: NamedStruct,
  102. some_module_named_struct: some_module::NamedStruct,
  103. ) -> Result<()> {
  104. ctx.accounts.account.named_struct = named_struct;
  105. ctx.accounts.account.some_module_named_struct = some_module_named_struct;
  106. Ok(())
  107. }
  108. pub fn external(ctx: Context<External>, my_struct: external::MyStruct) -> Result<()> {
  109. ctx.accounts.account.my_struct = my_struct;
  110. Ok(())
  111. }
  112. pub fn external_non_anchor(
  113. ctx: Context<ExternalNonAnchor>,
  114. feature: wrapped::Feature,
  115. ) -> Result<()> {
  116. ctx.accounts.account.feature = feature;
  117. Ok(())
  118. }
  119. }
  120. #[account]
  121. #[derive(InitSpace)]
  122. pub struct SimpleAccount {
  123. pub field_name: u8,
  124. }
  125. #[event]
  126. #[derive(Clone)]
  127. pub struct SimpleEvent {
  128. pub field_name: u8,
  129. }
  130. #[derive(Accounts)]
  131. pub struct NoCaseConversion<'info> {
  132. #[account(init, payer = payer, space = 8 + SimpleAccount::INIT_SPACE)]
  133. pub case_conversion_account: Account<'info, SimpleAccount>,
  134. #[account(mut)]
  135. pub payer: Signer<'info>,
  136. pub system_program: Program<'info, System>,
  137. }
  138. #[derive(Accounts)]
  139. pub struct Empty {}
  140. #[derive(Accounts)]
  141. pub struct PrimitiveTypes<'info> {
  142. #[account(zero)]
  143. pub account: Account<'info, PrimitiveAccount>,
  144. }
  145. #[account]
  146. pub struct PrimitiveAccount {
  147. pub bool: bool,
  148. pub i8: i8,
  149. pub i16: i16,
  150. pub i32: i32,
  151. pub i64: i64,
  152. pub i128: i128,
  153. pub u8: u8,
  154. pub u16: u16,
  155. pub u32: u32,
  156. pub u64: u64,
  157. pub u128: u128,
  158. pub f32: f32,
  159. pub f64: f64,
  160. pub pubkey: Pubkey,
  161. }
  162. #[derive(Accounts)]
  163. pub struct UnsizedTypes<'info> {
  164. #[account(zero)]
  165. pub account: Account<'info, UnsizedAccount>,
  166. }
  167. #[account]
  168. pub struct UnsizedAccount {
  169. pub string: String,
  170. pub bytes: Vec<u8>,
  171. }
  172. #[derive(Accounts)]
  173. pub struct Struct<'info> {
  174. #[account(zero)]
  175. pub account: Account<'info, StructAccount>,
  176. }
  177. #[account]
  178. pub struct StructAccount {
  179. pub unit: UnitStruct,
  180. pub named: NamedStruct,
  181. pub tuple: TupleStruct,
  182. }
  183. #[derive(AnchorDeserialize, AnchorSerialize, Clone)]
  184. pub struct UnitStruct;
  185. #[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, Eq, PartialEq)]
  186. pub struct NamedStruct {
  187. pub u8: u8,
  188. pub u16: u16,
  189. pub u32: u32,
  190. pub u64: u64,
  191. }
  192. #[derive(AnchorDeserialize, AnchorSerialize, Clone)]
  193. pub struct TupleStruct(u64, String);
  194. #[derive(Accounts)]
  195. pub struct Enum<'info> {
  196. #[account(zero)]
  197. pub account: Account<'info, EnumAccount>,
  198. }
  199. #[account]
  200. pub struct EnumAccount {
  201. pub full_enum: FullEnum,
  202. }
  203. #[derive(AnchorSerialize, AnchorDeserialize, Clone, Copy, Debug, Eq, PartialEq)]
  204. pub enum FullEnum {
  205. Unit,
  206. Named { point_x: u64, point_y: u64 },
  207. Unnamed(u8, u8, u16, u16),
  208. UnnamedStruct(NamedStruct),
  209. }
  210. #[derive(Accounts)]
  211. pub struct TypeAlias<'info> {
  212. #[account(zero)]
  213. pub account: Account<'info, AliasAccount>,
  214. }
  215. #[account]
  216. pub struct AliasAccount {
  217. pub alias_u8: AliasU8,
  218. pub alias_u8_array: AliasU8Array,
  219. pub alias_struct: AliasStruct,
  220. pub alias_vec_string: AliasVec<String>,
  221. pub alias_option_vec_pubkey: AliasOptionVec<Pubkey>,
  222. pub alias_generic_const: AliasGenericConst<4>,
  223. pub alias_multiple_generics_mixed: AliasMultipleGenericMixed<bool, 2>,
  224. pub alias_external: UnixTimestamp,
  225. }
  226. pub type AliasU8 = u8;
  227. pub type AliasU8Array = [AliasU8; 8];
  228. pub type AliasStruct = NamedStruct;
  229. pub type AliasVec<T> = Vec<T>;
  230. pub type AliasOptionVec<T> = Vec<Option<T>>;
  231. pub type AliasGenericConst<const N: usize> = [u32; N];
  232. pub type AliasMultipleGenericMixed<T, const N: usize> = Vec<[T; N]>;
  233. #[derive(Accounts)]
  234. pub struct AccountAndEventArgAndField<'info> {
  235. #[account(zero)]
  236. pub account: Account<'info, AccountAndEventFieldAccount>,
  237. }
  238. #[account]
  239. pub struct AccountAndEventFieldAccount {
  240. pub simple_account: SimpleAccount,
  241. pub simple_event: SimpleEvent,
  242. }
  243. #[derive(Accounts)]
  244. pub struct FullPath<'info> {
  245. #[account(zero)]
  246. pub account: Account<'info, FullPathAccount>,
  247. }
  248. #[account]
  249. pub struct FullPathAccount {
  250. pub named_struct: NamedStruct,
  251. pub some_module_named_struct: some_module::NamedStruct,
  252. }
  253. mod some_module {
  254. use super::*;
  255. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  256. pub struct NamedStruct {
  257. pub data: u8,
  258. }
  259. }
  260. #[derive(Accounts)]
  261. pub struct Generic<'info> {
  262. #[account(mut)]
  263. pub signer: Signer<'info>,
  264. #[account(
  265. init,
  266. payer = signer,
  267. space = 1024,
  268. seeds = [b"generic", signer.key.as_ref()],
  269. bump
  270. )]
  271. pub my_account: Account<'info, GenericAccount>,
  272. pub system_program: Program<'info, System>,
  273. }
  274. #[account]
  275. pub struct GenericAccount {
  276. pub field: GenericStruct<u16, 4>,
  277. }
  278. #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
  279. pub struct GenericStruct<T, const N: usize> {
  280. arr: [T; N],
  281. sub_field: SubGenericStruct<8, T, Vec<Option<T>>>,
  282. }
  283. #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
  284. pub struct SubGenericStruct<const N: usize, T, U> {
  285. sub_arr: [T; N],
  286. another: U,
  287. }
  288. #[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug)]
  289. pub enum GenericEnum<T> {
  290. Unit,
  291. Named { x: T },
  292. Tuple(Vec<T>),
  293. }
  294. #[derive(Accounts)]
  295. pub struct External<'info> {
  296. #[account(zero)]
  297. pub account: Account<'info, AccountWithExternalField>,
  298. }
  299. #[account]
  300. pub struct AccountWithExternalField {
  301. pub my_struct: external::MyStruct,
  302. }
  303. #[derive(Accounts)]
  304. pub struct ExternalNonAnchor<'info> {
  305. #[account(zero)]
  306. pub account: Account<'info, AccountWithNonAnchorExternalField>,
  307. }
  308. #[account]
  309. pub struct AccountWithNonAnchorExternalField {
  310. pub feature: wrapped::Feature,
  311. }
  312. /// An example of wrapping a non-Anchor external type in order to include it in the IDL
  313. mod wrapped {
  314. use super::*;
  315. #[cfg(feature = "idl-build")]
  316. use anchor_lang::idl::types::*;
  317. pub struct Feature(anchor_lang::solana_program::feature::Feature);
  318. impl AnchorSerialize for Feature {
  319. fn serialize<W: std::io::prelude::Write>(&self, writer: &mut W) -> std::io::Result<()> {
  320. self.0.activated_at.serialize(writer)?;
  321. Ok(())
  322. }
  323. }
  324. impl AnchorDeserialize for Feature {
  325. fn deserialize_reader<R: std::io::prelude::Read>(reader: &mut R) -> std::io::Result<Self> {
  326. Ok(Self(anchor_lang::solana_program::feature::Feature {
  327. activated_at: AnchorDeserialize::deserialize_reader(reader)?,
  328. }))
  329. }
  330. }
  331. impl Clone for Feature {
  332. fn clone(&self) -> Self {
  333. Self(anchor_lang::solana_program::feature::Feature {
  334. activated_at: self.0.activated_at.clone(),
  335. })
  336. }
  337. }
  338. #[cfg(feature = "idl-build")]
  339. impl IdlBuild for Feature {
  340. fn create_type() -> Option<IdlTypeDef> {
  341. Some(IdlTypeDef {
  342. name: "Feature".into(),
  343. ty: IdlTypeDefTy::Struct {
  344. fields: Some(IdlDefinedFields::Named(vec![IdlField {
  345. name: "activated_at".into(),
  346. ty: IdlType::Option(Box::new(IdlType::U64)),
  347. docs: Default::default(),
  348. }])),
  349. },
  350. docs: Default::default(),
  351. generics: Default::default(),
  352. serialization: Default::default(),
  353. repr: Default::default(),
  354. })
  355. }
  356. }
  357. }