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