Features
Updating Assets
The update authority of an asset can update its Metadata account using the Update instruction as long as the Is Mutable attribute is set to true. The Update instruction requires the Update Authority to sign the transaction and can update the following attributes of the Metadata account:
Updatable Fields
Note that certain delegated authorities can also update the Metadata account of assets as discussed in the "Delegated Authorities" page.
Below is an explanation of all the individual fields available for update in the UpdateV1 instruction.
The Data Object
The object that defines the Name, Symbol, URI, Seller Fee Basis Points and the array of Creators of the asset. Note that the update authority can only add and/or remove unverified creators from the Creators array. The only exception is if the creator is the update authority, in which case the added or removed creators can be verified.
Data Object
const data = {
name: 'New Name',
symbol: 'New Symbol',
uri: 'https://newuri.com',
sellerFeeBasisPoints: 500,
creators: [],
}
Primary Sale Happened
Primary Sale Happened: A boolean that indicates whether the asset has been sold before.
Primary Sale Happened
primarySaleHappened: true
Is Mutable
A boolean that indicates whether the asset can be updated again. When changing this to false, any future updates will fail.
Is Mutable
isMutable: true
Collection
This attribute enables us to set or clear the collection of the asset. Note that when setting a new collection, the verified boolean must be set to false and verified using another instruction.
Setting A Collection
Setting A Collection
collection: collectionToggle('Set', [
{
key: publicKey('11111111111111111111111111111111'),
verified: false,
},
])
Clearing a Collection
Clearing a Collection
collection: collectionToggle("Clear"),
New Update Authority
A new update authority can be assigned to an Asset by passing in the newUpdateAuthority field.
New Update Authority
newUpdateAuthority: publicKey('1111111111111111111111111111111')
Programable RuleSets
This attribute enables us to set or clear the rule set of the asset. This is only relevant for Programmable Non-Fungibles.
Programable RuleSets
ruleSet: publicKey('1111111111111111111111111111111')
Here is how you can use our SDKs to update an asset on Token Metadata.
Update As Update Authority
NFT Asset
This example shows you how to update an NFT Asset as the update Authority of the Asset.
1import { publicKey, none, some } from '@metaplex-foundation/umi';
2import { updateV1 } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi is set up with mplTokenMetadata plugin
5// See getting-started for full setup
6
7const mintAddress = publicKey('mintAddress...');
8
9// Update the NFT metadata
10await updateV1(umi, {
11 mint: mintAddress,
12 authority: umi.identity,
13 // Only specify fields you want to update
14 data: some({
15 name: 'Updated NFT Name',
16 symbol: '', // Keep existing
17 uri: '', // Keep existing
18 sellerFeeBasisPoints: 0, // Keep existing
19 creators: none(),
20 }),
21}).sendAndConfirm(umi);
22
23console.log('NFT metadata updated');
1import {
2 getUpdateV1InstructionAsync,
3 TokenStandard,
4} from '@metaplex-foundation/mpl-token-metadata-kit';
5
6// Assuming rpc, rpcSubscriptions, sendAndConfirm, and authority are set up
7// See getting-started for full setup
8
9const mintAddress = 'mintAddress...'; // The NFT mint address
10
11// Update the NFT metadata
12const updateIx = await getUpdateV1InstructionAsync({
13 mint: mintAddress,
14 authority,
15 payer: authority,
16 // Specify fields to update (creators must be explicitly set, use null to keep existing)
17 data: {
18 name: 'Updated NFT Name',
19 symbol: 'UNFT',
20 uri: 'https://example.com/updated-nft.json',
21 sellerFeeBasisPoints: 550,
22 creators: null, // Keep existing creators
23 },
24});
25
26await sendAndConfirm({
27 instructions: [updateIx],
28 payer: authority,
29});
30
31console.log('NFT metadata updated');
1use anchor_lang::prelude::*;
2use mpl_token_metadata::{
3 accounts::Metadata,
4 instructions::UpdateAsUpdateAuthorityV2CpiBuilder, types::Data,
5};
6
7#[derive(Accounts)]
8pub struct NftUpdateMpl<'info> {
9 pub mint: AccountInfo<'info>,
10 /// CHECK: Handled by CPI
11 #[account(mut)]
12 pub metadata: AccountInfo<'info>,
13 #[account(mut)]
14 pub update_authority: Signer<'info>,
15 /// CHECK: Handled by CPI
16 pub token_metadata_program: AccountInfo<'info>,
17}
18
19pub fn update_nft_mpl_instruction<'info>(
20 ctx: Context<'_, '_, '_, 'info, NftUpdateMpl<'info>>,
21 new_name: Option<String>,
22 new_uri: Option<String>,
23) -> Result<()> {
24 let mint = ctx.accounts.mint.to_account_info();
25 let metadata = ctx.accounts.metadata.to_account_info();
26 let token_metadata_program = ctx.accounts.token_metadata_program.to_account_info();
27
28 // Get the original metadata values
29 let metadata_account = Metadata::try_from(&metadata)?;
30
31 let original_metadata = Data {
32 name: metadata_account.name,
33 symbol: metadata_account.symbol,
34 uri: metadata_account.uri,
35 seller_fee_basis_points: metadata_account.seller_fee_basis_points,
36 creators: metadata_account.creators,
37 };
38
39 let new_metadata = Data {
40 name: new_name.unwrap_or(original_metadata.name),
41 uri: new_uri.unwrap_or(original_metadata.uri),
42 ..original_metadata // Keep the rest of the metadata the same
43 };
44
45 UpdateAsUpdateAuthorityV2CpiBuilder::new(&token_metadata_program)
46 .mint(&mint)
47 .metadata(&metadata)
48 .authority(&ctx.accounts.update_authority)
49 .data(new_metadata)
50 // Add remaining data fields/accounts to be adjusted to the CPI if needed
51 // https://docs.rs/mpl-token-metadata/latest/mpl_token_metadata/instructions/struct.UpdateAsUpdateAuthorityV2CpiBuilder.html
52 .invoke()?;
53
54 Ok(())
55}
pNFT Asset
This example shows you how to update a Programable NFT (pNFT) Asset as the update Authority of the Asset.
pNFTs may require additional accounts to be passed in for the instruction to work. These include: tokenAccount, tokenRecord, authorizationRules, and authorizationRulesProgram.
1import { publicKey, none, some } from '@metaplex-foundation/umi';
2import { updateV1 } from '@metaplex-foundation/mpl-token-metadata';
3
4// Assuming umi is set up with mplTokenMetadata plugin
5
6const mintAddress = publicKey('mintAddress...');
7
8// Update the Programmable NFT metadata
9// Note: pNFTs may have rule sets that restrict updates
10await updateV1(umi, {
11 mint: mintAddress,
12 authority: umi.identity,
13 data: some({
14 name: 'Updated pNFT Name',
15 symbol: '',
16 uri: '',
17 sellerFeeBasisPoints: 0,
18 creators: none(),
19 }),
20}).sendAndConfirm(umi);
21
22console.log('pNFT metadata updated');
1import {
2 getUpdateV1InstructionAsync,
3 TokenStandard,
4} from '@metaplex-foundation/mpl-token-metadata-kit';
5
6// Assuming rpc, rpcSubscriptions, sendAndConfirm, and authority are set up
7
8const mintAddress = 'mintAddress...'; // The pNFT mint address
9
10// Update the Programmable NFT metadata
11// Note: pNFTs may have rule sets that restrict updates
12const updateIx = await getUpdateV1InstructionAsync({
13 mint: mintAddress,
14 authority,
15 payer: authority,
16 // Specify fields to update (creators must be explicitly set, use null to keep existing)
17 data: {
18 name: 'Updated pNFT Name',
19 symbol: 'UPNFT',
20 uri: 'https://example.com/updated-pnft.json',
21 sellerFeeBasisPoints: 550,
22 creators: null, // Keep existing creators
23 },
24});
25
26await sendAndConfirm({
27 instructions: [updateIx],
28 payer: authority,
29});
30
31console.log('pNFT metadata updated');
1use anchor_lang::prelude::*;
2use mpl_token_metadata::{
3 accounts::Metadata,
4 instructions::UpdateAsUpdateAuthorityV2CpiBuilder, types::Data,
5};
6
7#[derive(Accounts)]
8pub struct NftUpdateMpl<'info> {
9 pub mint: AccountInfo<'info>,
10 /// CHECK: Handled by CPI
11 #[account(mut)]
12 pub metadata: AccountInfo<'info>,
13 #[account(mut)]
14 pub update_authority: Signer<'info>,
15 /// CHECK: Handled by CPI
16 pub token_metadata_program: AccountInfo<'info>,
17 // Add additional accounts below if needed
18}
19
20pub fn update_nft_mpl_instruction<'info>(
21 ctx: Context<'_, '_, '_, 'info, NftUpdateMpl<'info>>,
22 new_name: Option<String>,
23 new_uri: Option<String>,
24) -> Result<()> {
25 let mint = ctx.accounts.mint.to_account_info();
26 let metadata = ctx.accounts.metadata.to_account_info();
27 let token_metadata_program = ctx.accounts.token_metadata_program.to_account_info();
28
29 // Get the original metadata values
30 let metadata_account = Metadata::try_from(&metadata)?;
31
32 let original_metadata = Data {
33 name: metadata_account.name,
34 symbol: metadata_account.symbol,
35 uri: metadata_account.uri,
36 seller_fee_basis_points: metadata_account.seller_fee_basis_points,
37 creators: metadata_account.creators,
38 };
39
40 let new_metadata = Data {
41 name: new_name.unwrap_or(original_metadata.name),
42 uri: new_uri.unwrap_or(original_metadata.uri),
43 ..original_metadata // Keep the rest of the metadata the same
44 };
45
46 UpdateAsUpdateAuthorityV2CpiBuilder::new(&token_metadata_program)
47 .mint(&mint)
48 .metadata(&metadata)
49 .authority(&ctx.accounts.update_authority)
50 .data(new_metadata)
51
52 // Add remaining data fields to be adjusted to the CPI if needed
53 // https://docs.rs/mpl-token-metadata/latest/mpl_token_metadata/instructions/struct.UpdateAsUpdateAuthorityV2CpiBuilder.html
54 //
55 // .authorization_rules(authorization_rules)
56 // .authorization_rules_program(authorization_rules_program)
57 // .token_record(token_record)
58 .invoke()?;
59
60 Ok(())
61}
