Skip to content

Commit

Permalink
Master edition collection plugin (#81)
Browse files Browse the repository at this point in the history
- allow specifying max supply, name and uri on the collection
- the fields are informational only and can be freely updated by the creator
  • Loading branch information
nhanphan authored Apr 25, 2024
1 parent 1686736 commit 8216772
Show file tree
Hide file tree
Showing 22 changed files with 358 additions and 16 deletions.
1 change: 1 addition & 0 deletions clients/js/src/generated/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export * from './freezeDelegate';
export * from './hashablePluginSchema';
export * from './hashedAssetSchema';
export * from './key';
export * from './masterEdition';
export * from './permanentBurnDelegate';
export * from './permanentFreezeDelegate';
export * from './permanentTransferDelegate';
Expand Down
42 changes: 42 additions & 0 deletions clients/js/src/generated/types/masterEdition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* This code was AUTOGENERATED using the kinobi library.
* Please DO NOT EDIT THIS FILE, instead use visitors
* to add features, then rerun kinobi to update it.
*
* @see https://github.com/metaplex-foundation/kinobi
*/

import { Option, OptionOrNullable } from '@metaplex-foundation/umi';
import {
Serializer,
option,
string,
struct,
u32,
} from '@metaplex-foundation/umi/serializers';

export type MasterEdition = {
maxSupply: Option<number>;
name: Option<string>;
uri: Option<string>;
};

export type MasterEditionArgs = {
maxSupply: OptionOrNullable<number>;
name: OptionOrNullable<string>;
uri: OptionOrNullable<string>;
};

export function getMasterEditionSerializer(): Serializer<
MasterEditionArgs,
MasterEdition
> {
return struct<MasterEdition>(
[
['maxSupply', option(u32())],
['name', option(string())],
['uri', option(string())],
],
{ description: 'MasterEdition' }
) as Serializer<MasterEditionArgs, MasterEdition>;
}
19 changes: 17 additions & 2 deletions clients/js/src/generated/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {
EditionArgs,
FreezeDelegate,
FreezeDelegateArgs,
MasterEdition,
MasterEditionArgs,
PermanentBurnDelegate,
PermanentBurnDelegateArgs,
PermanentFreezeDelegate,
Expand All @@ -39,6 +41,7 @@ import {
getBurnDelegateSerializer,
getEditionSerializer,
getFreezeDelegateSerializer,
getMasterEditionSerializer,
getPermanentBurnDelegateSerializer,
getPermanentFreezeDelegateSerializer,
getPermanentTransferDelegateSerializer,
Expand All @@ -57,7 +60,8 @@ export type Plugin =
| { __kind: 'Attributes'; fields: [Attributes] }
| { __kind: 'PermanentTransferDelegate'; fields: [PermanentTransferDelegate] }
| { __kind: 'PermanentBurnDelegate'; fields: [PermanentBurnDelegate] }
| { __kind: 'Edition'; fields: [Edition] };
| { __kind: 'Edition'; fields: [Edition] }
| { __kind: 'MasterEdition'; fields: [MasterEdition] };

export type PluginArgs =
| { __kind: 'Royalties'; fields: [RoyaltiesArgs] }
Expand All @@ -72,7 +76,8 @@ export type PluginArgs =
fields: [PermanentTransferDelegateArgs];
}
| { __kind: 'PermanentBurnDelegate'; fields: [PermanentBurnDelegateArgs] }
| { __kind: 'Edition'; fields: [EditionArgs] };
| { __kind: 'Edition'; fields: [EditionArgs] }
| { __kind: 'MasterEdition'; fields: [MasterEditionArgs] };

export function getPluginSerializer(): Serializer<PluginArgs, Plugin> {
return dataEnum<Plugin>(
Expand Down Expand Up @@ -137,6 +142,12 @@ export function getPluginSerializer(): Serializer<PluginArgs, Plugin> {
['fields', tuple([getEditionSerializer()])],
]),
],
[
'MasterEdition',
struct<GetDataEnumKindContent<Plugin, 'MasterEdition'>>([
['fields', tuple([getMasterEditionSerializer()])],
]),
],
],
{ description: 'Plugin' }
) as Serializer<PluginArgs, Plugin>;
Expand Down Expand Up @@ -186,6 +197,10 @@ export function plugin(
kind: 'Edition',
data: GetDataEnumKindContent<PluginArgs, 'Edition'>['fields']
): GetDataEnumKind<PluginArgs, 'Edition'>;
export function plugin(
kind: 'MasterEdition',
data: GetDataEnumKindContent<PluginArgs, 'MasterEdition'>['fields']
): GetDataEnumKind<PluginArgs, 'MasterEdition'>;
export function plugin<K extends PluginArgs['__kind']>(
kind: K,
data?: any
Expand Down
1 change: 1 addition & 0 deletions clients/js/src/generated/types/pluginType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export enum PluginType {
PermanentTransferDelegate,
PermanentBurnDelegate,
Edition,
MasterEdition,
}

export type PluginTypeArgs = PluginType;
Expand Down
5 changes: 5 additions & 0 deletions clients/js/src/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
PluginType,
UpdateDelegateArgs,
EditionArgs,
MasterEditionArgs,
} from './generated';
import { BasePluginAuthority, PluginsList } from './types';
import { mapPluginAuthority } from './authority';
Expand Down Expand Up @@ -69,6 +70,10 @@ export type CreatePluginArgs =
| {
type: 'Edition';
data: EditionArgs;
}
| {
type: 'MasterEdition';
data: MasterEditionArgs;
};

