token_interface.rs 2.8 KB

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