1use crate::generated::types::PermissionStrategy;
9use borsh::BorshDeserialize;
10use borsh::BorshSerialize;
11
12pub const CREATE_POLICY_DISCRIMINATOR: u8 = 0;
13
14#[derive(Debug)]
16pub struct CreatePolicy {
17 pub mint: solana_pubkey::Pubkey,
19 pub token_account: solana_pubkey::Pubkey,
21 pub policy: solana_pubkey::Pubkey,
23 pub payer: solana_pubkey::Pubkey,
25 pub owner: solana_pubkey::Pubkey,
27 pub system_program: solana_pubkey::Pubkey,
29}
30
31impl CreatePolicy {
32 pub fn instruction(
33 &self,
34 args: CreatePolicyInstructionArgs,
35 ) -> solana_instruction::Instruction {
36 self.instruction_with_remaining_accounts(args, &[])
37 }
38 #[allow(clippy::arithmetic_side_effects)]
39 #[allow(clippy::vec_init_then_push)]
40 pub fn instruction_with_remaining_accounts(
41 &self,
42 args: CreatePolicyInstructionArgs,
43 remaining_accounts: &[solana_instruction::AccountMeta],
44 ) -> solana_instruction::Instruction {
45 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
46 accounts.push(solana_instruction::AccountMeta::new_readonly(
47 self.mint, false,
48 ));
49 accounts.push(solana_instruction::AccountMeta::new_readonly(
50 self.token_account,
51 false,
52 ));
53 accounts.push(solana_instruction::AccountMeta::new(self.policy, false));
54 accounts.push(solana_instruction::AccountMeta::new(self.payer, true));
55 accounts.push(solana_instruction::AccountMeta::new(self.owner, true));
56 accounts.push(solana_instruction::AccountMeta::new_readonly(
57 self.system_program,
58 false,
59 ));
60 accounts.extend_from_slice(remaining_accounts);
61 let mut data = CreatePolicyInstructionData::new().try_to_vec().unwrap();
62 let mut args = args.try_to_vec().unwrap();
63 data.append(&mut args);
64
65 solana_instruction::Instruction {
66 program_id: crate::SHIELD_ID,
67 accounts,
68 data,
69 }
70 }
71}
72
73#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
74#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75pub struct CreatePolicyInstructionData {
76 discriminator: u8,
77}
78
79impl CreatePolicyInstructionData {
80 pub fn new() -> Self {
81 Self { discriminator: 0 }
82 }
83
84 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
85 borsh::to_vec(self)
86 }
87}
88
89impl Default for CreatePolicyInstructionData {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
96#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
97pub struct CreatePolicyInstructionArgs {
98 pub strategy: PermissionStrategy,
99}
100
101impl CreatePolicyInstructionArgs {
102 pub(crate) fn try_to_vec(&self) -> Result<Vec<u8>, std::io::Error> {
103 borsh::to_vec(self)
104 }
105}
106
107#[derive(Clone, Debug, Default)]
118pub struct CreatePolicyBuilder {
119 mint: Option<solana_pubkey::Pubkey>,
120 token_account: Option<solana_pubkey::Pubkey>,
121 policy: Option<solana_pubkey::Pubkey>,
122 payer: Option<solana_pubkey::Pubkey>,
123 owner: Option<solana_pubkey::Pubkey>,
124 system_program: Option<solana_pubkey::Pubkey>,
125 strategy: Option<PermissionStrategy>,
126 __remaining_accounts: Vec<solana_instruction::AccountMeta>,
127}
128
129impl CreatePolicyBuilder {
130 pub fn new() -> Self {
131 Self::default()
132 }
133 #[inline(always)]
135 pub fn mint(&mut self, mint: solana_pubkey::Pubkey) -> &mut Self {
136 self.mint = Some(mint);
137 self
138 }
139 #[inline(always)]
141 pub fn token_account(&mut self, token_account: solana_pubkey::Pubkey) -> &mut Self {
142 self.token_account = Some(token_account);
143 self
144 }
145 #[inline(always)]
147 pub fn policy(&mut self, policy: solana_pubkey::Pubkey) -> &mut Self {
148 self.policy = Some(policy);
149 self
150 }
151 #[inline(always)]
153 pub fn payer(&mut self, payer: solana_pubkey::Pubkey) -> &mut Self {
154 self.payer = Some(payer);
155 self
156 }
157 #[inline(always)]
159 pub fn owner(&mut self, owner: solana_pubkey::Pubkey) -> &mut Self {
160 self.owner = Some(owner);
161 self
162 }
163 #[inline(always)]
166 pub fn system_program(&mut self, system_program: solana_pubkey::Pubkey) -> &mut Self {
167 self.system_program = Some(system_program);
168 self
169 }
170 #[inline(always)]
171 pub fn strategy(&mut self, strategy: PermissionStrategy) -> &mut Self {
172 self.strategy = Some(strategy);
173 self
174 }
175 #[inline(always)]
177 pub fn add_remaining_account(&mut self, account: solana_instruction::AccountMeta) -> &mut Self {
178 self.__remaining_accounts.push(account);
179 self
180 }
181 #[inline(always)]
183 pub fn add_remaining_accounts(
184 &mut self,
185 accounts: &[solana_instruction::AccountMeta],
186 ) -> &mut Self {
187 self.__remaining_accounts.extend_from_slice(accounts);
188 self
189 }
190 #[allow(clippy::clone_on_copy)]
191 pub fn instruction(&self) -> solana_instruction::Instruction {
192 let accounts = CreatePolicy {
193 mint: self.mint.expect("mint is not set"),
194 token_account: self.token_account.expect("token_account is not set"),
195 policy: self.policy.expect("policy is not set"),
196 payer: self.payer.expect("payer is not set"),
197 owner: self.owner.expect("owner is not set"),
198 system_program: self
199 .system_program
200 .unwrap_or(solana_pubkey::pubkey!("11111111111111111111111111111111")),
201 };
202 let args = CreatePolicyInstructionArgs {
203 strategy: self.strategy.clone().expect("strategy is not set"),
204 };
205
206 accounts.instruction_with_remaining_accounts(args, &self.__remaining_accounts)
207 }
208}
209
210pub struct CreatePolicyCpiAccounts<'a, 'b> {
212 pub mint: &'b solana_account_info::AccountInfo<'a>,
214 pub token_account: &'b solana_account_info::AccountInfo<'a>,
216 pub policy: &'b solana_account_info::AccountInfo<'a>,
218 pub payer: &'b solana_account_info::AccountInfo<'a>,
220 pub owner: &'b solana_account_info::AccountInfo<'a>,
222 pub system_program: &'b solana_account_info::AccountInfo<'a>,
224}
225
226pub struct CreatePolicyCpi<'a, 'b> {
228 pub __program: &'b solana_account_info::AccountInfo<'a>,
230 pub mint: &'b solana_account_info::AccountInfo<'a>,
232 pub token_account: &'b solana_account_info::AccountInfo<'a>,
234 pub policy: &'b solana_account_info::AccountInfo<'a>,
236 pub payer: &'b solana_account_info::AccountInfo<'a>,
238 pub owner: &'b solana_account_info::AccountInfo<'a>,
240 pub system_program: &'b solana_account_info::AccountInfo<'a>,
242 pub __args: CreatePolicyInstructionArgs,
244}
245
246impl<'a, 'b> CreatePolicyCpi<'a, 'b> {
247 pub fn new(
248 program: &'b solana_account_info::AccountInfo<'a>,
249 accounts: CreatePolicyCpiAccounts<'a, 'b>,
250 args: CreatePolicyInstructionArgs,
251 ) -> Self {
252 Self {
253 __program: program,
254 mint: accounts.mint,
255 token_account: accounts.token_account,
256 policy: accounts.policy,
257 payer: accounts.payer,
258 owner: accounts.owner,
259 system_program: accounts.system_program,
260 __args: args,
261 }
262 }
263 #[inline(always)]
264 pub fn invoke(&self) -> solana_program_error::ProgramResult {
265 self.invoke_signed_with_remaining_accounts(&[], &[])
266 }
267 #[inline(always)]
268 pub fn invoke_with_remaining_accounts(
269 &self,
270 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
271 ) -> solana_program_error::ProgramResult {
272 self.invoke_signed_with_remaining_accounts(&[], remaining_accounts)
273 }
274 #[inline(always)]
275 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
276 self.invoke_signed_with_remaining_accounts(signers_seeds, &[])
277 }
278 #[allow(clippy::arithmetic_side_effects)]
279 #[allow(clippy::clone_on_copy)]
280 #[allow(clippy::vec_init_then_push)]
281 pub fn invoke_signed_with_remaining_accounts(
282 &self,
283 signers_seeds: &[&[&[u8]]],
284 remaining_accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
285 ) -> solana_program_error::ProgramResult {
286 let mut accounts = Vec::with_capacity(6 + remaining_accounts.len());
287 accounts.push(solana_instruction::AccountMeta::new_readonly(
288 *self.mint.key,
289 false,
290 ));
291 accounts.push(solana_instruction::AccountMeta::new_readonly(
292 *self.token_account.key,
293 false,
294 ));
295 accounts.push(solana_instruction::AccountMeta::new(
296 *self.policy.key,
297 false,
298 ));
299 accounts.push(solana_instruction::AccountMeta::new(*self.payer.key, true));
300 accounts.push(solana_instruction::AccountMeta::new(*self.owner.key, true));
301 accounts.push(solana_instruction::AccountMeta::new_readonly(
302 *self.system_program.key,
303 false,
304 ));
305 remaining_accounts.iter().for_each(|remaining_account| {
306 accounts.push(solana_instruction::AccountMeta {
307 pubkey: *remaining_account.0.key,
308 is_signer: remaining_account.1,
309 is_writable: remaining_account.2,
310 })
311 });
312 let mut data = CreatePolicyInstructionData::new().try_to_vec().unwrap();
313 let mut args = self.__args.try_to_vec().unwrap();
314 data.append(&mut args);
315
316 let instruction = solana_instruction::Instruction {
317 program_id: crate::SHIELD_ID,
318 accounts,
319 data,
320 };
321 let mut account_infos = Vec::with_capacity(7 + remaining_accounts.len());
322 account_infos.push(self.__program.clone());
323 account_infos.push(self.mint.clone());
324 account_infos.push(self.token_account.clone());
325 account_infos.push(self.policy.clone());
326 account_infos.push(self.payer.clone());
327 account_infos.push(self.owner.clone());
328 account_infos.push(self.system_program.clone());
329 remaining_accounts
330 .iter()
331 .for_each(|remaining_account| account_infos.push(remaining_account.0.clone()));
332
333 if signers_seeds.is_empty() {
334 solana_cpi::invoke(&instruction, &account_infos)
335 } else {
336 solana_cpi::invoke_signed(&instruction, &account_infos, signers_seeds)
337 }
338 }
339}
340
341#[derive(Clone, Debug)]
352pub struct CreatePolicyCpiBuilder<'a, 'b> {
353 instruction: Box<CreatePolicyCpiBuilderInstruction<'a, 'b>>,
354}
355
356impl<'a, 'b> CreatePolicyCpiBuilder<'a, 'b> {
357 pub fn new(program: &'b solana_account_info::AccountInfo<'a>) -> Self {
358 let instruction = Box::new(CreatePolicyCpiBuilderInstruction {
359 __program: program,
360 mint: None,
361 token_account: None,
362 policy: None,
363 payer: None,
364 owner: None,
365 system_program: None,
366 strategy: None,
367 __remaining_accounts: Vec::new(),
368 });
369 Self { instruction }
370 }
371 #[inline(always)]
373 pub fn mint(&mut self, mint: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
374 self.instruction.mint = Some(mint);
375 self
376 }
377 #[inline(always)]
379 pub fn token_account(
380 &mut self,
381 token_account: &'b solana_account_info::AccountInfo<'a>,
382 ) -> &mut Self {
383 self.instruction.token_account = Some(token_account);
384 self
385 }
386 #[inline(always)]
388 pub fn policy(&mut self, policy: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
389 self.instruction.policy = Some(policy);
390 self
391 }
392 #[inline(always)]
394 pub fn payer(&mut self, payer: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
395 self.instruction.payer = Some(payer);
396 self
397 }
398 #[inline(always)]
400 pub fn owner(&mut self, owner: &'b solana_account_info::AccountInfo<'a>) -> &mut Self {
401 self.instruction.owner = Some(owner);
402 self
403 }
404 #[inline(always)]
406 pub fn system_program(
407 &mut self,
408 system_program: &'b solana_account_info::AccountInfo<'a>,
409 ) -> &mut Self {
410 self.instruction.system_program = Some(system_program);
411 self
412 }
413 #[inline(always)]
414 pub fn strategy(&mut self, strategy: PermissionStrategy) -> &mut Self {
415 self.instruction.strategy = Some(strategy);
416 self
417 }
418 #[inline(always)]
420 pub fn add_remaining_account(
421 &mut self,
422 account: &'b solana_account_info::AccountInfo<'a>,
423 is_writable: bool,
424 is_signer: bool,
425 ) -> &mut Self {
426 self.instruction
427 .__remaining_accounts
428 .push((account, is_writable, is_signer));
429 self
430 }
431 #[inline(always)]
436 pub fn add_remaining_accounts(
437 &mut self,
438 accounts: &[(&'b solana_account_info::AccountInfo<'a>, bool, bool)],
439 ) -> &mut Self {
440 self.instruction
441 .__remaining_accounts
442 .extend_from_slice(accounts);
443 self
444 }
445 #[inline(always)]
446 pub fn invoke(&self) -> solana_program_error::ProgramResult {
447 self.invoke_signed(&[])
448 }
449 #[allow(clippy::clone_on_copy)]
450 #[allow(clippy::vec_init_then_push)]
451 pub fn invoke_signed(&self, signers_seeds: &[&[&[u8]]]) -> solana_program_error::ProgramResult {
452 let args = CreatePolicyInstructionArgs {
453 strategy: self
454 .instruction
455 .strategy
456 .clone()
457 .expect("strategy is not set"),
458 };
459 let instruction = CreatePolicyCpi {
460 __program: self.instruction.__program,
461
462 mint: self.instruction.mint.expect("mint is not set"),
463
464 token_account: self
465 .instruction
466 .token_account
467 .expect("token_account is not set"),
468
469 policy: self.instruction.policy.expect("policy is not set"),
470
471 payer: self.instruction.payer.expect("payer is not set"),
472
473 owner: self.instruction.owner.expect("owner is not set"),
474
475 system_program: self
476 .instruction
477 .system_program
478 .expect("system_program is not set"),
479 __args: args,
480 };
481 instruction.invoke_signed_with_remaining_accounts(
482 signers_seeds,
483 &self.instruction.__remaining_accounts,
484 )
485 }
486}
487
488#[derive(Clone, Debug)]
489struct CreatePolicyCpiBuilderInstruction<'a, 'b> {
490 __program: &'b solana_account_info::AccountInfo<'a>,
491 mint: Option<&'b solana_account_info::AccountInfo<'a>>,
492 token_account: Option<&'b solana_account_info::AccountInfo<'a>>,
493 policy: Option<&'b solana_account_info::AccountInfo<'a>>,
494 payer: Option<&'b solana_account_info::AccountInfo<'a>>,
495 owner: Option<&'b solana_account_info::AccountInfo<'a>>,
496 system_program: Option<&'b solana_account_info::AccountInfo<'a>>,
497 strategy: Option<PermissionStrategy>,
498 __remaining_accounts: Vec<(&'b solana_account_info::AccountInfo<'a>, bool, bool)>,
500}