token_interface.rs 2.8 KB

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