spi_program/generated/instructions/
middleware.rs1#[cfg(feature = "anchor")]
2use anchor_lang::prelude::{AnchorDeserialize, AnchorSerialize};
3#[cfg(not(feature = "anchor"))]
4use borsh::{BorshDeserialize, BorshSerialize};
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct MetaEntry {
9 pub pubkey: solana_program::pubkey::Pubkey,
11 pub is_signer: bool,
13 pub is_writable: bool,
15}
16
17pub struct DynamicInstruction {
19 pub target_program_id: solana_program::pubkey::Pubkey,
21 pub data: Vec<u8>,
23 pub account_metas: Vec<MetaEntry>,
25}
26
27impl DynamicInstruction {
28 pub fn instruction(&self) -> solana_program::instruction::Instruction {
29 self.instruction_with_remaining_accounts(&[])
30 }
31
32 pub fn instruction_with_remaining_accounts(
33 &self,
34 remaining_accounts: &[solana_program::instruction::AccountMeta],
35 ) -> solana_program::instruction::Instruction {
36 let mut accounts = Vec::with_capacity(self.account_metas.len() + remaining_accounts.len());
37
38 for meta in &self.account_metas {
39 accounts.push(solana_program::instruction::AccountMeta {
40 pubkey: meta.pubkey,
41 is_signer: meta.is_signer,
42 is_writable: meta.is_writable,
43 });
44 }
45
46 accounts.extend_from_slice(remaining_accounts);
47
48 solana_program::instruction::Instruction {
49 program_id: self.target_program_id,
50 accounts,
51 data: self.data.clone(),
52 }
53 }
54}
55
56#[cfg_attr(not(feature = "anchor"), derive(BorshSerialize, BorshDeserialize))]
57#[cfg_attr(feature = "anchor", derive(AnchorSerialize, AnchorDeserialize))]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59#[derive(Clone, Debug, Eq, PartialEq)]
60pub struct MiddlewareArgs {
61 pub instruction_data: Vec<u8>,
63}
64
65#[derive(Default)]
66pub struct MiddlewareBuilder {
67 target_program_id: Option<solana_program::pubkey::Pubkey>,
68 data: Option<Vec<u8>>,
69 account_metas: Vec<MetaEntry>,
70 __remaining_accounts: Vec<solana_program::instruction::AccountMeta>,
71}
72
73impl MiddlewareBuilder {
74 pub fn new() -> Self {
75 Self::default()
76 }
77
78 pub fn target_program_id(mut self, target_program_id: solana_program::pubkey::Pubkey) -> Self {
80 self.target_program_id = Some(target_program_id);
81 self
82 }
83
84 pub fn data(mut self, data: Vec<u8>) -> Self {
86 self.data = Some(data);
87 self
88 }
89
90 pub fn add_account_meta(
92 mut self,
93 pubkey: solana_program::pubkey::Pubkey,
94 is_signer: bool,
95 is_writable: bool,
96 ) -> Self {
97 self.account_metas.push(MetaEntry {
98 pubkey,
99 is_signer,
100 is_writable,
101 });
102 self
103 }
104
105 pub fn add_remaining_account(
107 &mut self,
108 account: solana_program::instruction::AccountMeta,
109 ) -> &mut Self {
110 self.__remaining_accounts.push(account);
111 self
112 }
113
114 pub fn add_remaining_accounts(
116 &mut self,
117 accounts: &[solana_program::instruction::AccountMeta],
118 ) -> &mut Self {
119 self.__remaining_accounts.extend_from_slice(accounts);
120 self
121 }
122
123 pub fn instruction(&self) -> solana_program::instruction::Instruction {
125 let dynamic = DynamicInstruction {
126 target_program_id: self
127 .target_program_id
128 .expect("target_program_id is required"),
129 data: self.data.clone().expect("data is required"),
130 account_metas: self.account_metas.clone(),
131 };
132
133 dynamic.instruction_with_remaining_accounts(&self.__remaining_accounts)
134 }
135}
136