diff --git a/Cargo.lock b/Cargo.lock index 7a42d16da..5581c198a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1029,44 +1029,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "mpl-token-auth-rules" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a14e1ac5350734fd07f17d7eab733d27b7b45ca963642c565ec34ab015d9ceda" -dependencies = [ - "borsh", - "mpl-token-metadata-context-derive", - "num-derive", - "num-traits", - "rmp-serde", - "serde", - "shank 0.0.11", - "solana-program", - "solana-zk-token-sdk", - "thiserror", -] - -[[package]] -name = "mpl-token-metadata" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b20f44c87498baa14d504da1098da105cc1ddbb1adb7411fd60e8949c2b901" -dependencies = [ - "arrayref", - "borsh", - "mpl-token-auth-rules", - "mpl-token-metadata-context-derive", - "mpl-utils 0.0.6", - "num-derive", - "num-traits", - "shank 0.0.11", - "solana-program", - "spl-associated-token-account", - "spl-token", - "thiserror", -] - [[package]] name = "mpl-token-metadata" version = "3.0.1" @@ -1080,28 +1042,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "mpl-token-metadata-context-derive" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12989bc45715b0ee91944855130131479f9c772e198a910c3eb0ea327d5bffc3" -dependencies = [ - "quote", - "syn 1.0.107", -] - -[[package]] -name = "mpl-utils" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6195ce98b92f1d0ea06d0cc9b2392d81673e02b8fb063589926fa73ee6b071a" -dependencies = [ - "arrayref", - "borsh", - "solana-program", - "spl-token", -] - [[package]] name = "mpl-utils" version = "0.3.2" @@ -1209,12 +1149,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "paste" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" - [[package]] name = "pbkdf2" version = "0.4.0" @@ -1484,28 +1418,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rmp" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b13be192e0220b8afb7222aa5813cb62cc269ebb5cac346ca6487681d2913e" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -1649,16 +1561,7 @@ version = "0.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a9986b297e6f42bcbe41f95ca2a881e7a75bd091549e95ecf495fa8178c0c1b" dependencies = [ - "shank_macro 0.0.5", -] - -[[package]] -name = "shank" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63e565b5e95ad88ab38f312e89444c749360641c509ef2de0093b49f55974a5" -dependencies = [ - "shank_macro 0.0.11", + "shank_macro", ] [[package]] @@ -1669,19 +1572,7 @@ checksum = "5dd835154aa943dfc958f5a208f2e82b7d2a2c52b024229168c211ecc2d2bfd1" dependencies = [ "proc-macro2", "quote", - "shank_macro_impl 0.0.5", - "syn 1.0.107", -] - -[[package]] -name = "shank_macro" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63927d22a1e8b74bda98cc6e151fcdf178b7abb0dc6c4f81e0bbf5ffe2fc4ec8" -dependencies = [ - "proc-macro2", - "quote", - "shank_macro_impl 0.0.11", + "shank_macro_impl", "syn 1.0.107", ] @@ -1698,19 +1589,6 @@ dependencies = [ "syn 1.0.107", ] -[[package]] -name = "shank_macro_impl" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce03403df682f80f4dc1efafa87a4d0cb89b03726d0565e6364bdca5b9a441" -dependencies = [ - "anyhow", - "proc-macro2", - "quote", - "serde", - "syn 1.0.107", -] - [[package]] name = "signature" version = "1.6.4" @@ -1803,7 +1681,7 @@ dependencies = [ "num-derive", "num-traits", "sha2 0.9.9", - "shank 0.0.5", + "shank", "solana-program", "solana-security-txt", "spl-associated-token-account", @@ -1833,8 +1711,8 @@ checksum = "32a24ad4fffd1ac93df6bebb188f8838fbf99d75fdf397f36f53498b8deb2134" dependencies = [ "anchor-lang", "anchor-spl", - "mpl-token-metadata 3.0.1", - "mpl-utils 0.3.2", + "mpl-token-metadata", + "mpl-utils", "solana-program", "spl-associated-token-account", "spl-token", @@ -1860,7 +1738,8 @@ version = "1.0.0" dependencies = [ "anchor-lang", "anchor-spl", - "mpl-token-metadata 1.8.0", + "mpl-token-metadata", + "mpl-utils", "proptest", "solana-nft-programs-creator-standard", "solana-program", @@ -1874,7 +1753,8 @@ version = "1.0.0" dependencies = [ "anchor-lang", "anchor-spl", - "mpl-token-metadata 1.8.0", + "mpl-token-metadata", + "mpl-utils", "proptest", "solana-nft-programs-payment-manager", "solana-nft-programs-token-manager", @@ -1890,7 +1770,8 @@ dependencies = [ "anchor-lang", "anchor-spl", "arrayref", - "mpl-token-metadata 1.8.0", + "mpl-token-metadata", + "mpl-utils", "proptest", "solana-nft-programs-payment-manager", "solana-nft-programs-token-manager", diff --git a/programs/solana-nft-programs-token-manager/Cargo.toml b/programs/solana-nft-programs-token-manager/Cargo.toml index 41e65864e..acb8b4d45 100644 --- a/programs/solana-nft-programs-token-manager/Cargo.toml +++ b/programs/solana-nft-programs-token-manager/Cargo.toml @@ -22,7 +22,8 @@ anchor-spl = "0.28.0" solana-program = "1.10.29" spl-associated-token-account = "1.1.2" spl-token = { version = "3.3.0", features = ["no-entrypoint"] } -mpl-token-metadata = { version = "1.8.0", features = ["no-entrypoint"] } +mpl-token-metadata = "3.0.1" +mpl-utils = "0.3.2" solana-nft-programs-creator-standard = { version = "1.0.0", features = ["cpi"] } [dev-dependencies] diff --git a/programs/solana-nft-programs-token-manager/src/instructions/claim.rs b/programs/solana-nft-programs-token-manager/src/instructions/claim.rs index 640d1f34a..5c2fe2619 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/claim.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/claim.rs @@ -1,10 +1,12 @@ -use mpl_token_metadata::instruction::DelegateArgs; -use mpl_token_metadata::instruction::LockArgs; -use mpl_token_metadata::instruction::MetadataInstruction; -use mpl_token_metadata::instruction::TransferArgs; -use mpl_token_metadata::state::Metadata; -use mpl_token_metadata::state::TokenStandard; -use solana_program::instruction::Instruction; +use mpl_token_metadata::accounts::Metadata; +use mpl_token_metadata::instructions::DelegateLockedTransferV1; +use mpl_token_metadata::instructions::DelegateLockedTransferV1InstructionArgs; +use mpl_token_metadata::instructions::LockV1; +use mpl_token_metadata::instructions::LockV1InstructionArgs; +use mpl_token_metadata::instructions::TransferV1; +use mpl_token_metadata::instructions::TransferV1InstructionArgs; +use mpl_token_metadata::types::TokenStandard; +use mpl_utils::assert_derivation; use crate::errors::ErrorCode; use crate::state::*; @@ -20,8 +22,6 @@ use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use anchor_spl::token::Transfer; use anchor_spl::token::{self}; -use mpl_token_metadata::instruction::freeze_delegated_account; -use mpl_token_metadata::utils::assert_derivation; #[derive(Accounts)] pub struct ClaimCtx<'info> { @@ -64,7 +64,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, if token_manager.kind != TokenManagerKind::Programmable as u8 { // look at next account if let Some(next_account) = remaining_accs.peek() { - if next_account.owner == &mpl_token_metadata::id() { + if next_account.owner == &mpl_token_metadata::ID { let mint_metadata_data = next_account.try_borrow_mut_data().expect("Failed to borrow data"); if let Ok(metadata) = Metadata::deserialize(&mut mint_metadata_data.as_ref()) { // migrated pnft @@ -116,7 +116,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let mint_manager_info = next_account_info(remaining_accs)?; let mint = ctx.accounts.mint.key(); let path = &[MINT_MANAGER_SEED.as_bytes(), mint.as_ref()]; - assert_derivation(ctx.program_id, mint_manager_info, path)?; + assert_derivation(ctx.program_id, mint_manager_info, path, error!(ErrorCode::PublicKeyMismatch))?; // update mint manager let mut mint_manager = Account::::try_from(mint_manager_info)?; mint_manager.token_managers = mint_manager.token_managers.checked_add(1).expect("Addition error"); @@ -150,8 +150,8 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let metadata_program = next_account_info(remaining_accs)?; // edition will be validated by metadata_program - // assert_keys_eq!(metadata_program.key, mpl_token_metadata::id()); - if metadata_program.key() != mpl_token_metadata::id() { + // assert_keys_eq!(metadata_program.key, mpl_token_metadata::ID); + if metadata_program.key() != mpl_token_metadata::ID { return Err(error!(ErrorCode::PublicKeyMismatch)); } @@ -166,13 +166,14 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, token::approve(cpi_context, token_manager.amount)?; invoke_signed( - &freeze_delegated_account( - *metadata_program.key, - token_manager.key(), - ctx.accounts.recipient_token_account.key(), - *edition_info.key, - ctx.accounts.mint.key(), - ), + &mpl_token_metadata::instructions::FreezeDelegatedAccount { + delegate: token_manager.key(), + token_account: ctx.accounts.recipient_token_account.key(), + edition: edition_info.key(), + mint: ctx.accounts.mint.key(), + token_program: ctx.accounts.token_program.key(), + } + .instruction(), &[ token_manager.to_account_info(), ctx.accounts.recipient_token_account.to_account_info(), @@ -197,7 +198,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let mint_manager_info = next_account_info(remaining_accs)?; let mint = ctx.accounts.mint.key(); let path = &[MINT_MANAGER_SEED.as_bytes(), mint.as_ref()]; - assert_derivation(ctx.program_id, mint_manager_info, path)?; + assert_derivation(ctx.program_id, mint_manager_info, path, error!(ErrorCode::PublicKeyMismatch))?; // update mint manager let mut mint_manager = Account::::try_from(mint_manager_info)?; @@ -229,35 +230,31 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let authorization_rules_program_info = next_account_info(remaining_accs)?; let authorization_rules_info = next_account_info(remaining_accs)?; let _token_metadata_program = next_account_info(remaining_accs)?; + invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - AccountMeta::new_readonly(ctx.accounts.token_manager_token_account.owner.key(), false), - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - AccountMeta::new_readonly(ctx.accounts.recipient.key(), false), - AccountMeta::new_readonly(mint_info.key(), false), - AccountMeta::new(mint_metadata_info.key(), false), - AccountMeta::new_readonly(mint_edition_info.key(), false), - AccountMeta::new(token_manager_token_record_info.key(), false), - AccountMeta::new(recipient_token_record_info.key(), false), - AccountMeta::new_readonly(token_manager.key(), true), - AccountMeta::new(ctx.accounts.recipient.key(), true), - AccountMeta::new_readonly(ctx.accounts.system_program.key(), false), - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - AccountMeta::new_readonly(associated_token_program_info.key(), false), - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.token_manager_token_account.key(), + token_owner: ctx.accounts.token_manager_token_account.owner.key(), + destination_token: ctx.accounts.recipient_token_account.key(), + destination_owner: ctx.accounts.recipient.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(token_manager_token_record_info.key()), + destination_token_record: Some(recipient_token_record_info.key()), + authority: token_manager.key(), + payer: ctx.accounts.recipient.key(), + system_program: ctx.accounts.system_program.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.token_manager_token_account.to_account_info(), token_manager.to_account_info(), @@ -281,46 +278,27 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // 0. `[writable]` Delegate record account - AccountMeta::new_readonly(mpl_token_metadata::id(), false), - // 1. `[]` Delegated owner - AccountMeta::new_readonly(token_manager.key(), false), - // 2. `[writable]` Metadata account - AccountMeta::new(mint_metadata_info.key(), false), - // 3. `[optional]` Master Edition account - AccountMeta::new_readonly(mint_edition_info.key(), false), - // 4. `[]` Token record - AccountMeta::new(recipient_token_record_info.key(), false), - // 5. `[]` Mint account - AccountMeta::new_readonly(mint_info.key(), false), - // 6. `[optional, writable]` Token account - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // 7. `[signer]` Approver (update authority or token owner) to approve the delegation - AccountMeta::new_readonly(ctx.accounts.recipient.key(), true), - // 8. `[signer, writable]` Payer - AccountMeta::new(ctx.accounts.recipient.key(), true), - // 9. `[]` System Program - AccountMeta::new_readonly(ctx.accounts.system_program.key(), false), - // 10. `[]` Instructions sysvar account - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // 11. `[optional]` SPL Token Program - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // 12. `[optional]` Token Authorization Rules program - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // 13. `[optional]` Token Authorization Rules account - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Delegate(DelegateArgs::LockedTransferV1 { - amount: token_manager.amount, - locked_address: token_manager.key(), - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &DelegateLockedTransferV1 { + delegate_record: Some(mpl_token_metadata::ID), + delegate: ctx.accounts.token_manager.key(), + metadata: mint_metadata_info.key(), + master_edition: Some(mint_edition_info.key()), + token_record: Some(recipient_token_record_info.key()), + mint: mint_info.key(), + token: ctx.accounts.recipient_token_account.key(), + authority: ctx.accounts.recipient.key(), + payer: ctx.accounts.recipient.key(), + system_program: ctx.accounts.system_program.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: Some(ctx.accounts.token_program.key()), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(DelegateLockedTransferV1InstructionArgs { + amount: 1, + locked_address: token_manager.key(), + authorization_data: None, + }), &[ token_manager.to_account_info(), mint_metadata_info.to_account_info(), @@ -338,38 +316,22 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // 0. `[signer]` Delegate - AccountMeta::new_readonly(token_manager.key(), true), - // 1. `[optional]` Token owner - AccountMeta::new_readonly(ctx.accounts.recipient.key(), false), - // 2. `[writable]` Token account - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // 3. `[]` Mint account - AccountMeta::new_readonly(mint_info.key(), false), - // 4. `[writable]` Metadata account - AccountMeta::new(mint_metadata_info.key(), false), - // 5. `[optional]` Edition account - AccountMeta::new_readonly(mint_edition_info.key(), false), - // 6. `[optional, writable]` Token record account - AccountMeta::new(recipient_token_record_info.key(), false), - // 7. `[signer, writable]` Payer - AccountMeta::new(ctx.accounts.recipient.key(), true), - // 8. `[]` System Program - AccountMeta::new_readonly(ctx.accounts.system_program.key(), false), - // 9. `[]` Instructions sysvar account - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // 10. `[optional]` SPL Token Program - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // 11. `[optional]` Token Authorization Rules program - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // 12. `[optional]` Token Authorization Rules account - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Lock(LockArgs::V1 { authorization_data: None }).try_to_vec().unwrap(), - }, + &LockV1 { + authority: ctx.accounts.token_manager.key(), + token_owner: Some(ctx.accounts.recipient.key()), + token: ctx.accounts.recipient_token_account.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(recipient_token_record_info.key()), + payer: ctx.accounts.recipient.key(), + system_program: ctx.accounts.system_program.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: Some(ctx.accounts.token_program.key()), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(LockV1InstructionArgs { authorization_data: None }), &[ token_manager.to_account_info(), ctx.accounts.recipient.to_account_info(), diff --git a/programs/solana-nft-programs-token-manager/src/instructions/claim_receipt_mint.rs b/programs/solana-nft-programs-token-manager/src/instructions/claim_receipt_mint.rs index c9b381a9e..0d8b472c6 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/claim_receipt_mint.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/claim_receipt_mint.rs @@ -7,8 +7,10 @@ use anchor_spl::associated_token::AssociatedToken; use anchor_spl::associated_token::{self}; use anchor_spl::token::Token; use anchor_spl::token::{self}; -use mpl_token_metadata::instruction::create_metadata_accounts_v3; -use mpl_token_metadata::state::Creator; +use mpl_token_metadata::instructions::CreateMetadataAccountV3; +use mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs; +use mpl_token_metadata::types::Creator; +use mpl_token_metadata::types::DataV2; use solana_program::program_pack::Pack; use solana_program::system_instruction::create_account; @@ -44,7 +46,7 @@ pub struct ClaimReceiptMintCtx<'info> { associated_token: Program<'info, AssociatedToken>, system_program: Program<'info, System>, /// CHECK: This is not dangerous because we don't read or write from this account - #[account(address = mpl_token_metadata::id())] + #[account(address = mpl_token_metadata::ID)] token_metadata_program: UncheckedAccount<'info>, rent: Sysvar<'info, Rent>, } @@ -85,41 +87,44 @@ pub fn handler(ctx: Context, name: String) -> Result<()> { // create metadata invoke_signed( - &create_metadata_accounts_v3( - *ctx.accounts.token_metadata_program.key, - *ctx.accounts.receipt_mint_metadata.key, - *ctx.accounts.receipt_mint.key, - ctx.accounts.receipt_mint_manager.key(), - *ctx.accounts.payer.key, - ctx.accounts.receipt_mint_manager.key(), - name, - "RCP".to_string(), - // generative URL pointing to the original mint - "https://api.host.so/metadata/".to_string() + &ctx.accounts.token_manager.mint.to_string() + "?text=RENTED", - Some(vec![ - Creator { - address: ctx.accounts.receipt_mint_manager.key(), - verified: true, - share: 50, - }, - Creator { - address: ctx.accounts.issuer.key(), - verified: false, - share: 50, - }, - Creator { - address: ctx.accounts.token_manager.key(), - verified: false, - share: 0, - }, - ]), - 0, - true, - true, - None, - None, - None, - ), + &CreateMetadataAccountV3 { + metadata: ctx.accounts.receipt_mint_metadata.key(), + mint: ctx.accounts.receipt_mint.key(), + mint_authority: ctx.accounts.receipt_mint_manager.key(), + payer: ctx.accounts.payer.key(), + update_authority: ctx.accounts.receipt_mint_manager.key(), + system_program: ctx.accounts.system_program.key(), + rent: Some(ctx.accounts.rent.key()), + } + .instruction(CreateMetadataAccountV3InstructionArgs { + data: DataV2 { + name: name, + symbol: "RCP".to_string(), + uri: "https://api.host.so/metadata/".to_string() + &ctx.accounts.token_manager.mint.to_string() + "?text=RENTED", + seller_fee_basis_points: 0, + creators: Some(vec![ + Creator { + address: ctx.accounts.receipt_mint_manager.key(), + verified: true, + share: 50, + }, + Creator { + address: ctx.accounts.issuer.key(), + verified: false, + share: 50, + }, + Creator { + address: ctx.accounts.token_manager.key(), + verified: false, + share: 0, + }, + ]), + collection: None, + uses: None, + }, + is_mutable: true, + collection_details: None, + }), &[ ctx.accounts.receipt_mint_metadata.to_account_info(), ctx.accounts.receipt_mint.to_account_info(), diff --git a/programs/solana-nft-programs-token-manager/src/instructions/invalidate.rs b/programs/solana-nft-programs-token-manager/src/instructions/invalidate.rs index f22f81cde..0b7f2e454 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/invalidate.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/invalidate.rs @@ -1,9 +1,10 @@ -use mpl_token_metadata::instruction::MetadataInstruction; -use mpl_token_metadata::instruction::TransferArgs; -use mpl_token_metadata::instruction::UnlockArgs; -use mpl_token_metadata::state::Metadata; -use mpl_token_metadata::state::TokenStandard; -use solana_program::instruction::Instruction; +use mpl_token_metadata::accounts::Metadata; +use mpl_token_metadata::instructions::TransferV1; +use mpl_token_metadata::instructions::TransferV1InstructionArgs; +use mpl_token_metadata::instructions::UnlockV1; +use mpl_token_metadata::instructions::UnlockV1InstructionArgs; +use mpl_token_metadata::types::TokenStandard; +use mpl_utils::assert_derivation; use crate::errors::ErrorCode; use crate::state::*; @@ -17,8 +18,6 @@ use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use anchor_spl::token::Transfer; use anchor_spl::token::{self}; -use mpl_token_metadata::instruction::thaw_delegated_account; -use mpl_token_metadata::utils::assert_derivation; #[derive(Accounts)] pub struct InvalidateCtx<'info> { @@ -65,7 +64,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, if token_manager.kind != TokenManagerKind::Programmable as u8 { // look at next account if let Some(next_account) = remaining_accs.peek() { - if next_account.owner == &mpl_token_metadata::id() { + if next_account.owner == &mpl_token_metadata::ID { let mint_metadata_data = next_account.try_borrow_mut_data().expect("Failed to borrow data"); if let Ok(metadata) = Metadata::deserialize(&mut mint_metadata_data.as_ref()) { // migrated pnft @@ -90,7 +89,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, mint_manager.exit(ctx.program_id)?; let path = &[MINT_MANAGER_SEED.as_bytes(), mint.as_ref()]; - let bump_seed = assert_derivation(ctx.program_id, mint_manager_info, path)?; + let bump_seed = assert_derivation(ctx.program_id, mint_manager_info, path, error!(ErrorCode::PublicKeyMismatch))?; let mint_manager_seeds = &[MINT_MANAGER_SEED.as_bytes(), mint.as_ref(), &[bump_seed]]; let mint_manager_signer = &[&mint_manager_seeds[..]]; @@ -108,17 +107,19 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let edition_info = next_account_info(remaining_accs)?; let metadata_program = next_account_info(remaining_accs)?; // edition will be validated by metadata_program - if metadata_program.key() != mpl_token_metadata::id() { + if metadata_program.key() != mpl_token_metadata::ID { return Err(error!(ErrorCode::InvalidMetadataProgramId)); } + invoke_signed( - &thaw_delegated_account( - *metadata_program.key, - token_manager.key(), - ctx.accounts.recipient_token_account.key(), - *edition_info.key, - ctx.accounts.mint.key(), - ), + &mpl_token_metadata::instructions::ThawDelegatedAccount { + delegate: token_manager.key(), + token_account: ctx.accounts.recipient_token_account.key(), + edition: edition_info.key(), + mint: ctx.accounts.mint.key(), + token_program: ctx.accounts.token_program.key(), + } + .instruction(), &[ token_manager.to_account_info(), ctx.accounts.recipient_token_account.to_account_info(), @@ -230,38 +231,22 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let authorization_rules_info = next_account_info(remaining_accs)?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // 0. `[signer]` Delegate - AccountMeta::new_readonly(token_manager.key(), true), - // 1. `[optional]` Token owner - AccountMeta::new_readonly(recipient_token_account_owner_info.key(), false), - // 2. `[writable]` Token account - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // 3. `[]` Mint account - AccountMeta::new_readonly(mint_info.key(), false), - // 4. `[writable]` Metadata account - AccountMeta::new(mint_metadata_info.key(), false), - // 5. `[optional]` Edition account - AccountMeta::new_readonly(mint_edition_info.key(), false), - // 6. `[optional, writable]` Token record account - AccountMeta::new(from_token_record.key(), false), - // 7. `[signer, writable]` Payer - AccountMeta::new(payer_info.key(), true), - // 8. `[]` System Program - AccountMeta::new_readonly(system_program_info.key(), false), - // 9. `[]` Instructions sysvar account - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // 10. `[optional]` SPL Token Program - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // 11. `[optional]` Token Authorization Rules program - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // 12. `[optional]` Token Authorization Rules account - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Unlock(UnlockArgs::V1 { authorization_data: None }).try_to_vec().unwrap(), - }, + &UnlockV1 { + authority: token_manager.key(), + token_owner: Some(recipient_token_account_owner_info.key()), + token: ctx.accounts.recipient_token_account.owner, + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: Some(ctx.accounts.token_program.key()), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(UnlockV1InstructionArgs { authorization_data: None }), &[ token_manager.to_account_info(), recipient_token_account_owner_info.to_account_info(), @@ -283,51 +268,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(ctx.accounts.recipient_token_account.owner.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(from_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(token_manager_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(payer_info.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.recipient_token_account.key(), + token_owner: recipient_token_account_owner_info.key(), + destination_token: ctx.accounts.token_manager_token_account.key(), + destination_owner: token_manager.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + destination_token_record: Some(token_manager_token_record.key()), + authority: token_manager.key(), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.recipient_token_account.to_account_info(), recipient_token_account_owner_info.to_account_info(), @@ -350,51 +313,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(return_token_account_info.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(return_token_account_owner_info.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(token_manager_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(to_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(payer_info.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.token_manager_token_account.key(), + token_owner: token_manager.key(), + destination_token: return_token_account_info.key(), + destination_owner: return_token_account_owner_info.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(token_manager_token_record.key()), + destination_token_record: Some(to_token_record.key()), + authority: token_manager.key(), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.token_manager_token_account.to_account_info(), token_manager.to_account_info(), @@ -521,38 +462,22 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let authorization_rules_info = next_account_info(remaining_accs)?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // 0. `[signer]` Delegate - AccountMeta::new_readonly(token_manager.key(), true), - // 1. `[optional]` Token owner - AccountMeta::new_readonly(recipient_token_account_owner_info.key(), false), - // 2. `[writable]` Token account - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // 3. `[]` Mint account - AccountMeta::new_readonly(mint_info.key(), false), - // 4. `[writable]` Metadata account - AccountMeta::new(mint_metadata_info.key(), false), - // 5. `[optional]` Edition account - AccountMeta::new_readonly(mint_edition_info.key(), false), - // 6. `[optional, writable]` Token record account - AccountMeta::new(from_token_record.key(), false), - // 7. `[signer, writable]` Payer - AccountMeta::new(payer_info.key(), true), - // 8. `[]` System Program - AccountMeta::new_readonly(system_program_info.key(), false), - // 9. `[]` Instructions sysvar account - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // 10. `[optional]` SPL Token Program - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // 11. `[optional]` Token Authorization Rules program - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // 12. `[optional]` Token Authorization Rules account - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Unlock(UnlockArgs::V1 { authorization_data: None }).try_to_vec().unwrap(), - }, + &UnlockV1 { + authority: token_manager.key(), + token_owner: Some(recipient_token_account_owner_info.key()), + token: ctx.accounts.recipient_token_account.owner, + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: Some(ctx.accounts.token_program.key()), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(UnlockV1InstructionArgs { authorization_data: None }), &[ token_manager.to_account_info(), recipient_token_account_owner_info.to_account_info(), @@ -574,51 +499,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(ctx.accounts.recipient_token_account.owner.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(from_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(token_manager_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(payer_info.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.recipient_token_account.key(), + token_owner: recipient_token_account_owner_info.key(), + destination_token: ctx.accounts.token_manager_token_account.key(), + destination_owner: token_manager.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + destination_token_record: Some(token_manager_token_record.key()), + authority: token_manager.key(), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.recipient_token_account.to_account_info(), recipient_token_account_owner_info.to_account_info(), @@ -641,51 +544,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(recipient_token_account_owner_info.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(token_manager_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(from_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(payer_info.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.token_manager_token_account.key(), + token_owner: token_manager.key(), + destination_token: ctx.accounts.recipient_token_account.key(), + destination_owner: recipient_token_account_owner_info.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(token_manager_token_record.key()), + destination_token_record: Some(from_token_record.key()), + authority: token_manager.key(), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.token_manager_token_account.to_account_info(), token_manager.to_account_info(), @@ -776,38 +657,22 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let authorization_rules_info = next_account_info(remaining_accs)?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // 0. `[signer]` Delegate - AccountMeta::new_readonly(token_manager.key(), true), - // 1. `[optional]` Token owner - AccountMeta::new_readonly(recipient_token_account_owner_info.key(), false), - // 2. `[writable]` Token account - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // 3. `[]` Mint account - AccountMeta::new_readonly(mint_info.key(), false), - // 4. `[writable]` Metadata account - AccountMeta::new(mint_metadata_info.key(), false), - // 5. `[optional]` Edition account - AccountMeta::new_readonly(mint_edition_info.key(), false), - // 6. `[optional, writable]` Token record account - AccountMeta::new(from_token_record.key(), false), - // 7. `[signer, writable]` Payer - AccountMeta::new(payer_info.key(), true), - // 8. `[]` System Program - AccountMeta::new_readonly(system_program_info.key(), false), - // 9. `[]` Instructions sysvar account - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // 10. `[optional]` SPL Token Program - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // 11. `[optional]` Token Authorization Rules program - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // 12. `[optional]` Token Authorization Rules account - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Unlock(UnlockArgs::V1 { authorization_data: None }).try_to_vec().unwrap(), - }, + &UnlockV1 { + authority: token_manager.key(), + token_owner: Some(recipient_token_account_owner_info.key()), + token: ctx.accounts.recipient_token_account.owner, + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: Some(ctx.accounts.token_program.key()), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(UnlockV1InstructionArgs { authorization_data: None }), &[ token_manager.to_account_info(), recipient_token_account_owner_info.to_account_info(), @@ -829,51 +694,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, )?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.recipient_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(ctx.accounts.recipient_token_account.owner.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(from_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(token_manager_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(payer_info.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.recipient_token_account.key(), + token_owner: recipient_token_account_owner_info.key(), + destination_token: ctx.accounts.token_manager_token_account.key(), + destination_owner: token_manager.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + destination_token_record: Some(token_manager_token_record.key()), + authority: token_manager.key(), + payer: payer_info.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.recipient_token_account.to_account_info(), recipient_token_account_owner_info.to_account_info(), diff --git a/programs/solana-nft-programs-token-manager/src/instructions/issue.rs b/programs/solana-nft-programs-token-manager/src/instructions/issue.rs index dd2c19966..8305db99b 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/issue.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/issue.rs @@ -1,6 +1,5 @@ -use mpl_token_metadata::instruction::MetadataInstruction; -use mpl_token_metadata::instruction::TransferArgs; -use solana_program::instruction::Instruction; +use mpl_token_metadata::instructions::TransferV1; +use mpl_token_metadata::instructions::TransferV1InstructionArgs; use crate::errors::ErrorCode; use crate::state::*; @@ -76,36 +75,31 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let associated_token_program_info = next_account_info(remaining_accs)?; let authorization_rules_program_info = next_account_info(remaining_accs)?; let authorization_rules_info = next_account_info(remaining_accs)?; - let accounts = vec![ - AccountMeta::new(ctx.accounts.issuer_token_account.key(), false), - AccountMeta::new_readonly(ctx.accounts.issuer_token_account.owner.key(), false), - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - AccountMeta::new_readonly(token_manager.key(), false), - AccountMeta::new_readonly(mint_info.key(), false), - AccountMeta::new(mint_metadata_info.key(), false), - AccountMeta::new_readonly(mint_edition_info.key(), false), - AccountMeta::new(issuer_token_record_info.key(), false), - AccountMeta::new(token_manager_token_record_info.key(), false), - AccountMeta::new_readonly(ctx.accounts.issuer.key(), true), - AccountMeta::new(ctx.accounts.payer.key(), true), - AccountMeta::new_readonly(ctx.accounts.system_program.key(), false), - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - AccountMeta::new_readonly(associated_token_program_info.key(), false), - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ]; + invoke( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts, - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.issuer_token_account.key(), + token_owner: ctx.accounts.issuer_token_account.owner.key(), + destination_token: ctx.accounts.token_manager_token_account.key(), + destination_owner: token_manager.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(issuer_token_record_info.key()), + destination_token_record: Some(token_manager_token_record_info.key()), + authority: ctx.accounts.issuer.key(), + payer: ctx.accounts.payer.key(), + system_program: ctx.accounts.system_program.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.issuer_token_account.to_account_info(), ctx.accounts.issuer.to_account_info(), diff --git a/programs/solana-nft-programs-token-manager/src/instructions/permissioned/migrate.rs b/programs/solana-nft-programs-token-manager/src/instructions/permissioned/migrate.rs index 6213355cd..d989f3599 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/permissioned/migrate.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/permissioned/migrate.rs @@ -49,7 +49,7 @@ pub struct MigrateCtx<'info> { token_program: Program<'info, Token>, system_program: Program<'info, System>, /// CHECK: This is not dangerous because the ID is checked with instructions sysvar - #[account(address = mpl_token_metadata::id())] + #[account(address = mpl_token_metadata::ID)] mpl_token_metadata: UncheckedAccount<'info>, } diff --git a/programs/solana-nft-programs-token-manager/src/instructions/transfers/transfer.rs b/programs/solana-nft-programs-token-manager/src/instructions/transfers/transfer.rs index 9a4961fc3..eb6cbae22 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/transfers/transfer.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/transfers/transfer.rs @@ -112,7 +112,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let metadata_program = next_account_info(remaining_accs)?; // edition will be validated by metadata_program - if metadata_program.key() != mpl_token_metadata::id() { + if metadata_program.key() != mpl_token_metadata::ID { return Err(error!(ErrorCode::PublicKeyMismatch)); } diff --git a/programs/solana-nft-programs-token-manager/src/instructions/unissue.rs b/programs/solana-nft-programs-token-manager/src/instructions/unissue.rs index d5c7219db..ed3271b2a 100644 --- a/programs/solana-nft-programs-token-manager/src/instructions/unissue.rs +++ b/programs/solana-nft-programs-token-manager/src/instructions/unissue.rs @@ -7,11 +7,10 @@ use anchor_spl::token::Token; use anchor_spl::token::TokenAccount; use anchor_spl::token::Transfer; use anchor_spl::token::{self}; -use mpl_token_metadata::instruction::MetadataInstruction; -use mpl_token_metadata::instruction::TransferArgs; -use mpl_token_metadata::state::Metadata; -use mpl_token_metadata::state::TokenStandard; -use solana_program::instruction::Instruction; +use mpl_token_metadata::accounts::Metadata; +use mpl_token_metadata::instructions::TransferV1; +use mpl_token_metadata::instructions::TransferV1InstructionArgs; +use mpl_token_metadata::types::TokenStandard; use solana_program::program::invoke_signed; #[derive(Accounts)] @@ -42,7 +41,7 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, if token_manager.kind != TokenManagerKind::Programmable as u8 { // look at next account if let Some(next_account) = remaining_accs.peek() { - if next_account.owner == &mpl_token_metadata::id() { + if next_account.owner == &mpl_token_metadata::ID { let mint_metadata_data = next_account.try_borrow_mut_data().expect("Failed to borrow data"); if let Ok(metadata) = Metadata::deserialize(&mut mint_metadata_data.as_ref()) { // migrated pnft @@ -70,51 +69,29 @@ pub fn handler<'key, 'accounts, 'remaining, 'info>(ctx: Context<'key, 'accounts, let authorization_rules_info = next_account_info(remaining_accs)?; invoke_signed( - &Instruction { - program_id: mpl_token_metadata::id(), - accounts: vec![ - // #[account(0, writable, name="token", desc="Token account")] - AccountMeta::new(ctx.accounts.token_manager_token_account.key(), false), - // #[account(1, name="token_owner", desc="Token account owner")] - AccountMeta::new_readonly(token_manager.key(), false), - // #[account(2, writable, name="destination", desc="Destination token account")] - AccountMeta::new(ctx.accounts.issuer_token_account.key(), false), - // #[account(3, name="destination_owner", desc="Destination token account owner")] - AccountMeta::new_readonly(ctx.accounts.issuer.key(), false), - // #[account(4, name="mint", desc="Mint of token asset")] - AccountMeta::new_readonly(mint_info.key(), false), - // #[account(5, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")] - AccountMeta::new(mint_metadata_info.key(), false), - // #[account(6, optional, name="edition", desc="Edition of token asset")] - AccountMeta::new_readonly(mint_edition_info.key(), false), - // #[account(7, optional, writable, name="recipient_token_record", desc="Owner token record account")] - AccountMeta::new(from_token_record.key(), false), - // #[account(8, optional, writable, name="destination_token_record", desc="Destination token record account")] - AccountMeta::new(to_token_record.key(), false), - // #[account(9, signer, name="authority", desc="Transfer authority (token owner or delegate)")] - AccountMeta::new_readonly(token_manager.key(), true), - // #[account(10, signer, writable, name="payer", desc="Payer")] - AccountMeta::new(ctx.accounts.issuer.key(), true), - // #[account(11, name="system_program", desc="System Program")] - AccountMeta::new_readonly(system_program_info.key(), false), - // #[account(12, name="sysvar_instructions", desc="Instructions sysvar account")] - AccountMeta::new_readonly(sysvar_instructions_info.key(), false), - // #[account(13, name="spl_token_program", desc="SPL Token Program")] - AccountMeta::new_readonly(ctx.accounts.token_program.key(), false), - // #[account(14, name="spl_ata_program", desc="SPL Associated Token Account program")] - AccountMeta::new_readonly(associated_token_program_info.key(), false), - // #[account(15, optional, name="authorization_rules_program", desc="Token Authorization Rules Program")] - AccountMeta::new_readonly(authorization_rules_program_info.key(), false), - // #[account(16, optional, name="authorization_rules", desc="Token Authorization Rules account")] - AccountMeta::new_readonly(authorization_rules_info.key(), false), - ], - data: MetadataInstruction::Transfer(TransferArgs::V1 { - amount: token_manager.amount, - authorization_data: None, - }) - .try_to_vec() - .unwrap(), - }, + &TransferV1 { + token: ctx.accounts.token_manager_token_account.key(), + token_owner: token_manager.key(), + destination_token: ctx.accounts.issuer_token_account.key(), + destination_owner: ctx.accounts.issuer.key(), + mint: mint_info.key(), + metadata: mint_metadata_info.key(), + edition: Some(mint_edition_info.key()), + token_record: Some(from_token_record.key()), + destination_token_record: Some(to_token_record.key()), + authority: token_manager.key(), + payer: ctx.accounts.issuer.key(), + system_program: system_program_info.key(), + sysvar_instructions: sysvar_instructions_info.key(), + spl_token_program: ctx.accounts.token_program.key(), + spl_ata_program: associated_token_program_info.key(), + authorization_rules_program: Some(authorization_rules_program_info.key()), + authorization_rules: Some(authorization_rules_info.key()), + } + .instruction(TransferV1InstructionArgs { + amount: token_manager.amount, + authorization_data: None, + }), &[ ctx.accounts.token_manager_token_account.to_account_info(), token_manager.to_account_info(), diff --git a/programs/solana-nft-programs-transfer-authority/Cargo.toml b/programs/solana-nft-programs-transfer-authority/Cargo.toml index 17252567d..56319a961 100644 --- a/programs/solana-nft-programs-transfer-authority/Cargo.toml +++ b/programs/solana-nft-programs-transfer-authority/Cargo.toml @@ -21,7 +21,8 @@ anchor-lang = { version = "0.28.0", features = ["init-if-needed"] } anchor-spl = "0.28.0" spl-associated-token-account = "1.1.2" spl-token = { version = "3.3.0", features = ["no-entrypoint"] } -mpl-token-metadata = { version = "1.7.0", features = ["no-entrypoint"] } +mpl-token-metadata = "3.0.1" +mpl-utils = "0.3.2" solana-program = "1.10.29" solana-nft-programs-token-manager = { version = "1.0.0", path = "../solana-nft-programs-token-manager", features = ["cpi"] } solana-nft-programs-payment-manager = { version = "1.0.0", features = ["cpi"] } diff --git a/programs/solana-nft-programs-use-invalidator/Cargo.toml b/programs/solana-nft-programs-use-invalidator/Cargo.toml index f4c7e8ae3..9a8bed8e8 100644 --- a/programs/solana-nft-programs-use-invalidator/Cargo.toml +++ b/programs/solana-nft-programs-use-invalidator/Cargo.toml @@ -24,7 +24,8 @@ spl-token = { version = "3.3.0", features = ["no-entrypoint"] } solana-program = "1.10.29" solana-nft-programs-token-manager = { version = "1.0.0", path = "../solana-nft-programs-token-manager", features = ["cpi"] } solana-nft-programs-payment-manager = { version = "1.0.0", features = ["cpi"] } -mpl-token-metadata = { version = "1.7.0", features = ["no-entrypoint"] } +mpl-token-metadata = "3.0.1" +mpl-utils = "0.3.2" arrayref = "0.3.6" [dev-dependencies]