From a9d17e0ce03e3887c4ac89b6b5b01a7cbfa8b034 Mon Sep 17 00:00:00 2001 From: blockiosaurus Date: Wed, 10 Jan 2024 06:37:29 -0500 Subject: [PATCH] Adding inscription account and extra PDA check. --- .../generated/accounts/inscriptionMetadata.ts | 18 ++++++++++++++---- clients/js/test/initialize.test.ts | 3 +++ clients/js/test/initializeFromMint.test.ts | 2 ++ .../generated/accounts/inscription_metadata.rs | 6 ++++++ idls/mpl_inscription.json | 13 +++++++++++++ .../src/processor/initialize.rs | 1 + .../initialize_associated_inscription.rs | 11 +++++++++++ .../src/processor/initialize_from_mint.rs | 1 + programs/mpl-inscription/src/state.rs | 4 ++++ 9 files changed, 55 insertions(+), 4 deletions(-) diff --git a/clients/js/src/generated/accounts/inscriptionMetadata.ts b/clients/js/src/generated/accounts/inscriptionMetadata.ts index 68ad0e0..164e969 100644 --- a/clients/js/src/generated/accounts/inscriptionMetadata.ts +++ b/clients/js/src/generated/accounts/inscriptionMetadata.ts @@ -47,22 +47,26 @@ export type InscriptionMetadata = Account; export type InscriptionMetadataAccountData = { key: Key; + inscriptionAccount: PublicKey; bump: number; dataType: DataType; inscriptionRank: bigint; inscriptionBump: Option; updateAuthorities: Array; associatedInscriptions: Array; + padding: Array; }; export type InscriptionMetadataAccountDataArgs = { key: KeyArgs; + inscriptionAccount: PublicKey; bump: number; dataType: DataTypeArgs; inscriptionRank: number | bigint; inscriptionBump: OptionOrNullable; updateAuthorities: Array; associatedInscriptions: Array; + padding: Array; }; export function getInscriptionMetadataAccountDataSerializer(): Serializer< @@ -72,12 +76,14 @@ export function getInscriptionMetadataAccountDataSerializer(): Serializer< return struct( [ ['key', getKeySerializer()], + ['inscriptionAccount', publicKeySerializer()], ['bump', u8()], ['dataType', getDataTypeSerializer()], ['inscriptionRank', u64()], ['inscriptionBump', option(u8())], ['updateAuthorities', array(publicKeySerializer())], ['associatedInscriptions', array(getAssociatedInscriptionSerializer())], + ['padding', array(u8(), { size: 8 })], ], { description: 'InscriptionMetadataAccountData' } ) as Serializer< @@ -163,23 +169,27 @@ export function getInscriptionMetadataGpaBuilder( return gpaBuilder(context, programId) .registerFields<{ key: KeyArgs; + inscriptionAccount: PublicKey; bump: number; dataType: DataTypeArgs; inscriptionRank: number | bigint; inscriptionBump: OptionOrNullable; updateAuthorities: Array; associatedInscriptions: Array; + padding: Array; }>({ key: [0, getKeySerializer()], - bump: [1, u8()], - dataType: [2, getDataTypeSerializer()], - inscriptionRank: [3, u64()], - inscriptionBump: [11, option(u8())], + inscriptionAccount: [1, publicKeySerializer()], + bump: [33, u8()], + dataType: [34, getDataTypeSerializer()], + inscriptionRank: [35, u64()], + inscriptionBump: [43, option(u8())], updateAuthorities: [null, array(publicKeySerializer())], associatedInscriptions: [ null, array(getAssociatedInscriptionSerializer()), ], + padding: [null, array(u8(), { size: 8 })], }) .deserializeUsing((account) => deserializeInscriptionMetadata(account) diff --git a/clients/js/test/initialize.test.ts b/clients/js/test/initialize.test.ts index 57fd753..1b36d84 100644 --- a/clients/js/test/initialize.test.ts +++ b/clients/js/test/initialize.test.ts @@ -52,6 +52,7 @@ test('it can initialize an Inscription account', async (t) => { t.like(inscriptionMetadata, { key: Key.InscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount.publicKey, bump: inscriptionMetadataAccount[1], dataType: DataType.Uninitialized, inscriptionRank: @@ -111,6 +112,7 @@ test('it can initialize multiple Inscription accounts', async (t) => { t.like(inscriptionMetadata, { key: Key.InscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount[i].publicKey, bump: inscriptionMetadataAccount[1], dataType: DataType.Uninitialized, inscriptionRank: @@ -169,6 +171,7 @@ test('it can initialize an Inscription account with separate authority', async ( t.like(inscriptionMetadata, { key: Key.InscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount.publicKey, bump: inscriptionMetadataAccount[1], dataType: DataType.Uninitialized, inscriptionRank: diff --git a/clients/js/test/initializeFromMint.test.ts b/clients/js/test/initializeFromMint.test.ts index 7491933..5bae96f 100644 --- a/clients/js/test/initializeFromMint.test.ts +++ b/clients/js/test/initializeFromMint.test.ts @@ -77,6 +77,7 @@ test('it can initialize a Mint Inscription account', async (t) => { t.like(inscriptionMetadata, { key: Key.MintInscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount[0], bump: inscriptionMetadataAccount[1], dataType: DataType.Uninitialized, inscriptionRank: @@ -200,6 +201,7 @@ test('it can initialize a Mint Inscription account with separate authority', asy t.like(inscriptionMetadata, { key: Key.MintInscriptionMetadataAccount, + inscriptionAccount: inscriptionAccount[0], bump: inscriptionMetadataAccount[1], dataType: DataType.Uninitialized, inscriptionRank: diff --git a/clients/rust/src/generated/accounts/inscription_metadata.rs b/clients/rust/src/generated/accounts/inscription_metadata.rs index c59e609..24b05b7 100644 --- a/clients/rust/src/generated/accounts/inscription_metadata.rs +++ b/clients/rust/src/generated/accounts/inscription_metadata.rs @@ -16,12 +16,18 @@ use solana_program::pubkey::Pubkey; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct InscriptionMetadata { pub key: Key, + #[cfg_attr( + feature = "serde", + serde(with = "serde_with::As::") + )] + pub inscription_account: Pubkey, pub bump: u8, pub data_type: DataType, pub inscription_rank: u64, pub inscription_bump: Option, pub update_authorities: Vec, pub associated_inscriptions: Vec, + pub padding: [u8; 8], } impl InscriptionMetadata { diff --git a/idls/mpl_inscription.json b/idls/mpl_inscription.json index de8fb2e..6e9e769 100644 --- a/idls/mpl_inscription.json +++ b/idls/mpl_inscription.json @@ -573,6 +573,10 @@ "defined": "Key" } }, + { + "name": "inscriptionAccount", + "type": "publicKey" + }, { "name": "bump", "type": "u8" @@ -606,6 +610,15 @@ "defined": "AssociatedInscription" } } + }, + { + "name": "padding", + "type": { + "array": [ + "u8", + 8 + ] + } } ] } diff --git a/programs/mpl-inscription/src/processor/initialize.rs b/programs/mpl-inscription/src/processor/initialize.rs index 31595dd..33ba8fb 100644 --- a/programs/mpl-inscription/src/processor/initialize.rs +++ b/programs/mpl-inscription/src/processor/initialize.rs @@ -73,6 +73,7 @@ pub(crate) fn process_initialize<'a>(accounts: &'a [AccountInfo<'a>]) -> Program // Initialize the inscription metadata. let mut inscription_metadata = InscriptionMetadata { + inscription_account: *ctx.accounts.inscription_account.key, bump, update_authorities: vec![*authority.key], ..InscriptionMetadata::default() diff --git a/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs b/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs index 53e7cdc..6663b4a 100644 --- a/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs +++ b/programs/mpl-inscription/src/processor/initialize_associated_inscription.rs @@ -40,6 +40,17 @@ pub(crate) fn process_initialize_associated_inscription<'a>( &ctx.accounts.inscription_metadata_account.data.borrow(), )?; + let _metadata_bump = assert_derivation( + &crate::ID, + ctx.accounts.inscription_metadata_account, + &[ + PREFIX.as_bytes(), + crate::ID.as_ref(), + inscription_metadata.inscription_account.as_ref(), + ], + MplInscriptionError::DerivedKeyInvalid, + )?; + // Verify that the derived address is correct for the metadata account. let inscription_bump = assert_derivation( &crate::ID, diff --git a/programs/mpl-inscription/src/processor/initialize_from_mint.rs b/programs/mpl-inscription/src/processor/initialize_from_mint.rs index 9f0a2f2..11bc327 100644 --- a/programs/mpl-inscription/src/processor/initialize_from_mint.rs +++ b/programs/mpl-inscription/src/processor/initialize_from_mint.rs @@ -111,6 +111,7 @@ pub(crate) fn process_initialize_from_mint<'a>(accounts: &'a [AccountInfo<'a>]) // Initialize the inscription metadata. let mut inscription_metadata = InscriptionMetadata { key: Key::MintInscriptionMetadataAccount, + inscription_account: *ctx.accounts.mint_inscription_account.key, bump, inscription_bump: Some(inscription_bump), update_authorities: vec![token_metadata.update_authority], diff --git a/programs/mpl-inscription/src/state.rs b/programs/mpl-inscription/src/state.rs index 086d630..bda47b6 100644 --- a/programs/mpl-inscription/src/state.rs +++ b/programs/mpl-inscription/src/state.rs @@ -36,24 +36,28 @@ pub struct AssociatedInscription { #[derive(Clone, BorshSerialize, BorshDeserialize, Debug, ShankAccount)] pub struct InscriptionMetadata { pub key: Key, + pub inscription_account: Pubkey, pub bump: u8, pub data_type: DataType, pub inscription_rank: u64, pub inscription_bump: Option, pub update_authorities: Vec, pub associated_inscriptions: Vec, + pub _padding: [u8; 8], } impl Default for InscriptionMetadata { fn default() -> Self { Self { key: Key::InscriptionMetadataAccount, + inscription_account: Pubkey::default(), bump: 0, data_type: DataType::Uninitialized, inscription_rank: u64::MAX, inscription_bump: None, update_authorities: vec![], associated_inscriptions: vec![], + _padding: [0; 8], } } }