spl_token_2022_interface/extension/transfer_hook/
mod.rs1use {
2 crate::{
3 extension::{
4 BaseState, BaseStateWithExtensions, BaseStateWithExtensionsMut, Extension,
5 ExtensionType, PodStateWithExtensionsMut,
6 },
7 pod::PodAccount,
8 },
9 bytemuck::{Pod, Zeroable},
10 solana_account_info::AccountInfo,
11 solana_address::Address,
12 solana_nullable::MaybeNull,
13 solana_program_error::ProgramError,
14 solana_zero_copy::unaligned::Bool,
15};
16#[cfg(feature = "serde")]
17use {
18 serde::{Deserialize, Serialize},
19 serde_with::{As, DisplayFromStr},
20};
21
22pub mod instruction;
24
25#[repr(C)]
27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
28#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
29#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
30pub struct TransferHook {
31 #[cfg_attr(feature = "serde", serde(with = "As::<Option<DisplayFromStr>>"))]
33 pub authority: MaybeNull<Address>,
34 #[cfg_attr(feature = "serde", serde(with = "As::<Option<DisplayFromStr>>"))]
36 pub program_id: MaybeNull<Address>,
37}
38
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
42#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
43#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
44#[repr(transparent)]
45pub struct TransferHookAccount {
46 pub transferring: Bool,
48}
49
50impl Extension for TransferHook {
51 const TYPE: ExtensionType = ExtensionType::TransferHook;
52}
53
54impl Extension for TransferHookAccount {
55 const TYPE: ExtensionType = ExtensionType::TransferHookAccount;
56}
57
58pub fn get_program_id<S: BaseState, BSE: BaseStateWithExtensions<S>>(
61 state: &BSE,
62) -> Option<Address> {
63 state
64 .get_extension::<TransferHook>()
65 .ok()
66 .and_then(|e| Option::<Address>::from(e.program_id))
67}
68
69pub fn set_transferring<BSE: BaseStateWithExtensionsMut<S>, S: BaseState>(
72 account: &mut BSE,
73) -> Result<(), ProgramError> {
74 let account_extension = account.get_extension_mut::<TransferHookAccount>()?;
75 account_extension.transferring = true.into();
76 Ok(())
77}
78
79pub fn unset_transferring(account_info: &AccountInfo) -> Result<(), ProgramError> {
81 let mut account_data = account_info.data.borrow_mut();
82 let mut account = PodStateWithExtensionsMut::<PodAccount>::unpack(&mut account_data)?;
83 let account_extension = account.get_extension_mut::<TransferHookAccount>()?;
84 account_extension.transferring = false.into();
85 Ok(())
86}