Token Metadata Descriptor

🚧 This is an experimental contract and has not been formally audited. Please use/modify at your own risk.

Overview

Please see this document for more info: https://broken-bellflower-f99.notion.site/Token-Metadata-Descriptor-6227a069bd1049e78fddc3ce1cbf36f1

Reading the tests in /sdk/test can also provide insight into how the program instructions work.

Example Usage

Initialize with data

``` // imports use tokenmetadatadescriptor::{ cpi::accounts::InitializeWithData, state::Encoding, };

// context

[derive(Accounts)]

pub struct Initialize<'info> { #[account(mut)] pub payer: Signer<'info>,

// assumption: authority is an end-user here, but could be a pda
pub update_authority: Signer<'info>,

#[account(mut)]
pub descriptor: AccountInfo<'info>,

// assumption: nft already exists
pub mint: Account<'info, Mint>,

pub metadata: AccountInfo<'info>,

#[account(address = mpl_token_metadata::id())]
pub token_metadata_program: UncheckedAccount<'info>,

#[account(address = token_metadata_descriptor::id())]
pub token_metadata_descriptor: UncheckedAccount<'info>,

pub system_program: Program<'info, System>,

}

... other code ...

// logic using Initialize in context

let cpiprogram = ctx.accounts.tokenmetadatadescriptor.toaccount_info();

let cpiaccounts = InitializeWithData { payer: ctx.accounts.payer.toaccountinfo(), mint: ctx.accounts.mint.toaccountinfo(), tokenmetadata: ctx.accounts.metadata.toaccountinfo(), authority: ctx.accounts.updateauthority.toaccountinfo(), descriptor: ctx.accounts.descriptor.toaccountinfo(), tokenmetadataprogram: ctx.accounts.tokenmetadataprogram.toaccountinfo(), systemprogram: ctx.accounts.systemprogram.toaccount_info(), };

let data = "hello world".trytovec().unwrap();

tokenmetadatadescriptor::cpi::initializewithdata( CpiContext::new(cpiprogram, cpiaccounts) Encoding::Utf8, bump, data )?; ```

Initialize with buffer

``` // imports use tokenmetadatadescriptor::{ cpi::accounts::InitializeWithBuffer, state::Encoding, };

// context

[derive(Accounts)]

pub struct Initialize<'info> { #[account(mut)] pub payer: Signer<'info>,

// assumption: authority is an end-user here, but could be a pda
pub update_authority: Signer<'info>,

#[account(mut)]
pub descriptor: AccountInfo<'info>,

#[account(mut)]
pub buffer: AccountInfo<'info>,

// assumption: nft already exists
pub mint: Account<'info, Mint>,

pub metadata: AccountInfo<'info>,

#[account(address = mpl_token_metadata::id())]
pub token_metadata_program: UncheckedAccount<'info>,

#[account(address = token_metadata_descriptor::id())]
pub token_metadata_descriptor: UncheckedAccount<'info>,

pub system_program: Program<'info, System>,

}

... other code, like initialize and fill buffer ...

// logic using Initialize in context

let cpiprogram = ctx.accounts.tokenmetadatadescriptor.toaccount_info();

let cpiaccounts = InitializeWithBuffer { payer: ctx.accounts.payer.toaccountinfo(), mint: ctx.accounts.mint.toaccountinfo(), tokenmetadata: ctx.accounts.metadata.toaccountinfo(), authority: ctx.accounts.updateauthority.toaccountinfo(), descriptor: ctx.accounts.descriptor.toaccountinfo(), buffer: ctx.accounts.buffer.toaccountinfo(), tokenmetadataprogram: ctx.accounts.tokenmetadataprogram.toaccountinfo(), systemprogram: ctx.accounts.systemprogram.toaccount_info(), };

tokenmetadatadescriptor::cpi::initializewithbuffer( CpiContext::new(cpiprogram, cpiaccounts) None, // copy entire buffer Encoding::Base64, desc_bump, )?; ```