1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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
}
}