export function createPlugin(args: CreatePluginArgs): BasePlugin {
Expand Down
3 changes: 3 additions & 0 deletions clients/js/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
UpdateAuthority,
PermanentBurnDelegate,
Edition,
MasterEdition,
} from './generated';

export type BasePluginAuthority = {
Expand Down Expand Up @@ -44,6 +45,7 @@ export type PermanentTransferDelegatePlugin = BasePlugin &
PermanentTransferDelegate;
export type PermanentBurnDelegatePlugin = BasePlugin & PermanentBurnDelegate;
export type EditionPlugin = BasePlugin & Edition;
export type MasterEditionPlugin = BasePlugin & MasterEdition;

export type PluginsList = {
royalties?: RoyaltiesPlugin;
Expand All @@ -56,4 +58,5 @@ export type PluginsList = {
permanentTransferDelegate?: PermanentTransferDelegatePlugin;
permanentBurnDelegate?: PermanentBurnDelegatePlugin;
edition?: EditionPlugin;
masterEdition?: MasterEditionPlugin;
};
155 changes: 155 additions & 0 deletions clients/js/test/plugins/collection/masterEdition.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import test from 'ava';
import { none, some } from '@metaplex-foundation/umi';
import {
pluginAuthorityPair,
updatePluginAuthority,
createPlugin,
addPluginV1,
addCollectionPluginV1,
} from '../../../src';
import {
DEFAULT_COLLECTION,
assertCollection,
createAsset,
createCollection,
createUmi,
} from '../../_setup';

test('it can add masterEdition to collection', async (t) => {
const umi = await createUmi();
const collection = await createCollection(umi);

await addCollectionPluginV1(umi, {
collection: collection.publicKey,
plugin: createPlugin({
type: 'MasterEdition',
data: {
maxSupply: 100,
name: 'name',
uri: 'uri',
},
}),
}).sendAndConfirm(umi);

await assertCollection(t, umi, {
...DEFAULT_COLLECTION,
collection: collection.publicKey,
updateAuthority: umi.identity.publicKey,
masterEdition: {
authority: {
type: 'UpdateAuthority',
},
maxSupply: some(100),
name: some('name'),
uri: some('uri'),
},
});
});

test('it can create collection with masterEdition', async (t) => {
const umi = await createUmi();

const collection = await createCollection(umi, {
plugins: [
pluginAuthorityPair({
type: 'MasterEdition',
data: {
maxSupply: 100,
name: 'name',
uri: 'uri',
},
authority: updatePluginAuthority(),
}),
],
});

await assertCollection(t, umi, {
...DEFAULT_COLLECTION,
collection: collection.publicKey,
updateAuthority: umi.identity.publicKey,
masterEdition: {
authority: {
type: 'UpdateAuthority',
},
maxSupply: some(100),
name: some('name'),
uri: some('uri'),
},
});
});

test('it can create master edition with default values', async (t) => {
const umi = await createUmi();

const collection = await createCollection(umi, {
plugins: [
pluginAuthorityPair({
type: 'MasterEdition',
data: {
maxSupply: null,
name: null,
uri: null,
},
authority: updatePluginAuthority(),
}),
],
});

await assertCollection(t, umi, {
...DEFAULT_COLLECTION,
collection: collection.publicKey,
updateAuthority: umi.identity.publicKey,
masterEdition: {
authority: {
type: 'UpdateAuthority',
},
maxSupply: none(),
name: none(),
uri: none(),
},
});
});

test('it cannot add masterEdition to asset', async (t) => {
const umi = await createUmi();

const asset = await createAsset(umi);

const result = addPluginV1(umi, {
asset: asset.publicKey,
plugin: createPlugin({
type: 'MasterEdition',
data: {
maxSupply: 100,
name: 'name',
uri: 'uri',
},
}),
}).sendAndConfirm(umi);

await t.throwsAsync(result, {
name: 'InvalidPlugin',
});
});

test('it cannot create asset with masterEdition', async (t) => {
const umi = await createUmi();

const result = createAsset(umi, {
plugins: [
pluginAuthorityPair({
type: 'MasterEdition',
data: {
maxSupply: 100,
name: 'name',
uri: 'uri',
},
authority: updatePluginAuthority(),
}),
],
});

await t.throwsAsync(result, {
name: 'InvalidPlugin',
});
});
17 changes: 17 additions & 0 deletions clients/rust/src/generated/types/master_edition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//! This code was AUTOGENERATED using the kinobi library.
//! Please DO NOT EDIT THIS FILE, instead use visitors
//! to add features, then rerun kinobi to update it.
//!
//! [https://github.com/metaplex-foundation/kinobi]
//!
use borsh::BorshDeserialize;
use borsh::BorshSerialize;

#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MasterEdition {
pub max_supply: Option<u32>,
pub name: Option<String>,
pub uri: Option<String>,
}
2 changes: 2 additions & 0 deletions clients/rust/src/generated/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(crate) mod r#freeze_delegate;
pub(crate) mod r#hashable_plugin_schema;
pub(crate) mod r#hashed_asset_schema;
pub(crate) mod r#key;
pub(crate) mod r#master_edition;
pub(crate) mod r#permanent_burn_delegate;
pub(crate) mod r#permanent_freeze_delegate;
pub(crate) mod r#permanent_transfer_delegate;
Expand Down Expand Up @@ -45,6 +46,7 @@ pub use self::r#freeze_delegate::*;
pub use self::r#hashable_plugin_schema::*;
pub use self::r#hashed_asset_schema::*;
pub use self::r#key::*;
pub use self::r#master_edition::*;
pub use self::r#permanent_burn_delegate::*;
pub use self::r#permanent_freeze_delegate::*;
pub use self::r#permanent_transfer_delegate::*;
Expand Down
2 changes: 2 additions & 0 deletions clients/rust/src/generated/types/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::generated::types::Attributes;
use crate::generated::types::BurnDelegate;
use crate::generated::types::Edition;
use crate::generated::types::FreezeDelegate;
use crate::generated::types::MasterEdition;
use crate::generated::types::PermanentBurnDelegate;
use crate::generated::types::PermanentFreezeDelegate;
use crate::generated::types::PermanentTransferDelegate;
Expand All @@ -31,4 +32,5 @@ pub enum Plugin {
PermanentTransferDelegate(PermanentTransferDelegate),
PermanentBurnDelegate(PermanentBurnDelegate),
Edition(Edition),
MasterEdition(MasterEdition),
}
1 change: 1 addition & 0 deletions clients/rust/src/generated/types/plugin_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ pub enum PluginType {
PermanentTransferDelegate,
PermanentBurnDelegate,
Edition,
MasterEdition,
}
Loading

0 comments on commit 8216772

Please sign in to comment.