From 4040e7e4550dc2e28ef534f462c9d971f2222d47 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 14 Feb 2024 22:06:12 -0700 Subject: [PATCH] Renaming to plugins and minor tweaks. --- clients/js/src/generated/accounts/asset.ts | 14 ++-- .../js/src/generated/accounts/hashedAsset.ts | 12 +-- clients/js/src/generated/types/assetHeader.ts | 6 +- clients/js/src/generated/types/authority.ts | 77 +++++++++++++++++++ clients/js/src/generated/types/index.ts | 4 +- clients/js/src/generated/types/key.ts | 26 +++++++ .../types/{interface.ts => plugin.ts} | 13 ++-- clients/js/test/create.test.ts | 17 ++-- clients/rust/src/generated/accounts/asset.rs | 4 +- .../src/generated/accounts/hashed_asset.rs | 4 +- .../rust/src/generated/types/asset_header.rs | 2 +- clients/rust/src/generated/types/authority.rs | 27 +++++++ clients/rust/src/generated/types/key.rs | 19 +++++ clients/rust/src/generated/types/mod.rs | 8 +- .../types/{interface.rs => plugin.rs} | 2 +- configs/kinobi.cjs | 4 +- idls/mpl_asset_program.json | 66 ++++++++++++++-- programs/mpl-asset/src/interfaces/mod.rs | 56 -------------- programs/mpl-asset/src/lib.rs | 2 +- .../src/{interfaces => plugins}/asset.rs | 15 +++- programs/mpl-asset/src/plugins/collection.rs | 16 ++++ programs/mpl-asset/src/plugins/mod.rs | 67 ++++++++++++++++ .../src/{interfaces => plugins}/royalties.rs | 0 programs/mpl-asset/src/processor/create.rs | 6 +- programs/mpl-asset/src/state/mod.rs | 12 ++- 25 files changed, 371 insertions(+), 108 deletions(-) create mode 100644 clients/js/src/generated/types/authority.ts create mode 100644 clients/js/src/generated/types/key.ts rename clients/js/src/generated/types/{interface.ts => plugin.ts} (61%) create mode 100644 clients/rust/src/generated/types/authority.rs create mode 100644 clients/rust/src/generated/types/key.rs rename clients/rust/src/generated/types/{interface.rs => plugin.rs} (96%) delete mode 100644 programs/mpl-asset/src/interfaces/mod.rs rename programs/mpl-asset/src/{interfaces => plugins}/asset.rs (73%) create mode 100644 programs/mpl-asset/src/plugins/collection.rs create mode 100644 programs/mpl-asset/src/plugins/mod.rs rename programs/mpl-asset/src/{interfaces => plugins}/royalties.rs (100%) diff --git a/clients/js/src/generated/accounts/asset.ts b/clients/js/src/generated/accounts/asset.ts index 285fd7f9..fbad7012 100644 --- a/clients/js/src/generated/accounts/asset.ts +++ b/clients/js/src/generated/accounts/asset.ts @@ -26,12 +26,12 @@ import { string, struct, } from '@metaplex-foundation/umi/serializers'; -import { Interface, InterfaceArgs, getInterfaceSerializer } from '../types'; +import { Key, KeyArgs, getKeySerializer } from '../types'; export type Asset = Account; export type AssetAccountData = { - interface: Interface; + key: Key; updateAuthority: PublicKey; owner: PublicKey; name: string; @@ -52,7 +52,7 @@ export function getAssetAccountDataSerializer(): Serializer< return mapSerializer( struct( [ - ['interface', getInterfaceSerializer()], + ['key', getKeySerializer()], ['updateAuthority', publicKeySerializer()], ['owner', publicKeySerializer()], ['name', string()], @@ -60,7 +60,7 @@ export function getAssetAccountDataSerializer(): Serializer< ], { description: 'AssetAccountData' } ), - (value) => ({ ...value, interface: Interface.Asset }) + (value) => ({ ...value, key: Key.Asset }) ) as Serializer; } @@ -129,18 +129,18 @@ export function getAssetGpaBuilder(context: Pick) { ); return gpaBuilder(context, programId) .registerFields<{ - interface: InterfaceArgs; + key: KeyArgs; updateAuthority: PublicKey; owner: PublicKey; name: string; uri: string; }>({ - interface: [0, getInterfaceSerializer()], + key: [0, getKeySerializer()], updateAuthority: [1, publicKeySerializer()], owner: [33, publicKeySerializer()], name: [65, string()], uri: [null, string()], }) .deserializeUsing((account) => deserializeAsset(account)) - .whereField('interface', Interface.Asset); + .whereField('key', Key.Asset); } diff --git a/clients/js/src/generated/accounts/hashedAsset.ts b/clients/js/src/generated/accounts/hashedAsset.ts index 669be7fc..c7640c2e 100644 --- a/clients/js/src/generated/accounts/hashedAsset.ts +++ b/clients/js/src/generated/accounts/hashedAsset.ts @@ -28,18 +28,18 @@ import { struct, u64, } from '@metaplex-foundation/umi/serializers'; -import { Interface, InterfaceArgs, getInterfaceSerializer } from '../types'; +import { Key, KeyArgs, getKeySerializer } from '../types'; export type HashedAsset = Account; export type HashedAssetAccountData = { - interface: Interface; + key: Key; hash: Uint8Array; watermarkSlot: Option; }; export type HashedAssetAccountDataArgs = { - interface: InterfaceArgs; + key: KeyArgs; hash: Uint8Array; watermarkSlot: OptionOrNullable; }; @@ -50,7 +50,7 @@ export function getHashedAssetAccountDataSerializer(): Serializer< > { return struct( [ - ['interface', getInterfaceSerializer()], + ['key', getKeySerializer()], ['hash', bytes({ size: 32 })], ['watermarkSlot', option(u64())], ], @@ -125,11 +125,11 @@ export function getHashedAssetGpaBuilder( ); return gpaBuilder(context, programId) .registerFields<{ - interface: InterfaceArgs; + key: KeyArgs; hash: Uint8Array; watermarkSlot: OptionOrNullable; }>({ - interface: [0, getInterfaceSerializer()], + key: [0, getKeySerializer()], hash: [1, bytes({ size: 32 })], watermarkSlot: [33, option(u64())], }) diff --git a/clients/js/src/generated/types/assetHeader.ts b/clients/js/src/generated/types/assetHeader.ts index 32783a57..c8b2f945 100644 --- a/clients/js/src/generated/types/assetHeader.ts +++ b/clients/js/src/generated/types/assetHeader.ts @@ -13,11 +13,11 @@ import { u8, } from '@metaplex-foundation/umi/serializers'; -export type AssetHeader = { version: number; interfaceMapOffset: bigint }; +export type AssetHeader = { version: number; pluginMapOffset: bigint }; export type AssetHeaderArgs = { version: number; - interfaceMapOffset: number | bigint; + pluginMapOffset: number | bigint; }; export function getAssetHeaderSerializer(): Serializer< @@ -27,7 +27,7 @@ export function getAssetHeaderSerializer(): Serializer< return struct( [ ['version', u8()], - ['interfaceMapOffset', u64()], + ['pluginMapOffset', u64()], ], { description: 'AssetHeader' } ) as Serializer; diff --git a/clients/js/src/generated/types/authority.ts b/clients/js/src/generated/types/authority.ts new file mode 100644 index 00000000..249ab4f2 --- /dev/null +++ b/clients/js/src/generated/types/authority.ts @@ -0,0 +1,77 @@ +/** + * 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 { PublicKey } from '@metaplex-foundation/umi'; +import { + GetDataEnumKind, + GetDataEnumKindContent, + Serializer, + dataEnum, + publicKey as publicKeySerializer, + struct, + unit, +} from '@metaplex-foundation/umi/serializers'; +import { Plugin, PluginArgs, getPluginSerializer } from '.'; + +export type Authority = + | { __kind: 'Owner' } + | { __kind: 'Permanent'; address: PublicKey } + | { __kind: 'SameAs'; plugin: Plugin }; + +export type AuthorityArgs = + | { __kind: 'Owner' } + | { __kind: 'Permanent'; address: PublicKey } + | { __kind: 'SameAs'; plugin: PluginArgs }; + +export function getAuthoritySerializer(): Serializer { + return dataEnum( + [ + ['Owner', unit()], + [ + 'Permanent', + struct>([ + ['address', publicKeySerializer()], + ]), + ], + [ + 'SameAs', + struct>([ + ['plugin', getPluginSerializer()], + ]), + ], + ], + { description: 'Authority' } + ) as Serializer; +} + +// Data Enum Helpers. +export function authority( + kind: 'Owner' +): GetDataEnumKind; +export function authority( + kind: 'Permanent', + data: GetDataEnumKindContent +): GetDataEnumKind; +export function authority( + kind: 'SameAs', + data: GetDataEnumKindContent +): GetDataEnumKind; +export function authority( + kind: K, + data?: any +): Extract { + return Array.isArray(data) + ? { __kind: kind, fields: data } + : { __kind: kind, ...(data ?? {}) }; +} +export function isAuthority( + kind: K, + value: Authority +): value is Authority & { __kind: K } { + return value.__kind === kind; +} diff --git a/clients/js/src/generated/types/index.ts b/clients/js/src/generated/types/index.ts index b0cd6663..64c3661d 100644 --- a/clients/js/src/generated/types/index.ts +++ b/clients/js/src/generated/types/index.ts @@ -7,7 +7,9 @@ */ export * from './assetHeader'; +export * from './authority'; export * from './creator'; export * from './dataState'; -export * from './interface'; +export * from './key'; +export * from './plugin'; export * from './royalties'; diff --git a/clients/js/src/generated/types/key.ts b/clients/js/src/generated/types/key.ts new file mode 100644 index 00000000..5ec97358 --- /dev/null +++ b/clients/js/src/generated/types/key.ts @@ -0,0 +1,26 @@ +/** + * 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 { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; + +export enum Key { + Uninitialized, + Asset, + HashedAsset, + Collection, + HashedCollection, +} + +export type KeyArgs = Key; + +export function getKeySerializer(): Serializer { + return scalarEnum(Key, { description: 'Key' }) as Serializer< + KeyArgs, + Key + >; +} diff --git a/clients/js/src/generated/types/interface.ts b/clients/js/src/generated/types/plugin.ts similarity index 61% rename from clients/js/src/generated/types/interface.ts rename to clients/js/src/generated/types/plugin.ts index e264c632..0c84968b 100644 --- a/clients/js/src/generated/types/interface.ts +++ b/clients/js/src/generated/types/plugin.ts @@ -8,7 +8,7 @@ import { Serializer, scalarEnum } from '@metaplex-foundation/umi/serializers'; -export enum Interface { +export enum Plugin { Reserved, Asset, HashedAsset, @@ -19,10 +19,11 @@ export enum Interface { Inscription, } -export type InterfaceArgs = Interface; +export type PluginArgs = Plugin; -export function getInterfaceSerializer(): Serializer { - return scalarEnum(Interface, { - description: 'Interface', - }) as Serializer; +export function getPluginSerializer(): Serializer { + return scalarEnum(Plugin, { description: 'Plugin' }) as Serializer< + PluginArgs, + Plugin + >; } diff --git a/clients/js/test/create.test.ts b/clients/js/test/create.test.ts index c2bbad31..ae159e4b 100644 --- a/clients/js/test/create.test.ts +++ b/clients/js/test/create.test.ts @@ -1,6 +1,6 @@ import { generateSigner, publicKey } from '@metaplex-foundation/umi'; import test from 'ava'; -import { base58 } from '@metaplex-foundation/umi/serializers'; +// import { base58 } from '@metaplex-foundation/umi/serializers'; import { Asset, DataState, create, fetchAsset, fetchHashedAsset, getAssetAccountDataSerializer } from '../src'; import { createUmi } from './_setup'; @@ -20,7 +20,7 @@ test('it can create a new asset in account state', async (t) => { // Then an account was created with the correct data. const asset = await fetchAsset(umi, assetAddress.publicKey); - // console.log(asset); + console.log("Account State:", asset); t.like(asset, { publicKey: assetAddress.publicKey, updateAuthority: umi.identity.publicKey, @@ -54,10 +54,17 @@ test('it can create a new asset in ledger state', async (t) => { const tx = await umi.rpc.getTransaction(txResult.signature); if (tx && tx.meta.innerInstructions) { - console.log(tx.meta.innerInstructions[0].instructions); + // console.log(tx.meta.innerInstructions[0].instructions); const { data } = tx.meta.innerInstructions[0].instructions[0]; - console.log(base58.deserialize(data)); + // console.log(base58.deserialize(data)); const parsed = getAssetAccountDataSerializer().deserialize(data)[0]; - console.log("Parsed data:", parsed); + console.log("Ledger State:", parsed); + t.like(parsed, { + updateAuthority: umi.identity.publicKey, + owner: umi.identity.publicKey, + name: 'Test Bread', + uri: 'https://example.com/bread', + }); } + }); diff --git a/clients/rust/src/generated/accounts/asset.rs b/clients/rust/src/generated/accounts/asset.rs index 84ba00a6..876396ee 100644 --- a/clients/rust/src/generated/accounts/asset.rs +++ b/clients/rust/src/generated/accounts/asset.rs @@ -5,7 +5,7 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::Interface; +use crate::generated::types::Key; use borsh::BorshDeserialize; use borsh::BorshSerialize; use solana_program::pubkey::Pubkey; @@ -13,7 +13,7 @@ use solana_program::pubkey::Pubkey; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Asset { - pub interface: Interface, + pub key: Key, #[cfg_attr( feature = "serde", serde(with = "serde_with::As::") diff --git a/clients/rust/src/generated/accounts/hashed_asset.rs b/clients/rust/src/generated/accounts/hashed_asset.rs index 61ec8fb0..2c609193 100644 --- a/clients/rust/src/generated/accounts/hashed_asset.rs +++ b/clients/rust/src/generated/accounts/hashed_asset.rs @@ -5,14 +5,14 @@ //! [https://github.com/metaplex-foundation/kinobi] //! -use crate::generated::types::Interface; +use crate::generated::types::Key; use borsh::BorshDeserialize; use borsh::BorshSerialize; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct HashedAsset { - pub interface: Interface, + pub key: Key, pub hash: [u8; 32], pub watermark_slot: Option, } diff --git a/clients/rust/src/generated/types/asset_header.rs b/clients/rust/src/generated/types/asset_header.rs index 3b1ea94c..9eab418b 100644 --- a/clients/rust/src/generated/types/asset_header.rs +++ b/clients/rust/src/generated/types/asset_header.rs @@ -12,5 +12,5 @@ use borsh::BorshSerialize; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AssetHeader { pub version: u8, - pub interface_map_offset: u64, + pub plugin_map_offset: u64, } diff --git a/clients/rust/src/generated/types/authority.rs b/clients/rust/src/generated/types/authority.rs new file mode 100644 index 00000000..56fe2936 --- /dev/null +++ b/clients/rust/src/generated/types/authority.rs @@ -0,0 +1,27 @@ +//! 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 crate::generated::types::Plugin; +use borsh::BorshDeserialize; +use borsh::BorshSerialize; +use solana_program::pubkey::Pubkey; + +#[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum Authority { + Owner, + Permanent { + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + address: Pubkey, + }, + SameAs { + plugin: Plugin, + }, +} diff --git a/clients/rust/src/generated/types/key.rs b/clients/rust/src/generated/types/key.rs new file mode 100644 index 00000000..e6f27e58 --- /dev/null +++ b/clients/rust/src/generated/types/key.rs @@ -0,0 +1,19 @@ +//! 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, PartialOrd, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum Key { + Uninitialized, + Asset, + HashedAsset, + Collection, + HashedCollection, +} diff --git a/clients/rust/src/generated/types/mod.rs b/clients/rust/src/generated/types/mod.rs index ff8b0437..a984daf3 100644 --- a/clients/rust/src/generated/types/mod.rs +++ b/clients/rust/src/generated/types/mod.rs @@ -6,13 +6,17 @@ //! pub(crate) mod asset_header; +pub(crate) mod authority; pub(crate) mod creator; pub(crate) mod data_state; -pub(crate) mod interface; +pub(crate) mod key; +pub(crate) mod plugin; pub(crate) mod royalties; pub use self::asset_header::*; +pub use self::authority::*; pub use self::creator::*; pub use self::data_state::*; -pub use self::interface::*; +pub use self::key::*; +pub use self::plugin::*; pub use self::royalties::*; diff --git a/clients/rust/src/generated/types/interface.rs b/clients/rust/src/generated/types/plugin.rs similarity index 96% rename from clients/rust/src/generated/types/interface.rs rename to clients/rust/src/generated/types/plugin.rs index 3cd2d0b1..4fabc30c 100644 --- a/clients/rust/src/generated/types/interface.rs +++ b/clients/rust/src/generated/types/plugin.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; #[derive(BorshSerialize, BorshDeserialize, Clone, Debug, Eq, PartialEq, PartialOrd, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum Interface { +pub enum Plugin { Reserved, Asset, HashedAsset, diff --git a/configs/kinobi.cjs b/configs/kinobi.cjs index 09e0e5b7..452e646d 100755 --- a/configs/kinobi.cjs +++ b/configs/kinobi.cjs @@ -55,10 +55,10 @@ kinobi.update( ); // Set ShankAccount discriminator. -const iface = (name) => ({ field: "interface", value: k.vEnum("Interface", name) }); +const key = (name) => ({ field: "key", value: k.vEnum("Key", name) }); kinobi.update( new k.SetAccountDiscriminatorFromFieldVisitor({ - asset: iface("Asset"), + asset: key("Asset"), // myPdaAccount: key("MyPdaAccount"), }) ); diff --git a/idls/mpl_asset_program.json b/idls/mpl_asset_program.json index 43c8da04..6e2e237c 100644 --- a/idls/mpl_asset_program.json +++ b/idls/mpl_asset_program.json @@ -78,9 +78,9 @@ "kind": "struct", "fields": [ { - "name": "interface", + "name": "key", "type": { - "defined": "Interface" + "defined": "Key" } }, { @@ -108,9 +108,9 @@ "kind": "struct", "fields": [ { - "name": "interface", + "name": "key", "type": { - "defined": "Interface" + "defined": "Key" } }, { @@ -209,14 +209,14 @@ "type": "u8" }, { - "name": "interfaceMapOffset", + "name": "pluginMapOffset", "type": "u64" } ] } }, { - "name": "Interface", + "name": "Plugin", "type": { "kind": "enum", "variants": [ @@ -247,6 +247,29 @@ ] } }, + { + "name": "Key", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Uninitialized" + }, + { + "name": "Asset" + }, + { + "name": "HashedAsset" + }, + { + "name": "Collection" + }, + { + "name": "HashedCollection" + } + ] + } + }, { "name": "DataState", "type": { @@ -260,6 +283,37 @@ } ] } + }, + { + "name": "Authority", + "type": { + "kind": "enum", + "variants": [ + { + "name": "Owner" + }, + { + "name": "Permanent", + "fields": [ + { + "name": "address", + "type": "publicKey" + } + ] + }, + { + "name": "SameAs", + "fields": [ + { + "name": "plugin", + "type": { + "defined": "Plugin" + } + } + ] + } + ] + } } ], "errors": [ diff --git a/programs/mpl-asset/src/interfaces/mod.rs b/programs/mpl-asset/src/interfaces/mod.rs deleted file mode 100644 index f4d6df98..00000000 --- a/programs/mpl-asset/src/interfaces/mod.rs +++ /dev/null @@ -1,56 +0,0 @@ -mod asset; -mod royalties; - -pub use asset::*; -use borsh::{BorshDeserialize, BorshSerialize}; -pub use royalties::*; - -use std::collections::HashMap; - -use solana_program::{program_error::ProgramError, pubkey::Pubkey}; - -macro_rules! interface_instruction { - ($a:expr, $b:expr) => { - (($a as u32) << 16u32) | ($b as u32) - }; -} - -#[repr(u16)] -#[derive(Clone, Copy, Debug, BorshSerialize, BorshDeserialize)] -pub enum Interface { - Reserved, - Asset, - HashedAsset, - Royalties, - MasterEdition, - PrintEdition, - Delegate, - Inscription, -} - -#[repr(u32)] -pub enum NonFungibleInstructions { - Create = interface_instruction!(Interface::Asset, 0), - Transfer = interface_instruction!(Interface::Asset, 1), - Burn = interface_instruction!(Interface::Asset, 2), -} - -pub struct RegistryData { - pub offset: usize, - pub authorities: Vec, -} - -pub struct InterfaceRegistry { - pub registry: HashMap, -} - -pub trait DataStorage { - fn get_required_length(&self); - fn save(&self, data: &mut [u8]); - fn load(&self, data: &[u8]); - fn load_mut(&self, data: &mut [u8]); -} - -pub trait Compressible { - fn hash(&self) -> Result<[u8; 32], ProgramError>; -} diff --git a/programs/mpl-asset/src/lib.rs b/programs/mpl-asset/src/lib.rs index 010c046e..42695316 100644 --- a/programs/mpl-asset/src/lib.rs +++ b/programs/mpl-asset/src/lib.rs @@ -1,7 +1,7 @@ pub mod entrypoint; pub mod error; pub mod instruction; -pub mod interfaces; +pub mod plugins; pub mod processor; pub mod state; diff --git a/programs/mpl-asset/src/interfaces/asset.rs b/programs/mpl-asset/src/plugins/asset.rs similarity index 73% rename from programs/mpl-asset/src/interfaces/asset.rs rename to programs/mpl-asset/src/plugins/asset.rs index 6b1daee5..09d7c050 100644 --- a/programs/mpl-asset/src/interfaces/asset.rs +++ b/programs/mpl-asset/src/plugins/asset.rs @@ -2,11 +2,20 @@ use borsh::{BorshDeserialize, BorshSerialize}; use shank::ShankAccount; use solana_program::{keccak, program_error::ProgramError, pubkey::Pubkey}; -use super::{Compressible, Interface}; +use super::Compressible; + +#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, PartialEq, Eq)] +pub enum Key { + Uninitialized, + Asset, + HashedAsset, + Collection, + HashedCollection, +} #[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)] pub struct Asset { - pub interface: Interface, //2 + pub key: Key, //2 pub update_authority: Pubkey, //32 pub owner: Pubkey, //32 pub name: String, //4 @@ -23,7 +32,7 @@ impl Compressible for Asset { #[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)] pub struct HashedAsset { - pub interface: Interface, //2 + pub key: Key, //2 pub hash: [u8; 32], //32 pub watermark_slot: Option, //1 | 9 } diff --git a/programs/mpl-asset/src/plugins/collection.rs b/programs/mpl-asset/src/plugins/collection.rs new file mode 100644 index 00000000..65738a41 --- /dev/null +++ b/programs/mpl-asset/src/plugins/collection.rs @@ -0,0 +1,16 @@ +use borsh::{BorshDeserialize, BorshSerialize}; +use solana_program::pubkey::Pubkey; + +#[derive(Clone, BorshSerialize, BorshDeserialize, Debug)] +pub struct Collection { + collection_address: Pubkey, +} + +#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)] +pub struct CollectionData { + pub key: Key, //2 + pub update_authority: Pubkey, //32 + pub owner: Pubkey, //32 + pub name: String, //4 + pub uri: String, //4 +} diff --git a/programs/mpl-asset/src/plugins/mod.rs b/programs/mpl-asset/src/plugins/mod.rs new file mode 100644 index 00000000..7f3e3c85 --- /dev/null +++ b/programs/mpl-asset/src/plugins/mod.rs @@ -0,0 +1,67 @@ +mod asset; +mod royalties; + +pub use asset::*; +pub use royalties::*; + +use borsh::{BorshDeserialize, BorshSerialize}; +use solana_program::program_error::ProgramError; +use std::collections::HashMap; + +use crate::state::Authority; + +// macro_rules! plugin_instruction { +// ($a:expr, $b:expr) => { +// (($a as u32) << 16u32) | ($b as u32) +// }; +// } + +#[repr(u16)] +#[derive(Clone, Debug, BorshSerialize, BorshDeserialize, Eq, PartialEq)] +pub enum Plugin { + Reserved, + Asset, + HashedAsset, + Royalties, + MasterEdition, + PrintEdition, + Delegate, + Inscription, +} + +// #[repr(u32)] +// pub enum NonFungibleInstructions { +// Create = plugin_instruction!(Plugin::Metadata, 0), +// Transfer = plugin_instruction!(Plugin::Metadata, 1), +// Burn = plugin_instruction!(Plugin::Metadata, 2), +//} + +pub struct RegistryData { + pub offset: usize, + pub authorities: Vec, +} + +pub struct PluginRegistry { + pub registry: HashMap, +} + +pub trait DataStorage { + fn get_required_length(&self); + fn save(&self, data: &mut [u8]); + fn load(&self, data: &[u8]); + fn load_mut(&self, data: &mut [u8]); +} + +pub trait Compressible { + fn hash(&self) -> Result<[u8; 32], ProgramError>; +} + +// pub trait PluginTrait +// where +// Self: BorshSerialize + BorshDeserialize + Clone + std::fmt::Debug + Sized, +// { +// fn get_plugin() -> Plugin; +// fn get_authority(&self) -> Option { +// None +// } +// } diff --git a/programs/mpl-asset/src/interfaces/royalties.rs b/programs/mpl-asset/src/plugins/royalties.rs similarity index 100% rename from programs/mpl-asset/src/interfaces/royalties.rs rename to programs/mpl-asset/src/plugins/royalties.rs diff --git a/programs/mpl-asset/src/processor/create.rs b/programs/mpl-asset/src/processor/create.rs index 850d8cd9..efcdc1ca 100644 --- a/programs/mpl-asset/src/processor/create.rs +++ b/programs/mpl-asset/src/processor/create.rs @@ -8,7 +8,7 @@ use solana_program::{ use crate::{ error::MplAssetError, instruction::{accounts::CreateAccounts, CreateArgs}, - interfaces::{Asset, Compressible, HashedAsset, Interface}, + plugins::{Asset, Compressible, HashedAsset, Key}, state::DataState, }; @@ -26,7 +26,7 @@ pub(crate) fn create<'a>(accounts: &'a [AccountInfo<'a>], args: CreateArgs) -> P } let new_asset = Asset { - interface: Interface::Asset, + key: Key::Asset, update_authority: *ctx.accounts.authority.unwrap_or(ctx.accounts.payer).key, owner: *ctx .accounts @@ -45,7 +45,7 @@ pub(crate) fn create<'a>(accounts: &'a [AccountInfo<'a>], args: CreateArgs) -> P invoke(&spl_noop::instruction(serialized_data.clone()), &[])?; let hashed_asset = HashedAsset { - interface: Interface::HashedAsset, + key: Key::HashedAsset, hash: new_asset.hash()?, watermark_slot: match args.watermark { true => Some(Clock::get()?.slot), diff --git a/programs/mpl-asset/src/state/mod.rs b/programs/mpl-asset/src/state/mod.rs index 3fb6f6f3..9c92ffbf 100644 --- a/programs/mpl-asset/src/state/mod.rs +++ b/programs/mpl-asset/src/state/mod.rs @@ -3,14 +3,16 @@ use solana_program::account_info::AccountInfo; use solana_program::entrypoint::ProgramResult; use solana_program::msg; use solana_program::program_error::ProgramError; +use solana_program::pubkey::Pubkey; use crate::error::MplAssetError; +use crate::plugins::Plugin; #[repr(C)] #[derive(Clone, BorshSerialize, BorshDeserialize, Debug)] pub struct AssetHeader { pub version: u8, - pub interface_map_offset: usize, + pub plugin_map_offset: usize, } impl AssetHeader { @@ -36,3 +38,11 @@ pub enum DataState { AccountState, LedgerState, } + +#[repr(C)] +#[derive(Clone, BorshSerialize, BorshDeserialize, Debug, Eq, PartialEq)] +pub enum Authority { + Owner, + Permanent { address: Pubkey }, + SameAs { plugin: Plugin }, +}