use anchor_lang::prelude::*;
use anchor_lang::solana_program;
use anchor_spl::token;
use std::convert::TryFrom;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod named_spl_mints {
use super::*;
pub fn create_new_mint(
ctx: Context<CreateNewMint>,
mint_bump: u8,
_attribution_bump: u8,
name: String,
decimals: u8,
mint_authority: Pubkey,
freeze_authority: Option<Pubkey>,
) -> ProgramResult {
let mint_span: u64 = 82;
let lamports = Rent::get()?.minimum_balance(usize::try_from(mint_span).unwrap());
solana_program::program::invoke_signed(
&solana_program::system_instruction::create_account(
&ctx.accounts.creator.key(),
&ctx.accounts.mint.key(),
lamports,
mint_span,
&ctx.accounts.token_program.key(),
),
&[
ctx.accounts.creator.to_account_info(),
ctx.accounts.mint.to_account_info(),
ctx.accounts.system_program.to_account_info(),
],
&[&[name.clone().to_seed_format().as_bytes(), &[mint_bump]]],
)?;
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_accounts = anchor_spl::token::InitializeMint {
mint: ctx.accounts.mint.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
};
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
if let Some(freeze_authority) = freeze_authority {
anchor_spl::token::initialize_mint(
cpi_ctx,
decimals,
&mint_authority,
Some(&freeze_authority),
)?;
} else {
anchor_spl::token::initialize_mint(cpi_ctx, decimals, &mint_authority, None)?;
};
ctx.accounts.attribution.mint = ctx.accounts.mint.key();
ctx.accounts.attribution.name = name;
Ok(())
}
}
#[derive(Accounts)]
#[instruction(mint_bump: u8, attribution_bump: u8, name: String)]
pub struct CreateNewMint<'info> {
#[account(mut)]
creator: Signer<'info>,
#[account(
mut,
seeds = [name.clone().to_seed_format().as_bytes()],
bump = mint_bump
)]
mint: UncheckedAccount<'info>,
#[account(
init,
seeds = [mint.key().as_ref()],
bump = attribution_bump,
space = 92,
payer = creator
)]
attribution: Account<'info, Attribution>,
rent: Sysvar<'info, Rent>,
system_program: Program<'info, System>,
token_program: Program<'info, token::Token>,
}
#[account]
#[derive(Default)]
pub struct Attribution {
pub mint: Pubkey,
pub name: String,
}
trait SeedFormat {
fn to_seed_format(self) -> String;
}
impl SeedFormat for String {
fn to_seed_format(mut self) -> String {
self.make_ascii_lowercase();
self.retain(|c| !c.is_whitespace());
self
}
}