Skip to main content

anchor_spl/token_2022_extensions/
token_metadata.rs

1// Avoiding AccountInfo deprecated msg in anchor context
2#![allow(deprecated)]
3use {
4    anchor_lang::{
5        context::CpiContext,
6        solana_program::{account_info::AccountInfo, pubkey::Pubkey},
7        Accounts, Result,
8    },
9    spl_pod::optional_keys::OptionalNonZeroPubkey,
10    spl_token_metadata_interface::state::Field,
11};
12
13pub fn token_metadata_initialize<'info>(
14    ctx: CpiContext<'_, '_, '_, 'info, TokenMetadataInitialize<'info>>,
15    name: String,
16    symbol: String,
17    uri: String,
18) -> Result<()> {
19    let ix = spl_token_metadata_interface::instruction::initialize(
20        ctx.accounts.program_id.key,
21        ctx.accounts.metadata.key,
22        ctx.accounts.update_authority.key,
23        ctx.accounts.mint.key,
24        ctx.accounts.mint_authority.key,
25        name,
26        symbol,
27        uri,
28    );
29    anchor_lang::solana_program::program::invoke_signed(
30        &ix,
31        &[
32            ctx.accounts.program_id,
33            ctx.accounts.metadata,
34            ctx.accounts.update_authority,
35            ctx.accounts.mint,
36            ctx.accounts.mint_authority,
37        ],
38        ctx.signer_seeds,
39    )
40    .map_err(Into::into)
41}
42
43#[derive(Accounts)]
44pub struct TokenMetadataInitialize<'info> {
45    pub program_id: AccountInfo<'info>,
46    pub metadata: AccountInfo<'info>,
47    pub update_authority: AccountInfo<'info>,
48    pub mint_authority: AccountInfo<'info>,
49    pub mint: AccountInfo<'info>,
50}
51
52pub fn token_metadata_update_authority<'info>(
53    ctx: CpiContext<'_, '_, '_, 'info, TokenMetadataUpdateAuthority<'info>>,
54    new_authority: OptionalNonZeroPubkey,
55) -> Result<()> {
56    let ix = spl_token_metadata_interface::instruction::update_authority(
57        ctx.accounts.program_id.key,
58        ctx.accounts.metadata.key,
59        ctx.accounts.current_authority.key,
60        new_authority,
61    );
62    anchor_lang::solana_program::program::invoke_signed(
63        &ix,
64        &[
65            ctx.accounts.program_id,
66            ctx.accounts.metadata,
67            ctx.accounts.current_authority,
68        ],
69        ctx.signer_seeds,
70    )
71    .map_err(Into::into)
72}
73
74#[derive(Accounts)]
75pub struct TokenMetadataUpdateAuthority<'info> {
76    pub program_id: AccountInfo<'info>,
77    pub metadata: AccountInfo<'info>,
78    pub current_authority: AccountInfo<'info>,
79    pub new_authority: AccountInfo<'info>,
80}
81
82pub fn token_metadata_update_field<'info>(
83    ctx: CpiContext<'_, '_, '_, 'info, TokenMetadataUpdateField<'info>>,
84    field: Field,
85    value: String,
86) -> Result<()> {
87    let ix = spl_token_metadata_interface::instruction::update_field(
88        ctx.accounts.program_id.key,
89        ctx.accounts.metadata.key,
90        ctx.accounts.update_authority.key,
91        field,
92        value,
93    );
94    anchor_lang::solana_program::program::invoke_signed(
95        &ix,
96        &[
97            ctx.accounts.program_id,
98            ctx.accounts.metadata,
99            ctx.accounts.update_authority,
100        ],
101        ctx.signer_seeds,
102    )
103    .map_err(Into::into)
104}
105
106#[derive(Accounts)]
107pub struct TokenMetadataUpdateField<'info> {
108    pub program_id: AccountInfo<'info>,
109    pub metadata: AccountInfo<'info>,
110    pub update_authority: AccountInfo<'info>,
111}