namespaces/instructions/deprecated/
init_entry.rs

1use {
2    crate::state::*,
3    anchor_lang::{prelude::*, solana_program::program::invoke_signed},
4    anchor_spl::{
5        associated_token::{self, AssociatedToken},
6        token::{self, Token},
7    },
8    cardinal_certificate::{self, cpi::accounts::CreateMintManagerCtx, program::CardinalCertificate},
9    mpl_token_metadata::{instruction::create_metadata_accounts, state::Creator as MCreator},
10    urlencoding::encode,
11};
12
13#[derive(AnchorSerialize, AnchorDeserialize)]
14pub struct InitEntryIx {
15    pub name: String,
16    pub entry_bump: u8,
17    pub mint_manager_bump: u8,
18}
19
20#[derive(Accounts)]
21#[instruction(ix: InitEntryIx)]
22pub struct InitEntry<'info> {
23    namespace: Box<Account<'info, Namespace>>,
24    #[account(
25        init,
26        payer = payer,
27        space = ENTRY_SIZE,
28        seeds = [ENTRY_SEED.as_bytes(), namespace.key().as_ref(), ix.name.as_bytes()],
29        bump,
30    )]
31    entry: Account<'info, Entry>,
32    #[account(mut)]
33    payer: Signer<'info>,
34    /// CHECK: This is not dangerous because we don't read or write from this account
35    #[account(mut)]
36    namespace_certificate_token_account: UncheckedAccount<'info>,
37
38    // cpi accounts
39    /// CHECK: This is not dangerous because we don't read or write from this account
40    #[account(mut)]
41    mint_manager: UncheckedAccount<'info>,
42    /// CHECK: This is not dangerous because we don't read or write from this account
43    #[account(mut)]
44    certificate_mint: UncheckedAccount<'info>,
45    /// CHECK: This is not dangerous because we don't read or write from this account
46    #[account(mut)]
47    certificate_mint_metadata: UncheckedAccount<'info>,
48
49    // programs
50    certificate_program: Program<'info, CardinalCertificate>,
51    /// CHECK: This is not dangerous because we don't read or write from this account
52    token_metadata_program: UncheckedAccount<'info>,
53    token_program: Program<'info, Token>,
54    associated_token: Program<'info, AssociatedToken>,
55    rent: Sysvar<'info, Rent>,
56    system_program: Program<'info, System>,
57}
58
59pub fn handler(ctx: Context<InitEntry>, ix: InitEntryIx) -> Result<()> {
60    let entry = &mut ctx.accounts.entry;
61    entry.namespace = ctx.accounts.namespace.key();
62    entry.name = ix.name.clone();
63    entry.bump = *ctx.bumps.get("entry").unwrap();
64    entry.data = None;
65    entry.mint = ctx.accounts.certificate_mint.key();
66    entry.is_claimed = false;
67
68    let namespace_seeds = &[NAMESPACE_PREFIX.as_bytes(), ctx.accounts.namespace.name.as_bytes(), &[ctx.accounts.namespace.bump]];
69    let namespace_signer = &[&namespace_seeds[..]];
70
71    // initialize certificate mint
72    let cpi_accounts = token::InitializeMint {
73        mint: ctx.accounts.certificate_mint.to_account_info(),
74        rent: ctx.accounts.rent.to_account_info(),
75    };
76    let cpi_program = ctx.accounts.token_program.to_account_info();
77    let cpi_context = CpiContext::new(cpi_program, cpi_accounts);
78    token::initialize_mint(cpi_context, 0, &ctx.accounts.namespace.key(), Some(&ctx.accounts.namespace.key()))?;
79
80    // create metadata
81    invoke_signed(
82        &create_metadata_accounts(
83            *ctx.accounts.token_metadata_program.key,
84            *ctx.accounts.certificate_mint_metadata.key,
85            *ctx.accounts.certificate_mint.key,
86            ctx.accounts.namespace.key(),
87            *ctx.accounts.payer.key,
88            ctx.accounts.namespace.key(),
89            ctx.accounts.namespace.name.clone(),
90            "NAME".to_string(),
91            // generative URL which will inclde image of the name with expiration data
92            "https://nft.cardinal.so/metadata/".to_string() + &ctx.accounts.certificate_mint.key().to_string() + "?name=" + &encode(ctx.accounts.entry.name.as_str()),
93            Some(vec![MCreator {
94                address: ctx.accounts.namespace.key(),
95                verified: true,
96                share: 100,
97            }]),
98            0,
99            true,
100            true,
101        ),
102        &[
103            ctx.accounts.certificate_mint_metadata.to_account_info(),
104            ctx.accounts.certificate_mint.to_account_info(),
105            ctx.accounts.namespace.to_account_info(),
106            ctx.accounts.payer.to_account_info(),
107            ctx.accounts.namespace.to_account_info(),
108            ctx.accounts.system_program.to_account_info(),
109            ctx.accounts.rent.to_account_info(),
110        ],
111        namespace_signer,
112    )?;
113
114    // create associated certificate token account for namespace
115    let cpi_accounts = associated_token::Create {
116        payer: ctx.accounts.payer.to_account_info(),
117        associated_token: ctx.accounts.namespace_certificate_token_account.to_account_info(),
118        authority: ctx.accounts.namespace.to_account_info(),
119        mint: ctx.accounts.certificate_mint.to_account_info(),
120        system_program: ctx.accounts.system_program.to_account_info(),
121        token_program: ctx.accounts.token_program.to_account_info(),
122        rent: ctx.accounts.rent.to_account_info(),
123    };
124    let cpi_program = ctx.accounts.token_program.to_account_info();
125    let cpi_context = CpiContext::new(cpi_program, cpi_accounts);
126    associated_token::create(cpi_context)?;
127
128    // mint single token to namespace token account
129    let cpi_accounts = token::MintTo {
130        mint: ctx.accounts.certificate_mint.to_account_info(),
131        to: ctx.accounts.namespace_certificate_token_account.to_account_info(),
132        authority: ctx.accounts.namespace.to_account_info(),
133    };
134    let cpi_program = ctx.accounts.token_program.to_account_info();
135    let cpi_context = CpiContext::new(cpi_program, cpi_accounts).with_signer(namespace_signer);
136    token::mint_to(cpi_context, 1)?;
137
138    // init certificate mint manager
139    let certificate_program = ctx.accounts.certificate_program.to_account_info();
140    let cpi_accounts = CreateMintManagerCtx {
141        mint_manager: ctx.accounts.mint_manager.to_account_info(),
142        mint: ctx.accounts.certificate_mint.to_account_info(),
143        freeze_authority: ctx.accounts.namespace.to_account_info(),
144        payer: ctx.accounts.payer.to_account_info(),
145        token_program: ctx.accounts.token_program.to_account_info(),
146        system_program: ctx.accounts.system_program.to_account_info(),
147    };
148    let cpi_ctx = CpiContext::new(certificate_program, cpi_accounts).with_signer(namespace_signer);
149    cardinal_certificate::cpi::create_mint_manager(cpi_ctx, ix.mint_manager_bump)?;
150    Ok(())
151}