diff --git a/clients/js/package.json b/clients/js/package.json index d1a47cb..1f8d412 100644 --- a/clients/js/package.json +++ b/clients/js/package.json @@ -1,6 +1,6 @@ { "name": "@metaplex-foundation/mpl-inscription", - "version": "0.7.0", + "version": "0.8.0", "description": "A simple program for inscribing bytes on chain.", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", diff --git a/clients/js/src/generated/instructions/allocate.ts b/clients/js/src/generated/instructions/allocate.ts index 610ed69..8830362 100644 --- a/clients/js/src/generated/instructions/allocate.ts +++ b/clients/js/src/generated/instructions/allocate.ts @@ -33,7 +33,7 @@ import { // Accounts. export type AllocateInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/clearData.ts b/clients/js/src/generated/instructions/clearData.ts index c1163fe..46eb0ea 100644 --- a/clients/js/src/generated/instructions/clearData.ts +++ b/clients/js/src/generated/instructions/clearData.ts @@ -32,7 +32,7 @@ import { // Accounts. export type ClearDataInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/close.ts b/clients/js/src/generated/instructions/close.ts index b9fec99..106f2b9 100644 --- a/clients/js/src/generated/instructions/close.ts +++ b/clients/js/src/generated/instructions/close.ts @@ -32,7 +32,7 @@ import { // Accounts. export type CloseInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/initialize.ts b/clients/js/src/generated/instructions/initialize.ts index 09e0477..dcc44df 100644 --- a/clients/js/src/generated/instructions/initialize.ts +++ b/clients/js/src/generated/instructions/initialize.ts @@ -30,7 +30,7 @@ import { // Accounts. export type InitializeInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ inscriptionAccount: Signer; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount?: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/initializeAssociatedInscription.ts b/clients/js/src/generated/instructions/initializeAssociatedInscription.ts index 8de38e6..1b537a1 100644 --- a/clients/js/src/generated/instructions/initializeAssociatedInscription.ts +++ b/clients/js/src/generated/instructions/initializeAssociatedInscription.ts @@ -21,7 +21,10 @@ import { struct, u8, } from '@metaplex-foundation/umi/serializers'; -import { findAssociatedInscriptionAccountPda } from '../accounts'; +import { + findAssociatedInscriptionAccountPda, + findInscriptionMetadataPda, +} from '../accounts'; import { ResolvedAccount, ResolvedAccountsWithIndices, @@ -32,8 +35,10 @@ import { // Accounts. export type InitializeAssociatedInscriptionInstructionAccounts = { + /** The account where data is stored. */ + inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ - inscriptionMetadataAccount: PublicKey | Pda; + 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. */ @@ -95,20 +100,25 @@ export function initializeAssociatedInscription( // Accounts. const resolvedAccounts: ResolvedAccountsWithIndices = { - inscriptionMetadataAccount: { + inscriptionAccount: { index: 0, + isWritable: false, + value: input.inscriptionAccount ?? null, + }, + inscriptionMetadataAccount: { + index: 1, isWritable: true, value: input.inscriptionMetadataAccount ?? null, }, associatedInscriptionAccount: { - index: 1, + index: 2, isWritable: true, value: input.associatedInscriptionAccount ?? null, }, - payer: { index: 2, isWritable: true, value: input.payer ?? null }, - authority: { index: 3, isWritable: false, value: input.authority ?? null }, + payer: { index: 3, isWritable: true, value: input.payer ?? null }, + authority: { index: 4, isWritable: false, value: input.authority ?? null }, systemProgram: { - index: 4, + index: 5, isWritable: false, value: input.systemProgram ?? null, }, @@ -120,6 +130,14 @@ export function initializeAssociatedInscription( }; // Default values. + if (!resolvedAccounts.inscriptionMetadataAccount.value) { + resolvedAccounts.inscriptionMetadataAccount.value = + findInscriptionMetadataPda(context, { + inscriptionAccount: expectPublicKey( + resolvedAccounts.inscriptionAccount.value + ), + }); + } if (!resolvedAccounts.associatedInscriptionAccount.value) { resolvedAccounts.associatedInscriptionAccount.value = findAssociatedInscriptionAccountPda(context, { diff --git a/clients/js/src/generated/instructions/initializeFromMint.ts b/clients/js/src/generated/instructions/initializeFromMint.ts index 95b462d..7137f85 100644 --- a/clients/js/src/generated/instructions/initializeFromMint.ts +++ b/clients/js/src/generated/instructions/initializeFromMint.ts @@ -30,7 +30,7 @@ import { // Accounts. export type InitializeFromMintInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ mintInscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; diff --git a/clients/js/src/generated/instructions/writeData.ts b/clients/js/src/generated/instructions/writeData.ts index 936a749..b8ddda4 100644 --- a/clients/js/src/generated/instructions/writeData.ts +++ b/clients/js/src/generated/instructions/writeData.ts @@ -35,7 +35,7 @@ import { // Accounts. export type WriteDataInstructionAccounts = { - /** The account to store the metadata in. */ + /** The account where data is stored. */ inscriptionAccount: PublicKey | Pda; /** The account to store the inscription account's metadata in. */ inscriptionMetadataAccount: PublicKey | Pda; diff --git a/clients/js/test/clearData.test.ts b/clients/js/test/clearData.test.ts index 3519f3d..53a03b9 100644 --- a/clients/js/test/clearData.test.ts +++ b/clients/js/test/clearData.test.ts @@ -218,15 +218,14 @@ test('it can write Image data to an associated inscription account', async (t) = ); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); builder = builder.add( initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount.publicKey, + associationTag: 'image', }) ); @@ -242,11 +241,12 @@ test('it can write Image data to an associated inscription account', async (t) = const chunk = imageBytes.slice(i, i + chunkSize); // eslint-disable-next-line no-await-in-loop promises.push( + // eslint-disable-next-line no-await-in-loop await writeData(umi, { inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, value: chunk, - associatedTag: 'image/png', + associatedTag: 'image', offset: i, }).sendAndConfirm(umi, { confirm: { commitment: 'finalized' } }) ); @@ -257,7 +257,7 @@ test('it can write Image data to an associated inscription account', async (t) = await clearData(umi, { inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, - associatedTag: 'image/png', + associatedTag: 'image', }).sendAndConfirm(umi, { confirm: { commitment: 'finalized' } }); // Then an account was cleared with no remaining data. @@ -308,15 +308,14 @@ test('it can write Image data to an associated mint inscription account', async ); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); builder = builder.add( initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount[0], + associationTag: 'image', }) ); @@ -332,11 +331,12 @@ test('it can write Image data to an associated mint inscription account', async const chunk = imageBytes.slice(i, i + chunkSize); // eslint-disable-next-line no-await-in-loop promises.push( + // eslint-disable-next-line no-await-in-loop await writeData(umi, { inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, value: chunk, - associatedTag: 'image/png', + associatedTag: 'image', offset: i, }).sendAndConfirm(umi) ); diff --git a/clients/js/test/initializeAssocatedInscription.test.ts b/clients/js/test/initializeAssocatedInscription.test.ts index 03638b4..74507cd 100644 --- a/clients/js/test/initializeAssocatedInscription.test.ts +++ b/clients/js/test/initializeAssocatedInscription.test.ts @@ -53,15 +53,14 @@ test('it can initialize an Associated Inscription account', async (t) => { t.is(shardDataBefore.count + BigInt(1), shardDataAfter.count); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); // Create an Associated Inscription account. await initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - // associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount.publicKey, + associationTag: 'image', }).sendAndConfirm(umi); const inscriptionMetadata = await fetchInscriptionMetadata( @@ -78,7 +77,7 @@ test('it can initialize an Associated Inscription account', async (t) => { updateAuthorities: [umi.identity.publicKey], associatedInscriptions: [ { - tag: 'image/png', + tag: 'image', bump: associatedInscriptionAccount[1], dataType: DataType.Uninitialized, }, @@ -149,15 +148,14 @@ test('it can initialize an Associated Inscription account on a Mint', async (t) t.is(shardDataBefore.count + BigInt(1), shardDataAfter.count); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); // Create an Associated Inscription account. await initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - // associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount[0], + associationTag: 'image', }).sendAndConfirm(umi); const inscriptionMetadata = await fetchInscriptionMetadata( @@ -174,7 +172,7 @@ test('it can initialize an Associated Inscription account on a Mint', async (t) updateAuthorities: [umi.identity.publicKey], associatedInscriptions: [ { - tag: 'image/png', + tag: 'image', bump: associatedInscriptionAccount[1], dataType: DataType.Uninitialized, }, diff --git a/clients/js/test/writeData.test.ts b/clients/js/test/writeData.test.ts index 19a2e75..bd86195 100644 --- a/clients/js/test/writeData.test.ts +++ b/clients/js/test/writeData.test.ts @@ -283,15 +283,14 @@ test('it can write Image data to an associated inscription account', async (t) = ); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); builder = builder.add( initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount.publicKey, + associationTag: 'image', }) ); @@ -311,7 +310,7 @@ test('it can write Image data to an associated inscription account', async (t) = inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, value: chunk, - associatedTag: 'image/png', + associatedTag: 'image', offset: i, }).sendAndConfirm(umi) ); @@ -366,15 +365,14 @@ test('it can write Image data to an associated mint inscription account', async ); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); builder = builder.add( initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount[0], + associationTag: 'image', }) ); @@ -394,7 +392,7 @@ test('it can write Image data to an associated mint inscription account', async inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, value: chunk, - associatedTag: 'image/png', + associatedTag: 'image', offset: i, }).sendAndConfirm(umi) ); @@ -432,15 +430,14 @@ test('it can write Image data to an associated inscription account, with preallo ); const associatedInscriptionAccount = findAssociatedInscriptionPda(umi, { - associated_tag: 'image/png', + associated_tag: 'image', inscriptionMetadataAccount, }); builder = builder.add( initializeAssociatedInscription(umi, { - inscriptionMetadataAccount, - associatedInscriptionAccount, - associationTag: 'image/png', + inscriptionAccount: inscriptionAccount.publicKey, + associationTag: 'image', }) ); @@ -454,7 +451,7 @@ test('it can write Image data to an associated inscription account, with preallo await allocate(umi, { inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, - associatedTag: 'image/png', + associatedTag: 'image', targetSize: imageBytes.length, }).sendAndConfirm(umi); } @@ -477,7 +474,7 @@ test('it can write Image data to an associated inscription account, with preallo inscriptionAccount: associatedInscriptionAccount, inscriptionMetadataAccount, value: chunk, - associatedTag: 'image/png', + associatedTag: 'image', offset: i, }).sendAndConfirm(umi) ); diff --git a/clients/rust/src/generated/instructions/allocate.rs b/clients/rust/src/generated/instructions/allocate.rs index 5047bd4..4516307 100644 --- a/clients/rust/src/generated/instructions/allocate.rs +++ b/clients/rust/src/generated/instructions/allocate.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct Allocate { - /// The account to store the metadata in. + /// The account where data is stored. 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, @@ -109,7 +109,7 @@ impl AllocateBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, @@ -202,7 +202,7 @@ impl AllocateBuilder { /// `allocate` CPI accounts. pub struct AllocateCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -218,7 +218,7 @@ pub struct AllocateCpiAccounts<'a, 'b> { pub struct AllocateCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -366,7 +366,7 @@ impl<'a, 'b> AllocateCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, diff --git a/clients/rust/src/generated/instructions/clear_data.rs b/clients/rust/src/generated/instructions/clear_data.rs index f3d3969..6ecf885 100644 --- a/clients/rust/src/generated/instructions/clear_data.rs +++ b/clients/rust/src/generated/instructions/clear_data.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct ClearData { - /// The account to store the metadata in. + /// The account where data is stored. 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, @@ -107,7 +107,7 @@ impl ClearDataBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, @@ -194,7 +194,7 @@ impl ClearDataBuilder { /// `clear_data` CPI accounts. pub struct ClearDataCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -210,7 +210,7 @@ pub struct ClearDataCpiAccounts<'a, 'b> { pub struct ClearDataCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -357,7 +357,7 @@ impl<'a, 'b> ClearDataCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, diff --git a/clients/rust/src/generated/instructions/close.rs b/clients/rust/src/generated/instructions/close.rs index 3f2b602..a3518b9 100644 --- a/clients/rust/src/generated/instructions/close.rs +++ b/clients/rust/src/generated/instructions/close.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct Close { - /// The account to store the metadata in. + /// The account where data is stored. 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, @@ -107,7 +107,7 @@ impl CloseBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, @@ -194,7 +194,7 @@ impl CloseBuilder { /// `close` CPI accounts. pub struct CloseCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -210,7 +210,7 @@ pub struct CloseCpiAccounts<'a, 'b> { pub struct CloseCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -357,7 +357,7 @@ impl<'a, 'b> CloseCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, diff --git a/clients/rust/src/generated/instructions/initialize.rs b/clients/rust/src/generated/instructions/initialize.rs index 3f0c234..ae2279d 100644 --- a/clients/rust/src/generated/instructions/initialize.rs +++ b/clients/rust/src/generated/instructions/initialize.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct Initialize { - /// The account to store the metadata in. + /// The account where data is stored. 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, @@ -101,7 +101,7 @@ impl InitializeBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, @@ -191,7 +191,7 @@ impl InitializeBuilder { /// `initialize` CPI accounts. pub struct InitializeCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -209,7 +209,7 @@ pub struct InitializeCpiAccounts<'a, 'b> { pub struct InitializeCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -358,7 +358,7 @@ impl<'a, 'b> InitializeCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, diff --git a/clients/rust/src/generated/instructions/initialize_associated_inscription.rs b/clients/rust/src/generated/instructions/initialize_associated_inscription.rs index 839462c..48367b5 100644 --- a/clients/rust/src/generated/instructions/initialize_associated_inscription.rs +++ b/clients/rust/src/generated/instructions/initialize_associated_inscription.rs @@ -10,6 +10,8 @@ use borsh::BorshSerialize; /// Accounts. pub struct InitializeAssociatedInscription { + /// The account where data is stored. + 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 to create and store the new associated data in. @@ -35,7 +37,11 @@ impl InitializeAssociatedInscription { args: InitializeAssociatedInscriptionInstructionArgs, remaining_accounts: &[solana_program::instruction::AccountMeta], ) -> solana_program::instruction::Instruction { - let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + self.inscription_account, + false, + )); accounts.push(solana_program::instruction::AccountMeta::new( self.inscription_metadata_account, false, @@ -96,6 +102,7 @@ pub struct InitializeAssociatedInscriptionInstructionArgs { /// Instruction builder. #[derive(Default)] pub struct InitializeAssociatedInscriptionBuilder { + inscription_account: Option, inscription_metadata_account: Option, associated_inscription_account: Option, payer: Option, @@ -109,6 +116,15 @@ impl InitializeAssociatedInscriptionBuilder { pub fn new() -> Self { Self::default() } + /// The account where data is stored. + #[inline(always)] + pub fn inscription_account( + &mut self, + inscription_account: solana_program::pubkey::Pubkey, + ) -> &mut Self { + self.inscription_account = Some(inscription_account); + self + } /// The account to store the inscription account's metadata in. #[inline(always)] pub fn inscription_metadata_account( @@ -173,6 +189,9 @@ impl InitializeAssociatedInscriptionBuilder { #[allow(clippy::clone_on_copy)] pub fn instruction(&self) -> solana_program::instruction::Instruction { let accounts = InitializeAssociatedInscription { + inscription_account: self + .inscription_account + .expect("inscription_account is not set"), inscription_metadata_account: self .inscription_metadata_account .expect("inscription_metadata_account is not set"), @@ -198,6 +217,8 @@ impl InitializeAssociatedInscriptionBuilder { /// `initialize_associated_inscription` CPI accounts. pub struct InitializeAssociatedInscriptionCpiAccounts<'a, 'b> { + /// The account where data is stored. + 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 to create and store the new associated data in. @@ -214,6 +235,8 @@ pub struct InitializeAssociatedInscriptionCpiAccounts<'a, 'b> { pub struct InitializeAssociatedInscriptionCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, + /// The account where data is stored. + 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 to create and store the new associated data in. @@ -236,6 +259,7 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpi<'a, 'b> { ) -> Self { Self { __program: program, + inscription_account: accounts.inscription_account, inscription_metadata_account: accounts.inscription_metadata_account, associated_inscription_account: accounts.associated_inscription_account, payer: accounts.payer, @@ -277,7 +301,11 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpi<'a, 'b> { bool, )], ) -> solana_program::entrypoint::ProgramResult { - let mut accounts = Vec::with_capacity(5 + remaining_accounts.len()); + let mut accounts = Vec::with_capacity(6 + remaining_accounts.len()); + accounts.push(solana_program::instruction::AccountMeta::new_readonly( + *self.inscription_account.key, + false, + )); accounts.push(solana_program::instruction::AccountMeta::new( *self.inscription_metadata_account.key, false, @@ -323,8 +351,9 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpi<'a, 'b> { accounts, data, }; - let mut account_infos = Vec::with_capacity(5 + 1 + remaining_accounts.len()); + let mut account_infos = Vec::with_capacity(6 + 1 + remaining_accounts.len()); account_infos.push(self.__program.clone()); + account_infos.push(self.inscription_account.clone()); account_infos.push(self.inscription_metadata_account.clone()); account_infos.push(self.associated_inscription_account.clone()); account_infos.push(self.payer.clone()); @@ -353,6 +382,7 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpiBuilder<'a, 'b> { pub fn new(program: &'b solana_program::account_info::AccountInfo<'a>) -> Self { let instruction = Box::new(InitializeAssociatedInscriptionCpiBuilderInstruction { __program: program, + inscription_account: None, inscription_metadata_account: None, associated_inscription_account: None, payer: None, @@ -363,6 +393,15 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpiBuilder<'a, 'b> { }); Self { instruction } } + /// The account where data is stored. + #[inline(always)] + pub fn inscription_account( + &mut self, + inscription_account: &'b solana_program::account_info::AccountInfo<'a>, + ) -> &mut Self { + self.instruction.inscription_account = Some(inscription_account); + self + } /// The account to store the inscription account's metadata in. #[inline(always)] pub fn inscription_metadata_account( @@ -462,6 +501,11 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpiBuilder<'a, 'b> { let instruction = InitializeAssociatedInscriptionCpi { __program: self.instruction.__program, + inscription_account: self + .instruction + .inscription_account + .expect("inscription_account is not set"), + inscription_metadata_account: self .instruction .inscription_metadata_account @@ -491,6 +535,7 @@ impl<'a, 'b> InitializeAssociatedInscriptionCpiBuilder<'a, 'b> { struct InitializeAssociatedInscriptionCpiBuilderInstruction<'a, 'b> { __program: &'b solana_program::account_info::AccountInfo<'a>, + inscription_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, inscription_metadata_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, associated_inscription_account: Option<&'b solana_program::account_info::AccountInfo<'a>>, payer: Option<&'b solana_program::account_info::AccountInfo<'a>>, diff --git a/clients/rust/src/generated/instructions/initialize_from_mint.rs b/clients/rust/src/generated/instructions/initialize_from_mint.rs index a255044..70bfab1 100644 --- a/clients/rust/src/generated/instructions/initialize_from_mint.rs +++ b/clients/rust/src/generated/instructions/initialize_from_mint.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct InitializeFromMint { - /// The account to store the metadata in. + /// 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, @@ -117,7 +117,7 @@ impl InitializeFromMintBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn mint_inscription_account( &mut self, @@ -226,7 +226,7 @@ impl InitializeFromMintBuilder { /// `initialize_from_mint` CPI accounts. pub struct InitializeFromMintCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// 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>, @@ -248,7 +248,7 @@ pub struct InitializeFromMintCpiAccounts<'a, 'b> { pub struct InitializeFromMintCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// 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>, @@ -417,7 +417,7 @@ impl<'a, 'b> InitializeFromMintCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn mint_inscription_account( &mut self, diff --git a/clients/rust/src/generated/instructions/write_data.rs b/clients/rust/src/generated/instructions/write_data.rs index 2f3b979..a1da6b5 100644 --- a/clients/rust/src/generated/instructions/write_data.rs +++ b/clients/rust/src/generated/instructions/write_data.rs @@ -10,7 +10,7 @@ use borsh::BorshSerialize; /// Accounts. pub struct WriteData { - /// The account to store the metadata in. + /// The account where data is stored. 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, @@ -111,7 +111,7 @@ impl WriteDataBuilder { pub fn new() -> Self { Self::default() } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, @@ -210,7 +210,7 @@ impl WriteDataBuilder { /// `write_data` CPI accounts. pub struct WriteDataCpiAccounts<'a, 'b> { - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -226,7 +226,7 @@ pub struct WriteDataCpiAccounts<'a, 'b> { pub struct WriteDataCpi<'a, 'b> { /// The program to invoke. pub __program: &'b solana_program::account_info::AccountInfo<'a>, - /// The account to store the metadata in. + /// The account where data is stored. 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>, @@ -375,7 +375,7 @@ impl<'a, 'b> WriteDataCpiBuilder<'a, 'b> { }); Self { instruction } } - /// The account to store the metadata in. + /// The account where data is stored. #[inline(always)] pub fn inscription_account( &mut self, diff --git a/configs/kinobi.cjs b/configs/kinobi.cjs index 457fcb8..db6eff7 100755 --- a/configs/kinobi.cjs +++ b/configs/kinobi.cjs @@ -116,6 +116,12 @@ kinobi.update( instruction: "initialize", ...k.pdaDefault("inscriptionMetadata"), }, + { + account: "inscriptionMetadataAccount", + ignoreIfOptional: true, + instruction: "initializeAssociatedInscription", + ...k.pdaDefault("inscriptionMetadata"), + }, { account: "tokenMetadataAccount", ignoreIfOptional: true, diff --git a/idls/mpl_inscription.json b/idls/mpl_inscription.json index 6e9e769..69d8e41 100644 --- a/idls/mpl_inscription.json +++ b/idls/mpl_inscription.json @@ -10,7 +10,7 @@ "isMut": true, "isSigner": true, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { @@ -69,7 +69,7 @@ "isMut": true, "isSigner": false, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { @@ -144,7 +144,7 @@ "isMut": true, "isSigner": false, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { @@ -202,7 +202,7 @@ "isMut": true, "isSigner": false, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { @@ -260,7 +260,7 @@ "isMut": true, "isSigner": false, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { @@ -447,6 +447,14 @@ { "name": "InitializeAssociatedInscription", "accounts": [ + { + "name": "inscriptionAccount", + "isMut": false, + "isSigner": false, + "docs": [ + "The account where data is stored." + ] + }, { "name": "inscriptionMetadataAccount", "isMut": true, @@ -510,7 +518,7 @@ "isMut": true, "isSigner": false, "docs": [ - "The account to store the metadata in." + "The account where data is stored." ] }, { diff --git a/programs/mpl-inscription/src/instruction/mod.rs b/programs/mpl-inscription/src/instruction/mod.rs index 552ea3d..ead117c 100644 --- a/programs/mpl-inscription/src/instruction/mod.rs +++ b/programs/mpl-inscription/src/instruction/mod.rs @@ -6,7 +6,7 @@ use solana_program::pubkey::Pubkey; #[rustfmt::skip] pub enum MplInscriptionInstruction { /// Initialize the Inscription and Metadata accounts. - #[account(0, writable, signer, name="inscription_account", desc = "The account to store the metadata in.")] + #[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.")] @@ -15,7 +15,7 @@ pub enum MplInscriptionInstruction { Initialize, /// Initialize the Inscription and Metadata accounts as a Mint PDA. - #[account(0, writable, name="mint_inscription_account", desc = "The account to store the metadata in.")] + #[account(0, writable, 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, name="token_metadata_account", desc="The metadata for the mint.")] @@ -26,7 +26,7 @@ pub enum MplInscriptionInstruction { InitializeFromMint, /// Close the Inscription and Metadata accounts. - #[account(0, writable, name="inscription_account", desc = "The account to store the metadata in.")] + #[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(3, optional, signer, name="authority", desc="The authority of the inscription account.")] @@ -34,7 +34,7 @@ pub enum MplInscriptionInstruction { Close(CloseArgs), /// Write data to the inscription account. - #[account(0, writable, name="inscription_account", desc = "The account to store the metadata in.")] + #[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(3, optional, signer, name="authority", desc="The authority of the inscription account.")] @@ -42,7 +42,7 @@ pub enum MplInscriptionInstruction { WriteData(WriteDataArgs), /// Clear the inscription account. - #[account(0, writable, name="inscription_account", desc = "The account to store the metadata in.")] + #[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(3, optional, signer, name="authority", desc="The authority of the inscription account.")] @@ -70,15 +70,16 @@ pub enum MplInscriptionInstruction { CreateShard(CreateShardArgs), /// Initialize the Inscription and Metadata accounts. - #[account(0, writable, name="inscription_metadata_account", desc = "The account to store the inscription account's metadata in.")] - #[account(1, writable, name="associated_inscription_account", desc = "The account to create and store the new associated data in.")] - #[account(2, writable, signer, name="payer", desc="The account that will pay for the transaction and rent.")] - #[account(3, optional, signer, name="authority", desc="The authority of the inscription account.")] - #[account(4, name="system_program", desc = "System program")] + #[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(4, optional, signer, name="authority", desc="The authority of the inscription account.")] + #[account(5, name="system_program", desc = "System program")] InitializeAssociatedInscription(AssociateInscriptionAccountArgs), /// Allocate additional space for the inscription account. - #[account(0, writable, name="inscription_account", desc = "The account to store the metadata in.")] + #[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(3, optional, signer, name="authority", desc="The authority of the inscription account.")] diff --git a/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs b/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs index 6663b4a..2227871 100644 --- a/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs +++ b/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs @@ -1,6 +1,6 @@ use borsh::{BorshDeserialize, BorshSerialize}; use mpl_utils::{ - assert_derivation, assert_signer, create_or_allocate_account_raw, + assert_derivation, assert_owned_by, assert_signer, create_or_allocate_account_raw, resize_or_reallocate_account_raw, }; use solana_program::{ @@ -22,6 +22,12 @@ pub(crate) fn process_initialize_associated_inscription<'a>( ) -> ProgramResult { let ctx = &InitializeAssociatedInscriptionAccounts::context(accounts)?; + assert_owned_by( + ctx.accounts.inscription_account, + &crate::ID, + MplInscriptionError::IncorrectOwner, + )?; + // Check that the account isn't already initialized. if (ctx.accounts.associated_inscription_account.owner != &system_program::ID) || !ctx.accounts.associated_inscription_account.data_is_empty() @@ -46,11 +52,21 @@ pub(crate) fn process_initialize_associated_inscription<'a>( &[ PREFIX.as_bytes(), crate::ID.as_ref(), - inscription_metadata.inscription_account.as_ref(), + ctx.accounts.inscription_account.key.as_ref(), ], MplInscriptionError::DerivedKeyInvalid, )?; + // We don't allow empty tags. + if args.association_tag.is_empty() { + return Err(MplInscriptionError::AssociationTagCannotBeBlank.into()); + } + + // A tag can't be greater than the seed size. + if args.association_tag.len() > 32 { + return Err(MplInscriptionError::AssociationTagTooLong.into()); + } + // Verify that the derived address is correct for the metadata account. let inscription_bump = assert_derivation( &crate::ID,