From b637a9f33e382a1f3a1d380b69a234d5d3c6872d Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Thu, 18 Jan 2024 00:30:24 -0500 Subject: [PATCH 1/4] Adding support for setMint IX for backfilling. --- .../generated/accounts/inscriptionMetadata.ts | 9 +- .../js/src/generated/errors/mplInscription.ts | 36 ++ .../js/src/generated/instructions/index.ts | 1 + .../js/src/generated/instructions/setMint.ts | 129 +++++ .../accounts/inscription_metadata.rs | 3 +- .../src/generated/errors/mpl_inscription.rs | 6 + .../rust/src/generated/instructions/mod.rs | 2 + .../src/generated/instructions/set_mint.rs | 443 ++++++++++++++++++ idls/mpl_inscription.json | 68 ++- programs/mpl-inscription/src/error.rs | 4 + .../mpl-inscription/src/instruction/mod.rs | 8 + .../src/processor/initialize_from_mint.rs | 1 + programs/mpl-inscription/src/processor/mod.rs | 6 + .../mpl-inscription/src/processor/set_mint.rs | 97 ++++ programs/mpl-inscription/src/state.rs | 6 +- 15 files changed, 813 insertions(+), 6 deletions(-) create mode 100644 clients/js/src/generated/instructions/setMint.ts create mode 100644 clients/rust/src/generated/instructions/set_mint.rs create mode 100644 programs/mpl-inscription/src/processor/set_mint.rs diff --git a/clients/js/src/generated/accounts/inscriptionMetadata.ts b/clients/js/src/generated/accounts/inscriptionMetadata.ts index 164e969..30deb86 100644 --- a/clients/js/src/generated/accounts/inscriptionMetadata.ts +++ b/clients/js/src/generated/accounts/inscriptionMetadata.ts @@ -54,6 +54,7 @@ export type InscriptionMetadataAccountData = { inscriptionBump: Option; updateAuthorities: Array; associatedInscriptions: Array; + mint: Option; padding: Array; }; @@ -66,6 +67,7 @@ export type InscriptionMetadataAccountDataArgs = { inscriptionBump: OptionOrNullable; updateAuthorities: Array; associatedInscriptions: Array; + mint: OptionOrNullable; padding: Array; }; @@ -83,7 +85,8 @@ export function getInscriptionMetadataAccountDataSerializer(): Serializer< ['inscriptionBump', option(u8())], ['updateAuthorities', array(publicKeySerializer())], ['associatedInscriptions', array(getAssociatedInscriptionSerializer())], - ['padding', array(u8(), { size: 8 })], + ['mint', option(publicKeySerializer())], + ['padding', array(u8(), { size: 7 })], ], { description: 'InscriptionMetadataAccountData' } ) as Serializer< @@ -176,6 +179,7 @@ export function getInscriptionMetadataGpaBuilder( inscriptionBump: OptionOrNullable; updateAuthorities: Array; associatedInscriptions: Array; + mint: OptionOrNullable; padding: Array; }>({ key: [0, getKeySerializer()], @@ -189,7 +193,8 @@ export function getInscriptionMetadataGpaBuilder( null, array(getAssociatedInscriptionSerializer()), ], - padding: [null, array(u8(), { size: 8 })], + mint: [null, option(publicKeySerializer())], + padding: [null, array(u8(), { size: 7 })], }) .deserializeUsing((account) => deserializeInscriptionMetadata(account) diff --git a/clients/js/src/generated/errors/mplInscription.ts b/clients/js/src/generated/errors/mplInscription.ts index 472d96d..13c79f8 100644 --- a/clients/js/src/generated/errors/mplInscription.ts +++ b/clients/js/src/generated/errors/mplInscription.ts @@ -243,6 +243,42 @@ export class AuthorityAlreadyExistsError extends ProgramError { codeToErrorMap.set(0x10, AuthorityAlreadyExistsError); nameToErrorMap.set('AuthorityAlreadyExists', AuthorityAlreadyExistsError); +/** RemainingAssociatedInscriptionAccounts: Cannot close Inscription accounts until all Associated Inscriptions are closed. */ +export class RemainingAssociatedInscriptionAccountsError extends ProgramError { + readonly name: string = 'RemainingAssociatedInscriptionAccounts'; + + readonly code: number = 0x11; // 17 + + constructor(program: Program, cause?: Error) { + super( + 'Cannot close Inscription accounts until all Associated Inscriptions are closed.', + program, + cause + ); + } +} +codeToErrorMap.set(0x11, RemainingAssociatedInscriptionAccountsError); +nameToErrorMap.set( + 'RemainingAssociatedInscriptionAccounts', + RemainingAssociatedInscriptionAccountsError +); + +/** InvalidInscriptionMetadataAccount: The inscription metadata account is invalid. */ +export class InvalidInscriptionMetadataAccountError extends ProgramError { + readonly name: string = 'InvalidInscriptionMetadataAccount'; + + readonly code: number = 0x12; // 18 + + constructor(program: Program, cause?: Error) { + super('The inscription metadata account is invalid.', program, cause); + } +} +codeToErrorMap.set(0x12, InvalidInscriptionMetadataAccountError); +nameToErrorMap.set( + 'InvalidInscriptionMetadataAccount', + InvalidInscriptionMetadataAccountError +); + /** * Attempts to resolve a custom program error from the provided error code. * @category Errors diff --git a/clients/js/src/generated/instructions/index.ts b/clients/js/src/generated/instructions/index.ts index 6493c67..23c610f 100644 --- a/clients/js/src/generated/instructions/index.ts +++ b/clients/js/src/generated/instructions/index.ts @@ -13,4 +13,5 @@ export * from './close'; export * from './createShard'; export * from './initializeAssociatedInscription'; export * from './removeAuthority'; +export * from './setMint'; export * from './writeData'; diff --git a/clients/js/src/generated/instructions/setMint.ts b/clients/js/src/generated/instructions/setMint.ts new file mode 100644 index 0000000..7b0b14c --- /dev/null +++ b/clients/js/src/generated/instructions/setMint.ts @@ -0,0 +1,129 @@ +/** + * 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 { + Context, + Pda, + PublicKey, + Signer, + TransactionBuilder, + transactionBuilder, +} from '@metaplex-foundation/umi'; +import { + Serializer, + mapSerializer, + struct, + u8, +} from '@metaplex-foundation/umi/serializers'; +import { + ResolvedAccount, + ResolvedAccountsWithIndices, + getAccountMetasAndSigners, +} from '../shared'; + +// Accounts. +export type SetMintInstructionAccounts = { + /** The account where data is stored. */ + mintInscriptionAccount: PublicKey | Pda; + /** The account to store the inscription account's metadata in. */ + inscriptionMetadataAccount: PublicKey | Pda; + /** The mint that will be used to derive the PDA. */ + mintAccount: PublicKey | Pda; + /** The account that will pay for the transaction and rent. */ + payer?: Signer; + /** System program */ + systemProgram?: PublicKey | Pda; +}; + +// Data. +export type SetMintInstructionData = { discriminator: number }; + +export type SetMintInstructionDataArgs = {}; + +export function getSetMintInstructionDataSerializer(): Serializer< + SetMintInstructionDataArgs, + SetMintInstructionData +> { + return mapSerializer( + struct([['discriminator', u8()]], { + description: 'SetMintInstructionData', + }), + (value) => ({ ...value, discriminator: 10 }) + ) as Serializer; +} + +// Instruction. +export function setMint( + context: Pick, + input: SetMintInstructionAccounts +): TransactionBuilder { + // Program ID. + const programId = context.programs.getPublicKey( + 'mplInscription', + '1NSCRfGeyo7wPUazGbaPBUsTM49e1k2aXewHGARfzSo' + ); + + // Accounts. + const resolvedAccounts: ResolvedAccountsWithIndices = { + mintInscriptionAccount: { + index: 0, + isWritable: false, + value: input.mintInscriptionAccount ?? null, + }, + inscriptionMetadataAccount: { + index: 1, + isWritable: true, + value: input.inscriptionMetadataAccount ?? null, + }, + mintAccount: { + index: 2, + isWritable: false, + value: input.mintAccount ?? null, + }, + payer: { index: 3, isWritable: true, value: input.payer ?? null }, + systemProgram: { + index: 4, + isWritable: false, + value: input.systemProgram ?? null, + }, + }; + + // Default values. + if (!resolvedAccounts.payer.value) { + resolvedAccounts.payer.value = context.payer; + } + if (!resolvedAccounts.systemProgram.value) { + resolvedAccounts.systemProgram.value = context.programs.getPublicKey( + 'splSystem', + '11111111111111111111111111111111' + ); + resolvedAccounts.systemProgram.isWritable = false; + } + + // Accounts in order. + const orderedAccounts: ResolvedAccount[] = Object.values( + resolvedAccounts + ).sort((a, b) => a.index - b.index); + + // Keys and Signers. + const [keys, signers] = getAccountMetasAndSigners( + orderedAccounts, + 'programId', + programId + ); + + // Data. + const data = getSetMintInstructionDataSerializer().serialize({}); + + // Bytes Created On Chain. + const bytesCreatedOnChain = 0; + + return transactionBuilder([ + { instruction: { keys, programId, data }, signers, bytesCreatedOnChain }, + ]); +} diff --git a/clients/rust/src/generated/accounts/inscription_metadata.rs b/clients/rust/src/generated/accounts/inscription_metadata.rs index 24b05b7..0dba3a6 100644 --- a/clients/rust/src/generated/accounts/inscription_metadata.rs +++ b/clients/rust/src/generated/accounts/inscription_metadata.rs @@ -27,7 +27,8 @@ pub struct InscriptionMetadata { pub inscription_bump: Option, pub update_authorities: Vec, pub associated_inscriptions: Vec, - pub padding: [u8; 8], + pub mint: Option, + pub padding: [u8; 7], } impl InscriptionMetadata { diff --git a/clients/rust/src/generated/errors/mpl_inscription.rs b/clients/rust/src/generated/errors/mpl_inscription.rs index 2367349..2106764 100644 --- a/clients/rust/src/generated/errors/mpl_inscription.rs +++ b/clients/rust/src/generated/errors/mpl_inscription.rs @@ -61,6 +61,12 @@ pub enum MplInscriptionError { /// 16 (0x10) - The authority already exists. #[error("The authority already exists.")] AuthorityAlreadyExists, + /// 17 (0x11) - Cannot close Inscription accounts until all Associated Inscriptions are closed. + #[error("Cannot close Inscription accounts until all Associated Inscriptions are closed.")] + RemainingAssociatedInscriptionAccounts, + /// 18 (0x12) - The inscription metadata account is invalid. + #[error("The inscription metadata account is invalid.")] + InvalidInscriptionMetadataAccount, } impl solana_program::program_error::PrintProgramError for MplInscriptionError { diff --git a/clients/rust/src/generated/instructions/mod.rs b/clients/rust/src/generated/instructions/mod.rs index a06b4a6..3217101 100644 --- a/clients/rust/src/generated/instructions/mod.rs +++ b/clients/rust/src/generated/instructions/mod.rs @@ -14,6 +14,7 @@ pub(crate) mod initialize; pub(crate) mod initialize_associated_inscription; pub(crate) mod initialize_from_mint; pub(crate) mod remove_authority; +pub(crate) mod set_mint; pub(crate) mod write_data; pub use self::add_authority::*; @@ -25,4 +26,5 @@ pub use self::initialize::*; pub use self::initialize_associated_inscription::*; pub use self::initialize_from_mint::*; pub use self::remove_authority::*; +pub use self::set_mint::*; pub use self::write_data::*; diff --git a/clients/rust/src/generated/instructions/set_mint.rs b/clients/rust/src/generated/instructions/set_mint.rs new file mode 100644 index 0000000..0584003 --- /dev/null +++ b/clients/rust/src/generated/instructions/set_mint.rs @@ -0,0 +1,443 @@ +//! 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; + +/// Accounts. +pub struct SetMint { + /// The account where data is stored. + pub mint_inscription_account: solana_program::pubkey::Pubkey, + /// The account to store the inscription account's metadata in. + pub inscription_metadata_account: solana_program::pubkey::Pubkey, + /// The mint that will be used to derive the PDA. + pub mint_account: solana_program::pubkey::Pubkey, + /// The account that will pay for the transaction and rent. + pub payer: solana_program::pubkey::Pubkey, + /// System program + pub system_program: solana_program::pubkey::Pubkey, +} + +impl SetMint { + pub fn instruction(&self) -> solana_program::instruction::Instruction { + self.instruction_with_remaining_accounts(&[]) + } + #[allow(clippy::vec_init_then_push)] + pub fn instruction_with_remaining_accounts( + &self, + remaining_accounts: &[solana_program::instruction::AccountMeta], + ) -> solana_program::instruction::Instruction { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + self.mint_inscription_account, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new( + self.inscription_metadata_account, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + self.mint_account, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new( + self.payer, true, + )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + self.system_program, + false, + )); + accounts.extend_from_slice(remaining_accounts); + let data = SetMintInstructionData::new().try_to_vec().unwrap(); + + solana_program::instruction::Instruction { + program_id: crate::MPL_INSCRIPTION_ID, + accounts, + data, + } + } +} + +#[derive(BorshDeserialize, BorshSerialize)] +struct SetMintInstructionData { + discriminator: u8, +} + +impl SetMintInstructionData { + fn new() -> Self { + Self { discriminator: 10 } + } +} + +/// Instruction builder. +#[derive(Default)] +pub struct SetMintBuilder { + mint_inscription_account: Option, + inscription_metadata_account: Option, + mint_account: Option, + payer: Option, + system_program: Option, + __remaining_accounts: Vec, +} + +impl SetMintBuilder { + pub fn new() -> Self { + Self::default() + } + /// The account where data is stored. + #[inline(always)] + pub fn mint_inscription_account( + &mut self, + mint_inscription_account: solana_program::pubkey::Pubkey, + ) -> &mut Self { + self.mint_inscription_account = Some(mint_inscription_account); + self + } + /// The account to store the inscription account's metadata in. + #[inline(always)] + pub fn inscription_metadata_account( + &mut self, + inscription_metadata_account: solana_program::pubkey::Pubkey, + ) -> &mut Self { + self.inscription_metadata_account = Some(inscription_metadata_account); + self + } + /// The mint that will be used to derive the PDA. + #[inline(always)] + pub fn mint_account(&mut self, mint_account: solana_program::pubkey::Pubkey) -> &mut Self { + self.mint_account = Some(mint_account); + self + } + /// The account that will pay for the transaction and rent. + #[inline(always)] + pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { + self.payer = Some(payer); + self + } + /// `[optional account, default to '11111111111111111111111111111111']` + /// System program + #[inline(always)] + pub fn system_program(&mut self, system_program: solana_program::pubkey::Pubkey) -> &mut Self { + self.system_program = Some(system_program); + self + } + /// Add an aditional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: solana_program::instruction::AccountMeta, + ) -> &mut Self { + self.__remaining_accounts.push(account); + self + } + /// Add additional accounts to the instruction. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[solana_program::instruction::AccountMeta], + ) -> &mut Self { + self.__remaining_accounts.extend_from_slice(accounts); + self + } + #[allow(clippy::clone_on_copy)] + pub fn instruction(&self) -> solana_program::instruction::Instruction { + let accounts = SetMint { + mint_inscription_account: self + .mint_inscription_account + .expect("mint_inscription_account is not set"), + inscription_metadata_account: self + .inscription_metadata_account + .expect("inscription_metadata_account is not set"), + mint_account: self.mint_account.expect("mint_account is not set"), + payer: self.payer.expect("payer is not set"), + system_program: self + .system_program + .unwrap_or(solana_program::pubkey!("11111111111111111111111111111111")), + }; + + accounts.instruction_with_remaining_accounts(&self.__remaining_accounts) + } +} + +/// `set_mint` CPI accounts. +pub struct SetMintCpiAccounts<'a, 'b> { + /// The account where data is stored. + pub mint_inscription_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The account to store the inscription account's metadata in. + pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The mint that will be used to derive the PDA. + pub mint_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The account that will pay for the transaction and rent. + pub payer: &'b solana_program::account_info::AccountInfo<'a>, + /// System program + pub system_program: &'b solana_program::account_info::AccountInfo<'a>, +} + +/// `set_mint` CPI instruction. +pub struct SetMintCpi<'a, 'b> { + /// The program to invoke. + pub __program: &'b solana_program::account_info::AccountInfo<'a>, + /// The account where data is stored. + pub mint_inscription_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The account to store the inscription account's metadata in. + pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The mint that will be used to derive the PDA. + pub mint_account: &'b solana_program::account_info::AccountInfo<'a>, + /// The account that will pay for the transaction and rent. + pub payer: &'b solana_program::account_info::AccountInfo<'a>, + /// System program + pub system_program: &'b solana_program::account_info::AccountInfo<'a>, +} + +impl<'a, 'b> SetMintCpi<'a, 'b> { + pub fn new( + program: &'b solana_program::account_info::AccountInfo<'a>, + accounts: SetMintCpiAccounts<'a, 'b>, + ) -> Self { + Self { + __program: program, + mint_inscription_account: accounts.mint_inscription_account, + inscription_metadata_account: accounts.inscription_metadata_account, + mint_account: accounts.mint_account, + payer: accounts.payer, + system_program: accounts.system_program, + } + } + #[inline(always)] + pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], &[]) + } + #[inline(always)] + pub fn invoke_with_remaining_accounts( + &self, + remaining_accounts: &[( + &'b solana_program::account_info::AccountInfo<'a>, + bool, + bool, + )], + ) -> solana_program::entrypoint::ProgramResult { + self.invoke_signed_with_remaining_accounts(&[], remaining_accounts) + } + #[inline(always)] + pub fn invoke_signed( + &self, + signers_seeds: &[&[&[u8]]], + ) -> solana_program::entrypoint::ProgramResult { + self.invoke_signed_with_remaining_accounts(signers_seeds, &[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed_with_remaining_accounts( + &self, + signers_seeds: &[&[&[u8]]], + remaining_accounts: &[( + &'b solana_program::account_info::AccountInfo<'a>, + bool, + bool, + )], + ) -> solana_program::entrypoint::ProgramResult { + let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + *self.mint_inscription_account.key, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new( + *self.inscription_metadata_account.key, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + *self.mint_account.key, + false, + )); + accounts.push(solana_program::instruction::AccountMeta::new( + *self.payer.key, + true, + )); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + *self.system_program.key, + false, + )); + remaining_accounts.iter().for_each(|remaining_account| { + accounts.push(solana_program::instruction::AccountMeta { + pubkey: *remaining_account.0.key, + is_signer: remaining_account.1, + is_writable: remaining_account.2, + }) + }); + let data = SetMintInstructionData::new().try_to_vec().unwrap(); + + let instruction = solana_program::instruction::Instruction { + program_id: crate::MPL_INSCRIPTION_ID, + accounts, + data, + }; + let mut account_infos = Vec::with_capacity(5 + 1 + remaining_accounts.len()); + account_infos.push(self.__program.clone()); + account_infos.push(self.mint_inscription_account.clone()); + account_infos.push(self.inscription_metadata_account.clone()); + account_infos.push(self.mint_account.clone()); + account_infos.push(self.payer.clone()); + account_infos.push(self.system_program.clone()); + remaining_accounts + .iter() + .for_each(|remaining_account| account_infos.push(remaining_account.0.clone())); + + if signers_seeds.is_empty() { + solana_program::program::invoke(&instruction, &account_infos) + } else { + solana_program::program::invoke_signed(&instruction, &account_infos, signers_seeds) + } + } +} + +/// `set_mint` CPI instruction builder. +pub struct SetMintCpiBuilder<'a, 'b> { + instruction: Box>, +} + +impl<'a, 'b> SetMintCpiBuilder<'a, 'b> { + pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self { + let instruction = Box::new(SetMintCpiBuilderInstruction { + __program: program, + mint_inscription_account: None, + inscription_metadata_account: None, + mint_account: None, + payer: None, + system_program: None, + __remaining_accounts: Vec::new(), + }); + Self { instruction } + } + /// The account where data is stored. + #[inline(always)] + pub fn mint_inscription_account( + &mut self, + mint_inscription_account: &'b solana_program::account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.mint_inscription_account = Some(mint_inscription_account); + self + } + /// The account to store the inscription account's metadata in. + #[inline(always)] + pub fn inscription_metadata_account( + &mut self, + inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.inscription_metadata_account = Some(inscription_metadata_account); + self + } + /// The mint that will be used to derive the PDA. + #[inline(always)] + pub fn mint_account( + &mut self, + mint_account: &'b solana_program::account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.mint_account = Some(mint_account); + self + } + /// The account that will pay for the transaction and rent. + #[inline(always)] + pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { + self.instruction.payer = Some(payer); + self + } + /// System program + #[inline(always)] + pub fn system_program( + &mut self, + system_program: &'b solana_program::account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.system_program = Some(system_program); + self + } + /// Add an additional account to the instruction. + #[inline(always)] + pub fn add_remaining_account( + &mut self, + account: &'b solana_program::account_info::AccountInfo<'a>, + is_writable: bool, + is_signer: bool, + ) -> &mut Self { + self.instruction + .__remaining_accounts + .push((account, is_writable, is_signer)); + self + } + /// Add additional accounts to the instruction. + /// + /// Each account is represented by a tuple of the `AccountInfo`, a `bool` indicating whether the account is writable or not, + /// and a `bool` indicating whether the account is a signer or not. + #[inline(always)] + pub fn add_remaining_accounts( + &mut self, + accounts: &[( + &'b solana_program::account_info::AccountInfo<'a>, + bool, + bool, + )], + ) -> &mut Self { + self.instruction + .__remaining_accounts + .extend_from_slice(accounts); + self + } + #[inline(always)] + pub fn invoke(&self) -> solana_program::entrypoint::ProgramResult { + self.invoke_signed(&[]) + } + #[allow(clippy::clone_on_copy)] + #[allow(clippy::vec_init_then_push)] + pub fn invoke_signed( + &self, + signers_seeds: &[&[&[u8]]], + ) -> solana_program::entrypoint::ProgramResult { + let instruction = SetMintCpi { + __program: self.instruction.__program, + + mint_inscription_account: self + .instruction + .mint_inscription_account + .expect("mint_inscription_account is not set"), + + inscription_metadata_account: self + .instruction + .inscription_metadata_account + .expect("inscription_metadata_account is not set"), + + mint_account: self + .instruction + .mint_account + .expect("mint_account is not set"), + + payer: self.instruction.payer.expect("payer is not set"), + + system_program: self + .instruction + .system_program + .expect("system_program is not set"), + }; + instruction.invoke_signed_with_remaining_accounts( + signers_seeds, + &self.instruction.__remaining_accounts, + ) + } +} + +struct SetMintCpiBuilderInstruction<'a, 'b> { + __program: &'b solana_program::account_info::AccountInfo<'a>, + mint_inscription_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, + inscription_metadata_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, + mint_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, + payer: Option<&'b solana_program::account_info::AccountInfo<'a>>, + system_program: Option<&'b solana_program::account_info::AccountInfo<'a>>, + /// Additional instruction accounts `(AccountInfo, is_writable, is_signer)`. + __remaining_accounts: Vec<( + &'b solana_program::account_info::AccountInfo<'a>, + bool, + bool, + )>, +} diff --git a/idls/mpl_inscription.json b/idls/mpl_inscription.json index 69d8e41..8e16e77 100644 --- a/idls/mpl_inscription.json +++ b/idls/mpl_inscription.json @@ -567,6 +567,56 @@ "type": "u8", "value": 9 } + }, + { + "name": "SetMint", + "accounts": [ + { + "name": "mintInscriptionAccount", + "isMut": false, + "isSigner": false, + "docs": [ + "The account where data is stored." + ] + }, + { + "name": "inscriptionMetadataAccount", + "isMut": true, + "isSigner": false, + "docs": [ + "The account to store the inscription account's metadata in." + ] + }, + { + "name": "mintAccount", + "isMut": false, + "isSigner": false, + "docs": [ + "The mint that will be used to derive the PDA." + ] + }, + { + "name": "payer", + "isMut": true, + "isSigner": true, + "docs": [ + "The account that will pay for the transaction and rent." + ] + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false, + "docs": [ + "System program" + ] + } + ], + "args": [], + "discriminant": { + "type": "u8", + "value": 10 + } } ], "accounts": [ @@ -619,12 +669,18 @@ } } }, + { + "name": "mint", + "type": { + "option": "publicKey" + } + }, { "name": "padding", "type": { "array": [ "u8", - 8 + 7 ] } } @@ -908,6 +964,16 @@ "code": 16, "name": "AuthorityAlreadyExists", "msg": "The authority already exists." + }, + { + "code": 17, + "name": "RemainingAssociatedInscriptionAccounts", + "msg": "Cannot close Inscription accounts until all Associated Inscriptions are closed." + }, + { + "code": 18, + "name": "InvalidInscriptionMetadataAccount", + "msg": "The inscription metadata account is invalid." } ], "metadata": { diff --git a/programs/mpl-inscription/src/error.rs b/programs/mpl-inscription/src/error.rs index 4547d90..72ee86e 100644 --- a/programs/mpl-inscription/src/error.rs +++ b/programs/mpl-inscription/src/error.rs @@ -79,6 +79,10 @@ pub enum MplInscriptionError { /// 17 - Remaining Associated Inscription Accounts #[error("Cannot close Inscription accounts until all Associated Inscriptions are closed.")] RemainingAssociatedInscriptionAccounts, + + /// 18 - Invalid Inscription Metadata Account + #[error("The inscription metadata account is invalid.")] + InvalidInscriptionMetadataAccount, } impl PrintProgramError for MplInscriptionError { diff --git a/programs/mpl-inscription/src/instruction/mod.rs b/programs/mpl-inscription/src/instruction/mod.rs index ead117c..47d95b1 100644 --- a/programs/mpl-inscription/src/instruction/mod.rs +++ b/programs/mpl-inscription/src/instruction/mod.rs @@ -85,6 +85,14 @@ pub enum MplInscriptionInstruction { #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(4, name="system_program", desc = "System program")] Allocate(AllocateArgs), + + /// Set the mint for the inscription metadata account. + #[account(0, name="mint_inscription_account", desc = "The account where data is stored.")] + #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] + #[account(2, name="mint_account", desc="The mint that will be used to derive the PDA.")] + #[account(3, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(4, name="system_program", desc = "System program")] + SetMint, } #[repr(C)] diff --git a/programs/mpl-inscription/src/processor/initialize_from_mint.rs b/programs/mpl-inscription/src/processor/initialize_from_mint.rs index 11bc327..337ba40 100644 --- a/programs/mpl-inscription/src/processor/initialize_from_mint.rs +++ b/programs/mpl-inscription/src/processor/initialize_from_mint.rs @@ -115,6 +115,7 @@ pub(crate) fn process_initialize_from_mint<'a>(accounts: &'a [AccountInfo<'a>]) bump, inscription_bump: Some(inscription_bump), update_authorities: vec![token_metadata.update_authority], + mint: Some(*ctx.accounts.mint_account.key), ..InscriptionMetadata::default() }; diff --git a/programs/mpl-inscription/src/processor/mod.rs b/programs/mpl-inscription/src/processor/mod.rs index c04238f..df7dec5 100644 --- a/programs/mpl-inscription/src/processor/mod.rs +++ b/programs/mpl-inscription/src/processor/mod.rs @@ -11,6 +11,7 @@ mod initialize; mod initialize_associated_inscription; mod initialize_from_mint; mod remove_authority; +mod set_mint; mod write_data; use add_authority::*; @@ -22,6 +23,7 @@ use initialize::*; use initialize_associated_inscription::*; use initialize_from_mint::*; use remove_authority::*; +use set_mint::*; use write_data::*; pub struct Processor; @@ -74,6 +76,10 @@ impl Processor { msg!("Instruction: Allocate"); process_allocate(accounts, args) } + MplInscriptionInstruction::SetMint => { + msg!("Instruction: SetMint"); + process_set_mint(accounts) + } } } } diff --git a/programs/mpl-inscription/src/processor/set_mint.rs b/programs/mpl-inscription/src/processor/set_mint.rs new file mode 100644 index 0000000..63d0d35 --- /dev/null +++ b/programs/mpl-inscription/src/processor/set_mint.rs @@ -0,0 +1,97 @@ +use borsh::{BorshDeserialize, BorshSerialize}; + +use mpl_utils::{ + assert_derivation, assert_owned_by, assert_signer, resize_or_reallocate_account_raw, +}; +use solana_program::{ + account_info::AccountInfo, entrypoint::ProgramResult, program_memory::sol_memcpy, +}; + +use crate::{ + error::MplInscriptionError, + instruction::accounts::SetMintAccounts, + state::{InscriptionMetadata, Key, PREFIX}, +}; + +pub(crate) fn process_set_mint<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { + let ctx = &SetMintAccounts::context(accounts)?; + + // Check that the account is already initialized. + if (ctx.accounts.mint_inscription_account.owner != &crate::ID) + || ctx.accounts.mint_inscription_account.data_is_empty() + { + return Err(MplInscriptionError::NotInitialized.into()); + } + + // Check that the account is already initialized. + if (ctx.accounts.inscription_metadata_account.owner != &crate::ID) + || ctx.accounts.inscription_metadata_account.data_is_empty() + { + return Err(MplInscriptionError::NotInitialized.into()); + } + + assert_owned_by( + ctx.accounts.mint_account, + &spl_token::ID, + MplInscriptionError::IncorrectOwner, + )?; + + // Verify that the derived address is correct for the metadata account. + let _inscription_bump = assert_derivation( + &crate::ID, + ctx.accounts.mint_inscription_account, + &[ + PREFIX.as_bytes(), + crate::ID.as_ref(), + ctx.accounts.mint_account.key.as_ref(), + ], + MplInscriptionError::DerivedKeyInvalid, + )?; + + // Verify that the derived address is correct for the metadata account. + let _bump = assert_derivation( + &crate::ID, + ctx.accounts.inscription_metadata_account, + &[ + PREFIX.as_bytes(), + crate::ID.as_ref(), + ctx.accounts.mint_inscription_account.key.as_ref(), + ], + MplInscriptionError::DerivedKeyInvalid, + )?; + + assert_signer(ctx.accounts.payer)?; + + // Initialize the inscription metadata. + let mut inscription_metadata = InscriptionMetadata::try_from_slice( + &ctx.accounts.inscription_metadata_account.data.borrow(), + )?; + + // Check that the account is a valid inscription metadata account. + if inscription_metadata.key != Key::MintInscriptionMetadataAccount { + return Err(MplInscriptionError::InvalidInscriptionMetadataAccount.into()); + } + + inscription_metadata.mint = Some(*ctx.accounts.mint_account.key); + + let serialized_metadata = &inscription_metadata.try_to_vec()?; + + resize_or_reallocate_account_raw( + ctx.accounts.inscription_metadata_account, + ctx.accounts.payer, + ctx.accounts.system_program, + serialized_metadata.len(), + )?; + + // Write the inscription metadata to the metadata account. + sol_memcpy( + &mut ctx + .accounts + .inscription_metadata_account + .try_borrow_mut_data()?, + serialized_metadata, + serialized_metadata.len(), + ); + + Ok(()) +} diff --git a/programs/mpl-inscription/src/state.rs b/programs/mpl-inscription/src/state.rs index bda47b6..3cef858 100644 --- a/programs/mpl-inscription/src/state.rs +++ b/programs/mpl-inscription/src/state.rs @@ -43,7 +43,8 @@ pub struct InscriptionMetadata { pub inscription_bump: Option, pub update_authorities: Vec, pub associated_inscriptions: Vec, - pub _padding: [u8; 8], + pub mint: Option, + pub _padding: [u8; 7], } impl Default for InscriptionMetadata { @@ -57,7 +58,8 @@ impl Default for InscriptionMetadata { inscription_bump: None, update_authorities: vec![], associated_inscriptions: vec![], - _padding: [0; 8], + mint: None, + _padding: [0; 7], } } } From efd617347a2867c0ae3780441bd28fcce70b0128 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Fri, 19 Jan 2024 16:03:10 -0500 Subject: [PATCH 2/4] Fixing wrong check and adding tests. --- clients/js/test/initialize.test.ts | 5 +- clients/js/test/initializeFromMint.test.ts | 4 +- clients/js/test/setMint.test.ts | 188 ++++++++++++++++++ .../mpl-inscription/src/processor/set_mint.rs | 4 +- 4 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 clients/js/test/setMint.test.ts diff --git a/clients/js/test/initialize.test.ts b/clients/js/test/initialize.test.ts index 1b36d84..18d557d 100644 --- a/clients/js/test/initialize.test.ts +++ b/clients/js/test/initialize.test.ts @@ -1,5 +1,5 @@ /* eslint-disable no-await-in-loop */ -import { generateSigner } from '@metaplex-foundation/umi'; +import { generateSigner, none } from '@metaplex-foundation/umi'; import test from 'ava'; import { AssociatedInscription, @@ -59,6 +59,7 @@ test('it can initialize an Inscription account', async (t) => { shardDataBefore.count * BigInt(32) + BigInt(shardDataBefore.shardNumber), updateAuthorities: [umi.identity.publicKey], associatedInscriptions: [] as AssociatedInscription[], + mint: none(), }); const jsonData = await umi.rpc.getAccount(inscriptionAccount.publicKey); @@ -120,6 +121,7 @@ test('it can initialize multiple Inscription accounts', async (t) => { BigInt(shardDataBefore.shardNumber), updateAuthorities: [umi.identity.publicKey], associatedInscriptions: [] as AssociatedInscription[], + mint: none(), }); const jsonData = await umi.rpc.getAccount(inscriptionAccount[i].publicKey); @@ -178,6 +180,7 @@ test('it can initialize an Inscription account with separate authority', async ( shardDataBefore.count * BigInt(32) + BigInt(shardDataBefore.shardNumber), updateAuthorities: [authority.publicKey], associatedInscriptions: [] as AssociatedInscription[], + mint: none(), }); const jsonData = await umi.rpc.getAccount(inscriptionAccount.publicKey); diff --git a/clients/js/test/initializeFromMint.test.ts b/clients/js/test/initializeFromMint.test.ts index 5bae96f..d8955c4 100644 --- a/clients/js/test/initializeFromMint.test.ts +++ b/clients/js/test/initializeFromMint.test.ts @@ -1,4 +1,4 @@ -import { generateSigner, percentAmount } from '@metaplex-foundation/umi'; +import { generateSigner, percentAmount, some } from '@metaplex-foundation/umi'; import test from 'ava'; import { TokenStandard, @@ -84,6 +84,7 @@ test('it can initialize a Mint Inscription account', async (t) => { shardDataBefore.count * BigInt(32) + BigInt(shardDataBefore.shardNumber), updateAuthorities: [umi.identity.publicKey], associatedInscriptions: [] as AssociatedInscription[], + mint: some(mint.publicKey), }); const jsonData = await umi.rpc.getAccount(inscriptionAccount[0]); @@ -208,6 +209,7 @@ test('it can initialize a Mint Inscription account with separate authority', asy shardDataBefore.count * BigInt(32) + BigInt(shardDataBefore.shardNumber), updateAuthorities: [authority.publicKey], associatedInscriptions: [] as AssociatedInscription[], + mint: some(mint.publicKey), }); const jsonData = await umi.rpc.getAccount(inscriptionAccount[0]); diff --git a/clients/js/test/setMint.test.ts b/clients/js/test/setMint.test.ts new file mode 100644 index 0000000..6183142 --- /dev/null +++ b/clients/js/test/setMint.test.ts @@ -0,0 +1,188 @@ +import { TransactionBuilder, generateSigner, percentAmount, some } from '@metaplex-foundation/umi'; +import test from 'ava'; +import { + TokenStandard, + createV1, + mintV1, + mplTokenMetadata, +} from '@metaplex-foundation/mpl-token-metadata'; +import { + AssociatedInscription, + DataType, + InscriptionMetadata, + Key, + fetchInscriptionMetadata, + findInscriptionMetadataPda, + findMintInscriptionPda, + initialize, + initializeFromMint, + setMint, +} from '../src'; +import { createUmi } from './_setup'; + +test('it can set the mint on a Mint Inscription account', async (t) => { + // Given a Umi instance and a new signer. + const umi = await createUmi(); + umi.use(mplTokenMetadata()); + + const mint = generateSigner(umi); + await createV1(umi, { + mint, + name: 'My NFT', + uri: 'https://arweave.net/LcjCf-NDr5bhCJ0YMKGlc8m8qT_J6TDWtIuW8lbu0-A', + sellerFeeBasisPoints: percentAmount(5.5), + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + await mintV1(umi, { + mint: mint.publicKey, + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + const inscriptionAccount = await findMintInscriptionPda(umi, { + mint: mint.publicKey, + }); + const inscriptionMetadataAccount = await findInscriptionMetadataPda(umi, { + inscriptionAccount: inscriptionAccount[0], + }); + + // const asset = await fetchDigitalAsset(umi, mint.publicKey); + + let builder = new TransactionBuilder(); + + // When we create a new account. + builder = builder.append(initializeFromMint(umi, { + mintAccount: mint.publicKey, + })); + + // Set the mint on the account. + builder = builder.append(setMint(umi, { + mintInscriptionAccount: inscriptionAccount, + inscriptionMetadataAccount, + mintAccount: mint.publicKey + })); + + await builder.sendAndConfirm(umi); + + // Then an account was created with the correct data. + const inscriptionMetadata = await fetchInscriptionMetadata( + umi, + inscriptionMetadataAccount + ); + + t.like(inscriptionMetadata, { + key: Key.MintInscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount[0], + bump: inscriptionMetadataAccount[1], + dataType: DataType.Uninitialized, + updateAuthorities: [umi.identity.publicKey], + associatedInscriptions: [] as AssociatedInscription[], + mint: some(mint.publicKey), + }); +}); + +test('it cannot set the mint on an Inscription account', async (t) => { + // Given a Umi instance and a new signer. + const umi = await createUmi(); + umi.use(mplTokenMetadata()); + + const mint = generateSigner(umi); + await createV1(umi, { + mint, + name: 'My NFT', + uri: 'https://arweave.net/LcjCf-NDr5bhCJ0YMKGlc8m8qT_J6TDWtIuW8lbu0-A', + sellerFeeBasisPoints: percentAmount(5.5), + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + await mintV1(umi, { + mint: mint.publicKey, + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + const inscriptionAccount = generateSigner(umi); + + const inscriptionMetadataAccount = await findInscriptionMetadataPda(umi, { + inscriptionAccount: inscriptionAccount.publicKey, + }); + + let builder = new TransactionBuilder(); + + // When we create a new account. + builder = builder.append(initialize(umi, { + inscriptionAccount, + })); + + // Set the mint on the account. + builder = builder.append(setMint(umi, { + mintInscriptionAccount: inscriptionAccount.publicKey, + inscriptionMetadataAccount, + mintAccount: mint.publicKey, + })); + + const promise = builder.sendAndConfirm(umi); + // Then an error is thrown. + await t.throwsAsync(promise, { name: 'DerivedKeyInvalid' }); +}); + +test('it cannot set the wrong mint on a Mint Inscription account', async (t) => { + // Given a Umi instance and a new signer. + const umi = await createUmi(); + umi.use(mplTokenMetadata()); + + const mint = generateSigner(umi); + await createV1(umi, { + mint, + name: 'My NFT', + uri: 'https://arweave.net/LcjCf-NDr5bhCJ0YMKGlc8m8qT_J6TDWtIuW8lbu0-A', + sellerFeeBasisPoints: percentAmount(5.5), + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + await mintV1(umi, { + mint: mint.publicKey, + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + const wrongMint = generateSigner(umi); + await createV1(umi, { + mint: wrongMint, + name: 'My NFT', + uri: 'https://arweave.net/LcjCf-NDr5bhCJ0YMKGlc8m8qT_J6TDWtIuW8lbu0-A', + sellerFeeBasisPoints: percentAmount(5.5), + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + await mintV1(umi, { + mint: wrongMint.publicKey, + tokenStandard: TokenStandard.NonFungible, + }).sendAndConfirm(umi); + + const inscriptionAccount = await findMintInscriptionPda(umi, { + mint: mint.publicKey, + }); + const inscriptionMetadataAccount = await findInscriptionMetadataPda(umi, { + inscriptionAccount: inscriptionAccount[0], + }); + + // const asset = await fetchDigitalAsset(umi, mint.publicKey); + + let builder = new TransactionBuilder(); + + // When we create a new account. + builder = builder.append(initializeFromMint(umi, { + mintAccount: mint.publicKey, + })); + + // Set the mint on the account. + builder = builder.append(setMint(umi, { + mintInscriptionAccount: inscriptionAccount, + inscriptionMetadataAccount, + mintAccount: wrongMint.publicKey + })); + + const promise = builder.sendAndConfirm(umi); + + // Then an error is thrown. + await t.throwsAsync(promise, { name: 'DerivedKeyInvalid' }); +}); diff --git a/programs/mpl-inscription/src/processor/set_mint.rs b/programs/mpl-inscription/src/processor/set_mint.rs index 63d0d35..21b43a9 100644 --- a/programs/mpl-inscription/src/processor/set_mint.rs +++ b/programs/mpl-inscription/src/processor/set_mint.rs @@ -17,9 +17,7 @@ pub(crate) fn process_set_mint<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramRe let ctx = &SetMintAccounts::context(accounts)?; // Check that the account is already initialized. - if (ctx.accounts.mint_inscription_account.owner != &crate::ID) - || ctx.accounts.mint_inscription_account.data_is_empty() - { + if ctx.accounts.mint_inscription_account.owner != &crate::ID { return Err(MplInscriptionError::NotInitialized.into()); } From da6ebef2f6058e6edfb5745f99a6380c7b426750 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Mon, 22 Jan 2024 13:47:22 -0500 Subject: [PATCH 3/4] Fixing formatting. --- clients/js/test/setMint.test.ts | 67 +++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/clients/js/test/setMint.test.ts b/clients/js/test/setMint.test.ts index 6183142..314d8b1 100644 --- a/clients/js/test/setMint.test.ts +++ b/clients/js/test/setMint.test.ts @@ -1,4 +1,9 @@ -import { TransactionBuilder, generateSigner, percentAmount, some } from '@metaplex-foundation/umi'; +import { + TransactionBuilder, + generateSigner, + percentAmount, + some, +} from '@metaplex-foundation/umi'; import test from 'ava'; import { TokenStandard, @@ -51,16 +56,20 @@ test('it can set the mint on a Mint Inscription account', async (t) => { let builder = new TransactionBuilder(); // When we create a new account. - builder = builder.append(initializeFromMint(umi, { - mintAccount: mint.publicKey, - })); + builder = builder.append( + initializeFromMint(umi, { + mintAccount: mint.publicKey, + }) + ); // Set the mint on the account. - builder = builder.append(setMint(umi, { - mintInscriptionAccount: inscriptionAccount, - inscriptionMetadataAccount, - mintAccount: mint.publicKey - })); + builder = builder.append( + setMint(umi, { + mintInscriptionAccount: inscriptionAccount, + inscriptionMetadataAccount, + mintAccount: mint.publicKey, + }) + ); await builder.sendAndConfirm(umi); @@ -109,16 +118,20 @@ test('it cannot set the mint on an Inscription account', async (t) => { let builder = new TransactionBuilder(); // When we create a new account. - builder = builder.append(initialize(umi, { - inscriptionAccount, - })); + builder = builder.append( + initialize(umi, { + inscriptionAccount, + }) + ); // Set the mint on the account. - builder = builder.append(setMint(umi, { - mintInscriptionAccount: inscriptionAccount.publicKey, - inscriptionMetadataAccount, - mintAccount: mint.publicKey, - })); + builder = builder.append( + setMint(umi, { + mintInscriptionAccount: inscriptionAccount.publicKey, + inscriptionMetadataAccount, + mintAccount: mint.publicKey, + }) + ); const promise = builder.sendAndConfirm(umi); // Then an error is thrown. @@ -170,16 +183,20 @@ test('it cannot set the wrong mint on a Mint Inscription account', async (t) => let builder = new TransactionBuilder(); // When we create a new account. - builder = builder.append(initializeFromMint(umi, { - mintAccount: mint.publicKey, - })); + builder = builder.append( + initializeFromMint(umi, { + mintAccount: mint.publicKey, + }) + ); // Set the mint on the account. - builder = builder.append(setMint(umi, { - mintInscriptionAccount: inscriptionAccount, - inscriptionMetadataAccount, - mintAccount: wrongMint.publicKey - })); + builder = builder.append( + setMint(umi, { + mintInscriptionAccount: inscriptionAccount, + inscriptionMetadataAccount, + mintAccount: wrongMint.publicKey, + }) + ); const promise = builder.sendAndConfirm(umi); From a4f35d6c1535522291b8e048dc1c2829cba05bc1 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Fri, 26 Jan 2024 07:54:29 -0500 Subject: [PATCH 4/4] Responding to feedback. --- .../generated/instructions/addAuthority.ts | 2 +- .../js/src/generated/instructions/allocate.ts | 2 +- .../src/generated/instructions/clearData.ts | 2 +- .../js/src/generated/instructions/close.ts | 2 +- .../src/generated/instructions/createShard.ts | 2 +- .../src/generated/instructions/initialize.ts | 2 +- .../initializeAssociatedInscription.ts | 2 +- .../instructions/initializeFromMint.ts | 2 +- .../js/src/generated/instructions/setMint.ts | 2 +- .../src/generated/instructions/writeData.ts | 2 +- clients/js/test/setMint.test.ts | 12 +++++------ .../generated/instructions/add_authority.rs | 10 +++++----- .../src/generated/instructions/allocate.rs | 10 +++++----- .../src/generated/instructions/clear_data.rs | 10 +++++----- .../rust/src/generated/instructions/close.rs | 10 +++++----- .../generated/instructions/create_shard.rs | 10 +++++----- .../src/generated/instructions/initialize.rs | 10 +++++----- .../initialize_associated_inscription.rs | 10 +++++----- .../instructions/initialize_from_mint.rs | 10 +++++----- .../src/generated/instructions/set_mint.rs | 10 +++++----- .../src/generated/instructions/write_data.rs | 10 +++++----- idls/mpl_inscription.json | 20 +++++++++---------- .../mpl-inscription/src/instruction/mod.rs | 20 +++++++++---------- .../mpl-inscription/src/processor/set_mint.rs | 9 +++++++-- 24 files changed, 92 insertions(+), 89 deletions(-) diff --git a/clients/js/src/generated/instructions/addAuthority.ts b/clients/js/src/generated/instructions/addAuthority.ts index d7407bf..187b777 100644 --- a/clients/js/src/generated/instructions/addAuthority.ts +++ b/clients/js/src/generated/instructions/addAuthority.ts @@ -31,7 +31,7 @@ import { export type AddAuthorityInstructionAccounts = { /** The account to store the metadata's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/allocate.ts b/clients/js/src/generated/instructions/allocate.ts index 8830362..af7305e 100644 --- a/clients/js/src/generated/instructions/allocate.ts +++ b/clients/js/src/generated/instructions/allocate.ts @@ -37,7 +37,7 @@ export type AllocateInstructionAccounts = { inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/clearData.ts b/clients/js/src/generated/instructions/clearData.ts index 46eb0ea..c09a9ed 100644 --- a/clients/js/src/generated/instructions/clearData.ts +++ b/clients/js/src/generated/instructions/clearData.ts @@ -36,7 +36,7 @@ export type ClearDataInstructionAccounts = { inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/close.ts b/clients/js/src/generated/instructions/close.ts index 106f2b9..d148074 100644 --- a/clients/js/src/generated/instructions/close.ts +++ b/clients/js/src/generated/instructions/close.ts @@ -36,7 +36,7 @@ export type CloseInstructionAccounts = { inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/createShard.ts b/clients/js/src/generated/instructions/createShard.ts index 05fe003..af41aa9 100644 --- a/clients/js/src/generated/instructions/createShard.ts +++ b/clients/js/src/generated/instructions/createShard.ts @@ -30,7 +30,7 @@ import { export type CreateShardInstructionAccounts = { /** The account to store the shard data in. */ shardAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** System program */ systemProgram?: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/initialize.ts b/clients/js/src/generated/instructions/initialize.ts index dcc44df..1e47ce7 100644 --- a/clients/js/src/generated/instructions/initialize.ts +++ b/clients/js/src/generated/instructions/initialize.ts @@ -36,7 +36,7 @@ export type InitializeInstructionAccounts = { inscriptionMetadataAccount?: PublicKey | Pda; /** The shard account for the inscription counter. */ inscriptionShardAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/initializeAssociatedInscription.ts b/clients/js/src/generated/instructions/initializeAssociatedInscription.ts index 1b537a1..f632688 100644 --- a/clients/js/src/generated/instructions/initializeAssociatedInscription.ts +++ b/clients/js/src/generated/instructions/initializeAssociatedInscription.ts @@ -41,7 +41,7 @@ export type InitializeAssociatedInscriptionInstructionAccounts = { inscriptionMetadataAccount?: PublicKey | Pda; /** The account to create and store the new associated data in. */ associatedInscriptionAccount?: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/initializeFromMint.ts b/clients/js/src/generated/instructions/initializeFromMint.ts index 7137f85..e75ada8 100644 --- a/clients/js/src/generated/instructions/initializeFromMint.ts +++ b/clients/js/src/generated/instructions/initializeFromMint.ts @@ -40,7 +40,7 @@ export type InitializeFromMintInstructionAccounts = { tokenMetadataAccount?: PublicKey | Pda; /** The shard account for the inscription counter. */ inscriptionShardAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/src/generated/instructions/setMint.ts b/clients/js/src/generated/instructions/setMint.ts index 7b0b14c..edc1887 100644 --- a/clients/js/src/generated/instructions/setMint.ts +++ b/clients/js/src/generated/instructions/setMint.ts @@ -34,7 +34,7 @@ export type SetMintInstructionAccounts = { inscriptionMetadataAccount: PublicKey | Pda; /** The mint that will be used to derive the PDA. */ mintAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** System program */ systemProgram?: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/writeData.ts b/clients/js/src/generated/instructions/writeData.ts index b8ddda4..47e3cc9 100644 --- a/clients/js/src/generated/instructions/writeData.ts +++ b/clients/js/src/generated/instructions/writeData.ts @@ -39,7 +39,7 @@ export type WriteDataInstructionAccounts = { inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; - /** The account that will pay for the transaction and rent. */ + /** The account that will pay for the rent. */ payer?: Signer; /** The authority of the inscription account. */ authority?: Signer; diff --git a/clients/js/test/setMint.test.ts b/clients/js/test/setMint.test.ts index 314d8b1..0a90bb7 100644 --- a/clients/js/test/setMint.test.ts +++ b/clients/js/test/setMint.test.ts @@ -51,8 +51,6 @@ test('it can set the mint on a Mint Inscription account', async (t) => { inscriptionAccount: inscriptionAccount[0], }); - // const asset = await fetchDigitalAsset(umi, mint.publicKey); - let builder = new TransactionBuilder(); // When we create a new account. @@ -90,7 +88,7 @@ test('it can set the mint on a Mint Inscription account', async (t) => { }); }); -test('it cannot set the mint on an Inscription account', async (t) => { +test('it cannot set the mint on an Inscription account that is not derived from a mint', async (t) => { // Given a Umi instance and a new signer. const umi = await createUmi(); umi.use(mplTokenMetadata()); @@ -109,6 +107,7 @@ test('it cannot set the mint on an Inscription account', async (t) => { tokenStandard: TokenStandard.NonFungible, }).sendAndConfirm(umi); + // We are creating an inscription account that is not derived from a mint and is not a PDA. const inscriptionAccount = generateSigner(umi); const inscriptionMetadataAccount = await findInscriptionMetadataPda(umi, { @@ -157,6 +156,7 @@ test('it cannot set the wrong mint on a Mint Inscription account', async (t) => tokenStandard: TokenStandard.NonFungible, }).sendAndConfirm(umi); + // Create a second mint. const wrongMint = generateSigner(umi); await createV1(umi, { mint: wrongMint, @@ -178,8 +178,6 @@ test('it cannot set the wrong mint on a Mint Inscription account', async (t) => inscriptionAccount: inscriptionAccount[0], }); - // const asset = await fetchDigitalAsset(umi, mint.publicKey); - let builder = new TransactionBuilder(); // When we create a new account. @@ -189,7 +187,7 @@ test('it cannot set the wrong mint on a Mint Inscription account', async (t) => }) ); - // Set the mint on the account. + // It tries to set the mint to an invalid mint. builder = builder.append( setMint(umi, { mintInscriptionAccount: inscriptionAccount, @@ -200,6 +198,6 @@ test('it cannot set the wrong mint on a Mint Inscription account', async (t) => const promise = builder.sendAndConfirm(umi); - // Then an error is thrown. + // And it fails because the derivation from the wrong mint is invalid. await t.throwsAsync(promise, { name: 'DerivedKeyInvalid' }); }); diff --git a/clients/rust/src/generated/instructions/add_authority.rs b/clients/rust/src/generated/instructions/add_authority.rs index 73d6f7d..70116e0 100644 --- a/clients/rust/src/generated/instructions/add_authority.rs +++ b/clients/rust/src/generated/instructions/add_authority.rs @@ -13,7 +13,7 @@ use solana_program::pubkey::Pubkey; pub struct AddAuthority { /// The account to store the metadata's metadata in. pub inscription_metadata_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -110,7 +110,7 @@ impl AddAuthorityBuilder { self.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -180,7 +180,7 @@ impl AddAuthorityBuilder { pub struct AddAuthorityCpiAccounts<'a, 'b> { /// The account to store the metadata's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -194,7 +194,7 @@ pub struct AddAuthorityCpi<'a, 'b> { pub __program: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the metadata's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -339,7 +339,7 @@ impl<'a, 'b> AddAuthorityCpiBuilder<'a, 'b> { self.instruction.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/allocate.rs b/clients/rust/src/generated/instructions/allocate.rs index 4516307..d8937d5 100644 --- a/clients/rust/src/generated/instructions/allocate.rs +++ b/clients/rust/src/generated/instructions/allocate.rs @@ -14,7 +14,7 @@ pub struct Allocate { pub inscription_account: solana_program::pubkey::Pubkey, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -127,7 +127,7 @@ impl AllocateBuilder { self.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -206,7 +206,7 @@ pub struct AllocateCpiAccounts<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -222,7 +222,7 @@ pub struct AllocateCpi<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -384,7 +384,7 @@ impl<'a, 'b> AllocateCpiBuilder<'a, 'b> { self.instruction.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/clear_data.rs b/clients/rust/src/generated/instructions/clear_data.rs index 6ecf885..6e149c6 100644 --- a/clients/rust/src/generated/instructions/clear_data.rs +++ b/clients/rust/src/generated/instructions/clear_data.rs @@ -14,7 +14,7 @@ pub struct ClearData { pub inscription_account: solana_program::pubkey::Pubkey, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -125,7 +125,7 @@ impl ClearDataBuilder { self.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -198,7 +198,7 @@ pub struct ClearDataCpiAccounts<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -214,7 +214,7 @@ pub struct ClearDataCpi<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -375,7 +375,7 @@ impl<'a, 'b> ClearDataCpiBuilder<'a, 'b> { self.instruction.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/close.rs b/clients/rust/src/generated/instructions/close.rs index a3518b9..9480674 100644 --- a/clients/rust/src/generated/instructions/close.rs +++ b/clients/rust/src/generated/instructions/close.rs @@ -14,7 +14,7 @@ pub struct Close { pub inscription_account: solana_program::pubkey::Pubkey, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -125,7 +125,7 @@ impl CloseBuilder { self.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -198,7 +198,7 @@ pub struct CloseCpiAccounts<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -214,7 +214,7 @@ pub struct CloseCpi<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -375,7 +375,7 @@ impl<'a, 'b> CloseCpiBuilder<'a, 'b> { self.instruction.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/create_shard.rs b/clients/rust/src/generated/instructions/create_shard.rs index 5a639ce..e591da0 100644 --- a/clients/rust/src/generated/instructions/create_shard.rs +++ b/clients/rust/src/generated/instructions/create_shard.rs @@ -12,7 +12,7 @@ use borsh::BorshSerialize; pub struct CreateShard { /// The account to store the shard data in. pub shard_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// System program pub system_program: solana_program::pubkey::Pubkey, @@ -93,7 +93,7 @@ impl CreateShardBuilder { self.shard_account = Some(shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -150,7 +150,7 @@ impl CreateShardBuilder { pub struct CreateShardCpiAccounts<'a, 'b> { /// The account to store the shard data in. pub shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// System program pub system_program: &'b solana_program::account_info::AccountInfo<'a>, @@ -162,7 +162,7 @@ pub struct CreateShardCpi<'a, 'b> { pub __program: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the shard data in. pub shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// System program pub system_program: &'b solana_program::account_info::AccountInfo<'a>, @@ -289,7 +289,7 @@ impl<'a, 'b> CreateShardCpiBuilder<'a, 'b> { self.instruction.shard_account = Some(shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/initialize.rs b/clients/rust/src/generated/instructions/initialize.rs index ae2279d..48bd0ac 100644 --- a/clients/rust/src/generated/instructions/initialize.rs +++ b/clients/rust/src/generated/instructions/initialize.rs @@ -16,7 +16,7 @@ pub struct Initialize { pub inscription_metadata_account: solana_program::pubkey::Pubkey, /// The shard account for the inscription counter. pub inscription_shard_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -128,7 +128,7 @@ impl InitializeBuilder { self.inscription_shard_account = Some(inscription_shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -197,7 +197,7 @@ pub struct InitializeCpiAccounts<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The shard account for the inscription counter. pub inscription_shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -215,7 +215,7 @@ pub struct InitializeCpi<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The shard account for the inscription counter. pub inscription_shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -385,7 +385,7 @@ impl<'a, 'b> InitializeCpiBuilder<'a, 'b> { self.instruction.inscription_shard_account = Some(inscription_shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/initialize_associated_inscription.rs b/clients/rust/src/generated/instructions/initialize_associated_inscription.rs index 48367b5..187450f 100644 --- a/clients/rust/src/generated/instructions/initialize_associated_inscription.rs +++ b/clients/rust/src/generated/instructions/initialize_associated_inscription.rs @@ -16,7 +16,7 @@ pub struct InitializeAssociatedInscription { pub inscription_metadata_account: solana_program::pubkey::Pubkey, /// The account to create and store the new associated data in. pub associated_inscription_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -143,7 +143,7 @@ impl InitializeAssociatedInscriptionBuilder { self.associated_inscription_account = Some(associated_inscription_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -223,7 +223,7 @@ pub struct InitializeAssociatedInscriptionCpiAccounts<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to create and store the new associated data in. pub associated_inscription_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -241,7 +241,7 @@ pub struct InitializeAssociatedInscriptionCpi<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to create and store the new associated data in. pub associated_inscription_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -420,7 +420,7 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpiBuilder<'a, 'b> { self.instruction.associated_inscription_account = Some(associated_inscription_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/initialize_from_mint.rs b/clients/rust/src/generated/instructions/initialize_from_mint.rs index 70bfab1..cc38998 100644 --- a/clients/rust/src/generated/instructions/initialize_from_mint.rs +++ b/clients/rust/src/generated/instructions/initialize_from_mint.rs @@ -20,7 +20,7 @@ pub struct InitializeFromMint { pub token_metadata_account: solana_program::pubkey::Pubkey, /// The shard account for the inscription counter. pub inscription_shard_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -159,7 +159,7 @@ impl InitializeFromMintBuilder { self.inscription_shard_account = Some(inscription_shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -236,7 +236,7 @@ pub struct InitializeFromMintCpiAccounts<'a, 'b> { pub token_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The shard account for the inscription counter. pub inscription_shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -258,7 +258,7 @@ pub struct InitializeFromMintCpi<'a, 'b> { pub token_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The shard account for the inscription counter. pub inscription_shard_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -462,7 +462,7 @@ impl<'a, 'b> InitializeFromMintCpiBuilder<'a, 'b> { self.instruction.inscription_shard_account = Some(inscription_shard_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/set_mint.rs b/clients/rust/src/generated/instructions/set_mint.rs index 0584003..3afdb99 100644 --- a/clients/rust/src/generated/instructions/set_mint.rs +++ b/clients/rust/src/generated/instructions/set_mint.rs @@ -16,7 +16,7 @@ pub struct SetMint { pub inscription_metadata_account: solana_program::pubkey::Pubkey, /// The mint that will be used to derive the PDA. pub mint_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// System program pub system_program: solana_program::pubkey::Pubkey, @@ -112,7 +112,7 @@ impl SetMintBuilder { self.mint_account = Some(mint_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -171,7 +171,7 @@ pub struct SetMintCpiAccounts<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The mint that will be used to derive the PDA. pub mint_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// System program pub system_program: &'b solana_program::account_info::AccountInfo<'a>, @@ -187,7 +187,7 @@ pub struct SetMintCpi<'a, 'b> { pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, /// The mint that will be used to derive the PDA. pub mint_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// System program pub system_program: &'b solana_program::account_info::AccountInfo<'a>, @@ -339,7 +339,7 @@ impl<'a, 'b> SetMintCpiBuilder<'a, 'b> { self.instruction.mint_account = Some(mint_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/clients/rust/src/generated/instructions/write_data.rs b/clients/rust/src/generated/instructions/write_data.rs index a1da6b5..1c324b7 100644 --- a/clients/rust/src/generated/instructions/write_data.rs +++ b/clients/rust/src/generated/instructions/write_data.rs @@ -14,7 +14,7 @@ pub struct WriteData { pub inscription_account: solana_program::pubkey::Pubkey, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: solana_program::pubkey::Pubkey, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: solana_program::pubkey::Pubkey, /// The authority of the inscription account. pub authority: Option, @@ -129,7 +129,7 @@ impl WriteDataBuilder { self.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: solana_program::pubkey::Pubkey) -> &mut Self { self.payer = Some(payer); @@ -214,7 +214,7 @@ pub struct WriteDataCpiAccounts<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -230,7 +230,7 @@ pub struct WriteDataCpi<'a, 'b> { pub inscription_account: &'b solana_program::account_info::AccountInfo<'a>, /// The account to store the inscription account's metadata in. pub inscription_metadata_account: &'b solana_program::account_info::AccountInfo<'a>, - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. pub payer: &'b solana_program::account_info::AccountInfo<'a>, /// The authority of the inscription account. pub authority: Option<&'b solana_program::account_info::AccountInfo<'a>>, @@ -393,7 +393,7 @@ impl<'a, 'b> WriteDataCpiBuilder<'a, 'b> { self.instruction.inscription_metadata_account = Some(inscription_metadata_account); self } - /// The account that will pay for the transaction and rent. + /// The account that will pay for the rent. #[inline(always)] pub fn payer(&mut self, payer: &'b solana_program::account_info::AccountInfo<'a>) -> &mut Self { self.instruction.payer = Some(payer); diff --git a/idls/mpl_inscription.json b/idls/mpl_inscription.json index 8e16e77..85513e6 100644 --- a/idls/mpl_inscription.json +++ b/idls/mpl_inscription.json @@ -34,7 +34,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -109,7 +109,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -160,7 +160,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -218,7 +218,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -276,7 +276,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -326,7 +326,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -419,7 +419,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -476,7 +476,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -534,7 +534,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { @@ -600,7 +600,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account that will pay for the transaction and rent." + "The account that will pay for the rent." ] }, { diff --git a/programs/mpl-inscription/src/instruction/mod.rs b/programs/mpl-inscription/src/instruction/mod.rs index 47d95b1..c93d0c9 100644 --- a/programs/mpl-inscription/src/instruction/mod.rs +++ b/programs/mpl-inscription/src/instruction/mod.rs @@ -9,7 +9,7 @@ pub enum MplInscriptionInstruction { #[account(0, writable, signer, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] #[account(2, writable, name="inscription_shard_account", desc="The shard account for the inscription counter.")] - #[account(3, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(3, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(4, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(5, name="system_program", desc = "System program")] Initialize, @@ -20,7 +20,7 @@ pub enum MplInscriptionInstruction { #[account(2, name="mint_account", desc="The mint that will be used to derive the PDA.")] #[account(3, name="token_metadata_account", desc="The metadata for the mint.")] #[account(4, writable, name="inscription_shard_account", desc="The shard account for the inscription counter.")] - #[account(5, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(5, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(6, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(7, name="system_program", desc = "System program")] InitializeFromMint, @@ -28,7 +28,7 @@ pub enum MplInscriptionInstruction { /// Close the Inscription and Metadata accounts. #[account(0, writable, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] - #[account(2, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(2, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(4, name="system_program", desc = "System program")] Close(CloseArgs), @@ -36,7 +36,7 @@ pub enum MplInscriptionInstruction { /// Write data to the inscription account. #[account(0, writable, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] - #[account(2, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(2, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(4, name="system_program", desc = "System program")] WriteData(WriteDataArgs), @@ -44,14 +44,14 @@ pub enum MplInscriptionInstruction { /// Clear the inscription account. #[account(0, writable, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] - #[account(2, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(2, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(4, name="system_program", desc = "System program")] ClearData(ClearDataArgs), /// Add an update authority to the Inscription. #[account(0, writable, name="inscription_metadata_account", desc = "The account to store the metadata's metadata in.")] - #[account(1, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(1, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(2, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(3, name="system_program", desc = "System program")] AddAuthority(AddAuthorityArgs), @@ -65,7 +65,7 @@ pub enum MplInscriptionInstruction { /// Create an Inscription Shard account for counting inscriptions. #[account(0, writable, name="shard_account", desc = "The account to store the shard data in.")] - #[account(1, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(1, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(2, name="system_program", desc = "System program")] CreateShard(CreateShardArgs), @@ -73,7 +73,7 @@ pub enum MplInscriptionInstruction { #[account(0, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] #[account(2, writable, name="associated_inscription_account", desc = "The account to create and store the new associated data in.")] - #[account(3, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(3, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(4, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(5, name="system_program", desc = "System program")] InitializeAssociatedInscription(AssociateInscriptionAccountArgs), @@ -81,7 +81,7 @@ pub enum MplInscriptionInstruction { /// Allocate additional space for the inscription account. #[account(0, writable, name="inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] - #[account(2, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(2, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] #[account(4, name="system_program", desc = "System program")] Allocate(AllocateArgs), @@ -90,7 +90,7 @@ pub enum MplInscriptionInstruction { #[account(0, name="mint_inscription_account", desc = "The account where data is stored.")] #[account(1, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] #[account(2, name="mint_account", desc="The mint that will be used to derive the PDA.")] - #[account(3, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] + #[account(3, writable, signer, name="payer", desc="The account that will pay for the rent.")] #[account(4, name="system_program", desc = "System program")] SetMint, } diff --git a/programs/mpl-inscription/src/processor/set_mint.rs b/programs/mpl-inscription/src/processor/set_mint.rs index 21b43a9..2656ed2 100644 --- a/programs/mpl-inscription/src/processor/set_mint.rs +++ b/programs/mpl-inscription/src/processor/set_mint.rs @@ -16,6 +16,11 @@ use crate::{ pub(crate) fn process_set_mint<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramResult { let ctx = &SetMintAccounts::context(accounts)?; + // Check that the system program is correct. + if ctx.accounts.system_program.key != &solana_program::system_program::ID { + return Err(MplInscriptionError::InvalidSystemProgram.into()); + } + // Check that the account is already initialized. if ctx.accounts.mint_inscription_account.owner != &crate::ID { return Err(MplInscriptionError::NotInitialized.into()); @@ -34,7 +39,7 @@ pub(crate) fn process_set_mint<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramRe MplInscriptionError::IncorrectOwner, )?; - // Verify that the derived address is correct for the metadata account. + // Verify that the derived address is correct for the mint inscription account. let _inscription_bump = assert_derivation( &crate::ID, ctx.accounts.mint_inscription_account, @@ -60,7 +65,7 @@ pub(crate) fn process_set_mint<'a>(accounts: &'a [AccountInfo<'a>]) -> ProgramRe assert_signer(ctx.accounts.payer)?; - // Initialize the inscription metadata. + // Deserialize the inscription metadata. let mut inscription_metadata = InscriptionMetadata::try_from_slice( &ctx.accounts.inscription_metadata_account.data.borrow(), )?;