anchor_spl/
token_interface.rs1pub use crate::token_2022::*;
2#[cfg(feature = "token_2022_extensions")]
3pub use crate::token_2022_extensions::*;
4use {
5 anchor_lang::{
6 __private::bytemuck::Pod,
7 solana_program::{program_pack::Pack, pubkey::Pubkey},
8 },
9 spl_token_2022::extension::{
10 BaseStateWithExtensions, Extension, ExtensionType, StateWithExtensions,
11 },
12 std::ops::Deref,
13};
14
15static IDS: [Pubkey; 2] = [spl_token_interface::ID, spl_token_2022_interface::ID];
16
17#[derive(Clone, Debug, Default, PartialEq, Copy)]
18pub struct TokenAccount(spl_token_2022::state::Account);
19
20impl anchor_lang::AccountDeserialize for TokenAccount {
21 fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
22 spl_token_2022::extension::StateWithExtensions::<spl_token_2022::state::Account>::unpack(
23 buf,
24 )
25 .map(|t| TokenAccount(t.base))
26 .map_err(Into::into)
27 }
28}
29
30impl anchor_lang::AccountSerialize for TokenAccount {}
31
32impl anchor_lang::Owners for TokenAccount {
33 fn owners() -> &'static [Pubkey] {
34 &IDS
35 }
36}
37
38impl Deref for TokenAccount {
39 type Target = spl_token_2022::state::Account;
40
41 fn deref(&self) -> &Self::Target {
42 &self.0
43 }
44}
45
46#[derive(Clone, Debug, Default, PartialEq, Copy)]
47pub struct Mint(spl_token_2022::state::Mint);
48
49impl anchor_lang::AccountDeserialize for Mint {
50 fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
51 spl_token_2022::extension::StateWithExtensions::<spl_token_2022::state::Mint>::unpack(buf)
52 .map(|t| Mint(t.base))
53 .map_err(Into::into)
54 }
55}
56
57impl anchor_lang::AccountSerialize for Mint {}
58
59impl anchor_lang::Owners for Mint {
60 fn owners() -> &'static [Pubkey] {
61 &IDS
62 }
63}
64
65impl Deref for Mint {
66 type Target = spl_token_2022::state::Mint;
67
68 fn deref(&self) -> &Self::Target {
69 &self.0
70 }
71}
72
73#[derive(Clone)]
74pub struct TokenInterface;
75
76impl anchor_lang::Ids for TokenInterface {
77 fn ids() -> &'static [Pubkey] {
78 &IDS
79 }
80}
81
82pub type ExtensionsVec = Vec<ExtensionType>;
83
84pub fn find_mint_account_size(extensions: Option<&ExtensionsVec>) -> anchor_lang::Result<usize> {
85 if let Some(extensions) = extensions {
86 Ok(ExtensionType::try_calculate_account_len::<
87 spl_token_2022::state::Mint,
88 >(extensions)?)
89 } else {
90 Ok(spl_token_2022::state::Mint::LEN)
91 }
92}
93
94pub fn get_mint_extension_data<T: Extension + Pod>(
95 account: &anchor_lang::solana_program::account_info::AccountInfo,
96) -> anchor_lang::Result<T> {
97 let mint_data = account.data.borrow();
98 let mint_with_extension =
99 StateWithExtensions::<spl_token_2022::state::Mint>::unpack(&mint_data)?;
100 let extension_data = *mint_with_extension.get_extension::<T>()?;
101 Ok(extension_data)
102}