typhoon-token 0.3.0

SPL token program integration and account types
Documentation
use {
    crate::Mint,
    pinocchio::{cpi::Signer as CpiSigner, sysvars::rent::Rent, AccountView, Address},
    pinocchio_token::{instructions::InitializeMint2, ID as TOKEN_PROGRAM_ID},
    typhoon_accounts::{
        Account, FromAccountInfo, Mut, ReadableAccount, Signer, SignerCheck, SystemAccount,
        UncheckedAccount, WritableAccount,
    },
    typhoon_errors::Error,
    typhoon_utility::create_account_with_minimum_balance_signed,
};

pub trait SplCreateMint<'a, T: ReadableAccount>
where
    Self: Sized + Into<&'a AccountView>,
    T: ReadableAccount + FromAccountInfo<'a>,
{
    #[inline]
    fn create_mint(
        self,
        rent: &Rent,
        payer: &impl WritableAccount,
        mint_authority: &Address,
        decimals: u8,
        freeze_authority: Option<&Address>,
        seeds: Option<&[CpiSigner]>,
    ) -> Result<Mut<T>, Error> {
        let info = self.into();
        create_account_with_minimum_balance_signed(
            info,
            Mint::LEN,
            &TOKEN_PROGRAM_ID,
            payer.as_ref(),
            rent,
            seeds.unwrap_or_default(),
        )?;

        InitializeMint2 {
            mint: info,
            mint_authority,
            decimals,
            freeze_authority,
        }
        .invoke()?;

        Mut::try_from_info(info)
    }
}

macro_rules! impl_trait {
    ($origin: ty) => {
        impl<'a> SplCreateMint<'a, Account<'a, Mint>> for $origin {}
        impl<'a, C> SplCreateMint<'a, Signer<'a, Account<'a, Mint>, C>> for $origin where
            C: SignerCheck
        {
        }
    };
}

impl_trait!(&'a AccountView);
impl_trait!(SystemAccount<'a>);
impl_trait!(UncheckedAccount<'a>);