nifty_asset_interface/
processor.rs1use solana_program::{
2 account_info::AccountInfo,
3 entrypoint::ProgramResult,
4 instruction::{AccountMeta, Instruction},
5 program::invoke_signed,
6 program_error::ProgramError,
7 pubkey::Pubkey,
8};
9
10use crate::Interface;
11
12#[macro_export]
24macro_rules! fetch_proxy_data {
25 ( $data:expr, $signer:ident, $authority:ident ) => {
26 let __proxy = $crate::state::Asset::get::<$crate::extensions::Proxy>($data)
28 .ok_or(solana_program::program_error::ProgramError::InvalidAccountData)?;
29
30 let __seeds = *__proxy.seeds;
31 let $signer = [__seeds.as_ref(), &[*__proxy.bump]];
32
33 let $authority = if let Some(authority) = __proxy.authority.value() {
34 Some(*authority)
35 } else {
36 None
37 };
38 };
39
40 ( $data:expr, $signer:ident, $authority:ident, $program:ident, $remaining:expr ) => {
41 fetch_proxy_data!($data, $signer, $authority);
42
43 let $program = $remaining
44 .iter()
45 .find(|account| {
46 account.key
47 == &solana_program::pubkey!("AssetGtQBTSgm5s91d1RAQod5JmaZiJDxqsgtqrZud73")
48 })
49 .ok_or(solana_program::program_error::ProgramError::NotEnoughAccountKeys)?;
50 };
51}
52
53macro_rules! log_instruction_name {
58 ( $instruction_data:expr ) => {{
59 if $instruction_data.is_empty() {
60 return Err(solana_program::program_error::ProgramError::InvalidInstructionData);
61 }
62
63 let name = match $instruction_data[0] {
64 0 => "Close",
65 1 => "Burn",
66 2 => "Create",
67 3 => "Approve",
68 4 => "Allocate",
69 5 => "Lock",
70 6 => "Revoke",
71 7 => "Transfer",
72 8 => "Unlock",
73 9 => "Unverify",
74 10 => "Update",
75 11 => "Verify",
76 12 => "Write",
77 13 => "Group",
78 14 => "Ungroup",
79 15 => "Handover",
80 16 => "Remove",
81 _ => return Err(solana_program::program_error::ProgramError::InvalidInstructionData),
82 };
83
84 solana_program::msg!("Interface: {}", name);
85 }};
86}
87
88impl Interface {
89 pub fn process_instruction<'a>(
91 _program_id: &'a Pubkey,
92 accounts: &'a [AccountInfo<'a>],
93 instruction_data: &[u8],
94 ) -> ProgramResult {
95 log_instruction_name!(instruction_data);
96
97 let asset = accounts.first().ok_or(ProgramError::NotEnoughAccountKeys)?;
98 let data = (*asset.data).borrow();
99 fetch_proxy_data!(&data, signer, _authority);
100 drop(data);
102
103 let mut account_metas = Vec::with_capacity(accounts.len());
104 accounts.iter().for_each(|account| {
105 account_metas.push(AccountMeta {
106 pubkey: *account.key,
107 is_signer: account.is_signer,
108 is_writable: account.is_writable,
109 });
110 });
111 account_metas.first_mut().unwrap().is_signer = true;
113
114 invoke_signed(
115 &Instruction {
116 accounts: account_metas,
117 data: instruction_data.to_vec(),
118 program_id: solana_program::pubkey!("AssetGtQBTSgm5s91d1RAQod5JmaZiJDxqsgtqrZud73"),
119 },
120 accounts,
121 &[&signer],
122 )
123 }
124}