From 2d967e76a71b14a153ea5bc3613eb55b136fac90 Mon Sep 17 00:00:00 2001 From: Michael Danenberg <56533526+danenbm@users.noreply.github.com> Date: Mon, 29 Jan 2024 20:47:21 -0800 Subject: [PATCH] Add deprecated MasterEditionV1 to clients (#86) --- .../accounts/deprecatedMasterEditionV1.ts | 214 ++++++++++++++++++ clients/js/src/generated/accounts/index.ts | 1 + .../accounts/deprecated_master_edition_v1.rs | 87 +++++++ clients/rust/src/generated/accounts/mod.rs | 2 + clients/rust/src/lib.rs | 4 +- configs/kinobi.cjs | 7 +- 6 files changed, 313 insertions(+), 2 deletions(-) create mode 100644 clients/js/src/generated/accounts/deprecatedMasterEditionV1.ts create mode 100644 clients/rust/src/generated/accounts/deprecated_master_edition_v1.rs diff --git a/clients/js/src/generated/accounts/deprecatedMasterEditionV1.ts b/clients/js/src/generated/accounts/deprecatedMasterEditionV1.ts new file mode 100644 index 00000000..a5ea6081 --- /dev/null +++ b/clients/js/src/generated/accounts/deprecatedMasterEditionV1.ts @@ -0,0 +1,214 @@ +/** + * 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 { + Account, + Context, + Option, + OptionOrNullable, + Pda, + PublicKey, + RpcAccount, + RpcGetAccountOptions, + RpcGetAccountsOptions, + assertAccountExists, + deserializeAccount, + gpaBuilder, + publicKey as toPublicKey, +} from '@metaplex-foundation/umi'; +import { + Serializer, + mapSerializer, + option, + publicKey as publicKeySerializer, + string, + struct, + u64, +} from '@metaplex-foundation/umi/serializers'; +import { Key, KeyArgs, getKeySerializer } from '../types'; + +export type DeprecatedMasterEditionV1 = + Account; + +export type DeprecatedMasterEditionV1AccountData = { + key: Key; + supply: bigint; + maxSupply: Option; + printingMint: PublicKey; + oneTimePrintingAuthorizationMint: PublicKey; +}; + +export type DeprecatedMasterEditionV1AccountDataArgs = { + supply: number | bigint; + maxSupply: OptionOrNullable; + printingMint: PublicKey; + oneTimePrintingAuthorizationMint: PublicKey; +}; + +export function getDeprecatedMasterEditionV1AccountDataSerializer(): Serializer< + DeprecatedMasterEditionV1AccountDataArgs, + DeprecatedMasterEditionV1AccountData +> { + return mapSerializer< + DeprecatedMasterEditionV1AccountDataArgs, + any, + DeprecatedMasterEditionV1AccountData + >( + struct( + [ + ['key', getKeySerializer()], + ['supply', u64()], + ['maxSupply', option(u64())], + ['printingMint', publicKeySerializer()], + ['oneTimePrintingAuthorizationMint', publicKeySerializer()], + ], + { description: 'DeprecatedMasterEditionV1AccountData' } + ), + (value) => ({ ...value, key: Key.MasterEditionV1 }) + ) as Serializer< + DeprecatedMasterEditionV1AccountDataArgs, + DeprecatedMasterEditionV1AccountData + >; +} + +export function deserializeDeprecatedMasterEditionV1( + rawAccount: RpcAccount +): DeprecatedMasterEditionV1 { + return deserializeAccount( + rawAccount, + getDeprecatedMasterEditionV1AccountDataSerializer() + ); +} + +export async function fetchDeprecatedMasterEditionV1( + context: Pick, + publicKey: PublicKey | Pda, + options?: RpcGetAccountOptions +): Promise { + const maybeAccount = await context.rpc.getAccount( + toPublicKey(publicKey, false), + options + ); + assertAccountExists(maybeAccount, 'DeprecatedMasterEditionV1'); + return deserializeDeprecatedMasterEditionV1(maybeAccount); +} + +export async function safeFetchDeprecatedMasterEditionV1( + context: Pick, + publicKey: PublicKey | Pda, + options?: RpcGetAccountOptions +): Promise { + const maybeAccount = await context.rpc.getAccount( + toPublicKey(publicKey, false), + options + ); + return maybeAccount.exists + ? deserializeDeprecatedMasterEditionV1(maybeAccount) + : null; +} + +export async function fetchAllDeprecatedMasterEditionV1( + context: Pick, + publicKeys: Array, + options?: RpcGetAccountsOptions +): Promise { + const maybeAccounts = await context.rpc.getAccounts( + publicKeys.map((key) => toPublicKey(key, false)), + options + ); + return maybeAccounts.map((maybeAccount) => { + assertAccountExists(maybeAccount, 'DeprecatedMasterEditionV1'); + return deserializeDeprecatedMasterEditionV1(maybeAccount); + }); +} + +export async function safeFetchAllDeprecatedMasterEditionV1( + context: Pick, + publicKeys: Array, + options?: RpcGetAccountsOptions +): Promise { + const maybeAccounts = await context.rpc.getAccounts( + publicKeys.map((key) => toPublicKey(key, false)), + options + ); + return maybeAccounts + .filter((maybeAccount) => maybeAccount.exists) + .map((maybeAccount) => + deserializeDeprecatedMasterEditionV1(maybeAccount as RpcAccount) + ); +} + +export function getDeprecatedMasterEditionV1GpaBuilder( + context: Pick +) { + const programId = context.programs.getPublicKey( + 'mplTokenMetadata', + 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' + ); + return gpaBuilder(context, programId) + .registerFields<{ + key: KeyArgs; + supply: number | bigint; + maxSupply: OptionOrNullable; + printingMint: PublicKey; + oneTimePrintingAuthorizationMint: PublicKey; + }>({ + key: [0, getKeySerializer()], + supply: [1, u64()], + maxSupply: [9, option(u64())], + printingMint: [null, publicKeySerializer()], + oneTimePrintingAuthorizationMint: [null, publicKeySerializer()], + }) + .deserializeUsing((account) => + deserializeDeprecatedMasterEditionV1(account) + ) + .whereField('key', Key.MasterEditionV1); +} + +export function findDeprecatedMasterEditionV1Pda( + context: Pick, + seeds: { + /** The address of the mint account */ + mint: PublicKey; + } +): Pda { + const programId = context.programs.getPublicKey( + 'mplTokenMetadata', + 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' + ); + return context.eddsa.findPda(programId, [ + string({ size: 'variable' }).serialize('metadata'), + publicKeySerializer().serialize(programId), + publicKeySerializer().serialize(seeds.mint), + string({ size: 'variable' }).serialize('edition'), + ]); +} + +export async function fetchDeprecatedMasterEditionV1FromSeeds( + context: Pick, + seeds: Parameters[1], + options?: RpcGetAccountOptions +): Promise { + return fetchDeprecatedMasterEditionV1( + context, + findDeprecatedMasterEditionV1Pda(context, seeds), + options + ); +} + +export async function safeFetchDeprecatedMasterEditionV1FromSeeds( + context: Pick, + seeds: Parameters[1], + options?: RpcGetAccountOptions +): Promise { + return safeFetchDeprecatedMasterEditionV1( + context, + findDeprecatedMasterEditionV1Pda(context, seeds), + options + ); +} diff --git a/clients/js/src/generated/accounts/index.ts b/clients/js/src/generated/accounts/index.ts index 87dff227..5f74bb62 100644 --- a/clients/js/src/generated/accounts/index.ts +++ b/clients/js/src/generated/accounts/index.ts @@ -7,6 +7,7 @@ */ export * from './collectionAuthorityRecord'; +export * from './deprecatedMasterEditionV1'; export * from './edition'; export * from './editionMarker'; export * from './editionMarkerV2'; diff --git a/clients/rust/src/generated/accounts/deprecated_master_edition_v1.rs b/clients/rust/src/generated/accounts/deprecated_master_edition_v1.rs new file mode 100644 index 00000000..d65c41b7 --- /dev/null +++ b/clients/rust/src/generated/accounts/deprecated_master_edition_v1.rs @@ -0,0 +1,87 @@ +//! 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::Key; +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 struct DeprecatedMasterEditionV1 { + pub key: Key, + pub supply: u64, + pub max_supply: Option, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub printing_mint: Pubkey, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub one_time_printing_authorization_mint: Pubkey, +} + +impl DeprecatedMasterEditionV1 { + /// Prefix values used to generate a PDA for this account. + /// + /// Values are positional and appear in the following order: + /// + /// 0. `DeprecatedMasterEditionV1::PREFIX.0` + /// 1. `crate::MPL_TOKEN_METADATA_ID` + /// 2. mint (`Pubkey`) + /// 3. `DeprecatedMasterEditionV1::PREFIX.1` + pub const PREFIX: (&'static [u8], &'static [u8]) = + ("metadata".as_bytes(), "edition".as_bytes()); + + pub fn create_pda( + mint: Pubkey, + bump: u8, + ) -> Result { + solana_program::pubkey::Pubkey::create_program_address( + &[ + "metadata".as_bytes(), + crate::MPL_TOKEN_METADATA_ID.as_ref(), + mint.as_ref(), + "edition".as_bytes(), + &[bump], + ], + &crate::MPL_TOKEN_METADATA_ID, + ) + } + + pub fn find_pda(mint: &Pubkey) -> (solana_program::pubkey::Pubkey, u8) { + solana_program::pubkey::Pubkey::find_program_address( + &[ + "metadata".as_bytes(), + crate::MPL_TOKEN_METADATA_ID.as_ref(), + mint.as_ref(), + "edition".as_bytes(), + ], + &crate::MPL_TOKEN_METADATA_ID, + ) + } + + #[inline(always)] + pub fn from_bytes(data: &[u8]) -> Result { + let mut data = data; + Self::deserialize(&mut data) + } +} + +impl<'a> TryFrom<&solana_program::account_info::AccountInfo<'a>> for DeprecatedMasterEditionV1 { + type Error = std::io::Error; + + fn try_from( + account_info: &solana_program::account_info::AccountInfo<'a>, + ) -> Result { + let mut data: &[u8] = &(*account_info.data).borrow(); + Self::deserialize(&mut data) + } +} diff --git a/clients/rust/src/generated/accounts/mod.rs b/clients/rust/src/generated/accounts/mod.rs index b3750e14..0907144c 100644 --- a/clients/rust/src/generated/accounts/mod.rs +++ b/clients/rust/src/generated/accounts/mod.rs @@ -6,6 +6,7 @@ //! pub(crate) mod r#collection_authority_record; +pub(crate) mod r#deprecated_master_edition_v1; pub(crate) mod r#edition; pub(crate) mod r#edition_marker; pub(crate) mod r#edition_marker_v2; @@ -17,6 +18,7 @@ pub(crate) mod r#token_record; pub(crate) mod r#use_authority_record; pub use self::r#collection_authority_record::*; +pub use self::r#deprecated_master_edition_v1::*; pub use self::r#edition::*; pub use self::r#edition_marker::*; pub use self::r#edition_marker_v2::*; diff --git a/clients/rust/src/lib.rs b/clients/rust/src/lib.rs index 30418d9e..608481c9 100644 --- a/clients/rust/src/lib.rs +++ b/clients/rust/src/lib.rs @@ -6,7 +6,7 @@ pub mod utils; pub use generated::programs::MPL_TOKEN_METADATA_ID as ID; pub use generated::*; -/// Maximum number of characters in a meetadata name. +/// Maximum number of characters in a metadata name. pub const MAX_NAME_LENGTH: usize = 32; /// Maximum number of characters in a metadata symbol. @@ -26,3 +26,5 @@ pub const MAX_EDITION_MARKER_SIZE: usize = 32; /// Number of bits used by a edition marker. pub const EDITION_MARKER_BIT_SIZE: u64 = 248; + +impl Copy for types::Key {} diff --git a/configs/kinobi.cjs b/configs/kinobi.cjs index 07b577ae..ef4825a8 100755 --- a/configs/kinobi.cjs +++ b/configs/kinobi.cjs @@ -28,6 +28,11 @@ kinobi.update( size: null, seeds: metadataSeeds, }, + masterEditionV1: { + size: null, + name: "deprecatedMasterEditionV1", + seeds: [...metadataSeeds, k.stringConstantSeed("edition")], + }, masterEditionV2: { size: null, name: "masterEdition", @@ -97,7 +102,6 @@ kinobi.update( // Deprecated nodes. "mplTokenMetadata.ReservationListV1": { delete: true }, "mplTokenMetadata.ReservationListV2": { delete: true }, - "mplTokenMetadata.MasterEditionV1": { delete: true }, }) ); @@ -479,6 +483,7 @@ kinobi.update( TokenOwnedEscrow: key("TokenOwnedEscrow"), TokenRecord: key("TokenRecord"), MetadataDelegate: key("MetadataDelegate"), + DeprecatedMasterEditionV1: key("MasterEditionV1"), }) );