typhoon_token/traits/
create_account.rs1use {
2 crate::TokenAccount,
3 pinocchio::{cpi::Signer as CpiSigner, sysvars::rent::Rent, AccountView, Address},
4 pinocchio_associated_token_account::instructions::{Create, CreateIdempotent},
5 pinocchio_token::{instructions::InitializeAccount3, ID as TOKEN_PROGRAM_ID},
6 typhoon_accounts::{
7 Account, FromAccountInfo, FromRaw, Mut, ReadableAccount, Signer, SignerCheck,
8 SystemAccount, UncheckedAccount, WritableAccount,
9 },
10 typhoon_errors::Error,
11 typhoon_utility::create_account_with_minimum_balance_signed,
12};
13
14pub trait SplCreateToken<'a, T>
15where
16 Self: Sized + Into<&'a AccountView>,
17 T: ReadableAccount + FromAccountInfo<'a> + FromRaw<'a>,
18{
19 fn create_token_account(
20 self,
21 rent: &Rent,
22 payer: &impl WritableAccount,
23 mint: &impl ReadableAccount,
24 owner: &Address,
25 seeds: Option<&[CpiSigner]>,
26 ) -> Result<Mut<T>, Error> {
27 let info = self.into();
28 create_account_with_minimum_balance_signed(
29 info,
30 TokenAccount::LEN,
31 &TOKEN_PROGRAM_ID,
32 payer.as_ref(),
33 rent,
34 seeds.unwrap_or_default(),
35 )?;
36
37 InitializeAccount3 {
38 account: info,
39 mint: mint.as_ref(),
40 owner,
41 }
42 .invoke()?;
43
44 Ok(Mut::from_raw_info(info))
45 }
46
47 fn create_associated_token_account(
48 self,
49 payer: &impl WritableAccount,
50 mint: &impl ReadableAccount,
51 owner: &impl ReadableAccount,
52 system_program: &impl ReadableAccount,
53 token_program: &impl ReadableAccount,
54 ) -> Result<Mut<T>, Error> {
55 let info = self.into();
56 Create {
57 funding_account: payer.as_ref(),
58 account: info,
59 wallet: owner.as_ref(),
60 mint: mint.as_ref(),
61 system_program: system_program.as_ref(),
62 token_program: token_program.as_ref(),
63 }
64 .invoke()?;
65
66 Ok(Mut::from_raw_info(info))
67 }
68
69 fn create_idempotent_associated_token_account(
70 self,
71 payer: &impl WritableAccount,
72 mint: &impl ReadableAccount,
73 owner: &impl ReadableAccount,
74 system_program: &impl ReadableAccount,
75 token_program: &impl ReadableAccount,
76 ) -> Result<Mut<T>, Error> {
77 let info = self.into();
78 CreateIdempotent {
79 funding_account: payer.as_ref(),
80 account: info,
81 wallet: owner.as_ref(),
82 mint: mint.as_ref(),
83 system_program: system_program.as_ref(),
84 token_program: token_program.as_ref(),
85 }
86 .invoke()?;
87
88 Ok(Mut::from_raw_info(info))
89 }
90}
91
92macro_rules! impl_trait {
93 ($origin: ty) => {
94 impl<'a> SplCreateToken<'a, Account<'a, TokenAccount>> for $origin {}
95 impl<'a, C> SplCreateToken<'a, Signer<'a, Account<'a, TokenAccount>, C>> for $origin where
96 C: SignerCheck
97 {
98 }
99 };
100}
101
102impl_trait!(&'a AccountView);
103impl_trait!(SystemAccount<'a>);
104impl_trait!(UncheckedAccount<'a>);