Plugins
Updating Plugins
Many plugins on MPL Core Assets and Collections can be updated after they've been added. The updatePlugin function allows you to modify plugin data, such as changing attributes, updating royalties, or modifying freeze states.
Updating Plugins on Assets
Basic Plugin Update Example
Here's how to update a plugin on an MPL Core Asset using the Attributes plugin as an example:
Update Plugin on Asset
import { publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, fetchAsset } from '@metaplex-foundation/mpl-core'
(async () => {
const assetAddress = publicKey('11111111111111111111111111111111')
// Fetch the current asset to see existing plugin data
const asset = await fetchAsset(umi, assetAddress, {
skipDerivePlugins: false,
})
// Update the Attributes plugin with new data
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'Attributes',
attributeList: [
{ key: 'level', value: '5' }, // Updated value
{ key: 'rarity', value: 'legendary' }, // New attribute
{ key: 'power', value: '150' }, // New attribute
],
},
}).sendAndConfirm(umi)
})();
Updating Royalties Plugin
Update Royalties Plugin
import { publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, ruleSet } from '@metaplex-foundation/mpl-core'
(async () => {
const assetAddress = publicKey('11111111111111111111111111111111')
const creator1 = publicKey('22222222222222222222222222222222')
const creator2 = publicKey('33333333333333333333333333333333')
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'Royalties',
basisPoints: 750, // Updated from 500 to 750 (7.5%)
creators: [
{ address: creator1, percentage: 70 }, // Updated distribution
{ address: creator2, percentage: 30 },
],
ruleSet: ruleSet('ProgramAllowList', [
[
publicKey('44444444444444444444444444444444'),
publicKey('55555555555555555555555555555555'),
],
]),
},
}).sendAndConfirm(umi)
})();
Updating State-Based Plugins
Some plugins store simple state that can be toggled, like the Freeze Delegate plugin:
Update Freeze State
import { publicKey } from '@metaplex-foundation/umi'
import { updatePlugin } from '@metaplex-foundation/mpl-core'
(async () => {
const assetAddress = publicKey('11111111111111111111111111111111')
// Freeze the asset
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'FreezeDelegate',
frozen: true, // Set to true to freeze, false to unfreeze
},
}).sendAndConfirm(umi)
// Later, unfreeze the asset
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'FreezeDelegate',
frozen: false, // Unfreeze the asset
},
}).sendAndConfirm(umi)
})();
Updating Plugins on Collections
Collection plugins work similarly to asset plugins, but use the updateCollectionPlugin function:
Update Plugin on Collection
import { publicKey } from '@metaplex-foundation/umi'
import { updateCollectionPlugin, ruleSet } from '@metaplex-foundation/mpl-core'
(async () => {
const collectionAddress = publicKey('11111111111111111111111111111111')
const creator1 = publicKey('22222222222222222222222222222222')
const creator2 = publicKey('33333333333333333333333333333333')
// Update collection-wide royalties
await updateCollectionPlugin(umi, {
collection: collectionAddress,
plugin: {
type: 'Royalties',
basisPoints: 600, // 6% royalty for the collection
creators: [
{ address: creator1, percentage: 80 },
{ address: creator2, percentage: 20 },
],
ruleSet: ruleSet('None'),
},
}).sendAndConfirm(umi)
})();
Working with Complex Plugin Data
Managing Lists in Plugins
Some plugins like Autograph and Verified Creators maintain lists of data. When updating these plugins, you need to pass the complete list you want to maintain:
Update List-Based Plugin
import { publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, fetchAsset } from '@metaplex-foundation/mpl-core'
(async () => {
const assetAddress = publicKey('11111111111111111111111111111111')
// First, fetch the current asset to see existing autographs
const asset = await fetchAsset(umi, assetAddress, {
skipDerivePlugins: false,
})
// Add a new autograph while keeping existing ones
const newAutograph = {
address: umi.identity.publicKey,
message: "Amazing NFT! Signed by collector."
}
// Include all existing autographs plus the new one
const updatedAutographs = [...asset.autograph.signatures, newAutograph]
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'Autograph',
signatures: updatedAutographs, // Complete list including new addition
},
authority: umi.identity,
}).sendAndConfirm(umi)
})();
Removing Items from Lists
Remove Items from Plugin Lists
import { publicKey } from '@metaplex-foundation/umi'
import { updatePlugin, fetchAsset } from '@metaplex-foundation/mpl-core'
(async () => {
const assetAddress = publicKey('11111111111111111111111111111111')
const autographToRemove = publicKey('44444444444444444444444444444444')
// Fetch current asset data
const asset = await fetchAsset(umi, assetAddress, {
skipDerivePlugins: false,
})
// Filter out the autograph we want to remove
const filteredAutographs = asset.autograph.signatures.filter(
(autograph) => autograph.address !== autographToRemove
)
await updatePlugin(umi, {
asset: assetAddress,
plugin: {
type: 'Autograph',
signatures: filteredAutographs, // List without the removed item
},
authority: umi.identity,
}).sendAndConfirm(umi)
})();
Authority Requirements
Different plugins require different authorities to update:
- Authority Managed Plugins (Royalties, Attributes, Update Delegate): Require the authority of the asset or collection
- Owner Managed Plugins (Autograph, Freeze Delegate): Require the owner of the asset or the plugin's specific authority
- Verified Creators Plugin: Requires the update authority to add/remove creators, but individual creators can verify themselves
Error Handling
Common errors when updating plugins:
- Authority mismatch: Ensure you're signing with the correct authority for the plugin type
- Plugin not found: The plugin must exist on the asset/collection before it can be updated
- Invalid data: Plugin data must conform to the expected structure and constraints
- Collection mismatch: If the asset is part of a collection, you may need to include the collection in the update
Best Practices
- Fetch before updating: Always fetch the current asset/collection state to see existing plugin data
- Preserve existing data: When updating list-based plugins, include existing data you want to keep
- Use proper authorities: Ensure you're using the correct signing authority for each plugin type
- Batch updates: If updating multiple plugins, consider batching operations for efficiency
- Validate data: Ensure your update data meets the plugin's requirements (e.g., creator percentages sum to 100%)
Next Steps
- Learn about specific plugin updates in individual plugin documentation
- Explore Plugin Overview for all available plugins
- Check out Adding Plugins and Removing Plugins
- Visit the MPL Core TypeDoc for detailed API documentation.