typhoon_utility_traits/
create.rs1use {
2 pinocchio::{cpi, sysvars::rent::Rent, AccountView, Address},
3 typhoon_accounts::{
4 Account, FromRaw, Mut, ReadableAccount, Signer, SignerCheck, SystemAccount,
5 UncheckedAccount, WritableAccount,
6 },
7 typhoon_errors::Error,
8 typhoon_traits::Discriminator,
9 typhoon_utility::create_account_with_minimum_balance_signed,
10};
11
12pub trait CreateAccountCpi<'a, T>
13where
14 Self: Sized + Into<&'a AccountView>,
15 T: ReadableAccount + FromRaw<'a>,
16{
17 type D: Discriminator;
18
19 #[inline(always)]
20 fn create(
21 self,
22 rent: &Rent,
23 payer: &impl WritableAccount,
24 owner: &Address,
25 space: usize,
26 seeds: Option<&[cpi::Signer]>,
27 ) -> Result<Mut<T>, Error> {
28 let info = self.into();
29 create_account_with_minimum_balance_signed(
30 info,
31 space,
32 owner,
33 payer.as_ref(),
34 rent,
35 seeds.unwrap_or_default(),
36 )?;
37
38 {
39 let data = info.data_ptr();
40 unsafe {
41 core::ptr::copy_nonoverlapping(
42 Self::D::DISCRIMINATOR.as_ptr(),
43 data,
44 Self::D::DISCRIMINATOR.len(),
45 );
46 }
47 }
48
49 Ok(Mut::from_raw_info(info))
50 }
51}
52
53macro_rules! impl_trait {
54 ($origin: ty) => {
55 impl<'a, T, C> CreateAccountCpi<'a, Signer<'a, Account<'a, T>, C>> for $origin
56 where
57 T: Discriminator,
58 C: SignerCheck,
59 {
60 type D = T;
61 }
62 impl<'a, T> CreateAccountCpi<'a, Account<'a, T>> for $origin
63 where
64 T: Discriminator,
65 {
66 type D = T;
67 }
68 };
69}
70
71impl_trait!(&'a AccountView);
72impl_trait!(SystemAccount<'a>);
73impl_trait!(UncheckedAccount<'a>);