Search code examples
rustanchorsolananft

Can I get nft metadata from the <AccountInfo> address in solana rust program?


I've noticed that metaplex got API for platforms like JS, iOS, Android and all of them are documented great, except RUST :)

For example all of apis above got something like getNftByMint with output of mine nft data with all metadata inside

But checking all the rust/solana/anchor crates and docs I didn't find any way how to get metadata from metadataAccount right in the rust program, in instance to check some params of some nfts and do something)

The only way I found is below, but even if I tried to mitigate this error adding match and so on, still I got the same error message, But without from_account_info this error dissapears.

In rs program i got:

pub fn get_metadata_by_pubkey(ctx: Context<GetMetadataByPubkey>) -> Result<()> {
    let account = ctx.accounts.metadata_pubkey.to_account_info();
    let metadata: Metadata = Metadata::from_account_info(&account)?;
    ...

And in ts file:

it("Is get_metadata_by_pubkey", async () => {
  const pk: PublicKey = new PublicKey("<public key of my nft's metadata account>");
  await program.methods.getMetadataByPubkey().accounts({
    metadataPubkey: pk
  }).rpc();
});

And I got this error, after running anchor test:

Error: failed to send transaction: Transaction simulation failed:
Error processing Instruction 0: Program failed to complete


Solution

  • from_account_info is the correct way of doing it. Here is an example of a program that uses it https://github.com/Bonfida/dex-v4/blob/main/program/src/processor/create_market.rs#L154

    However, you need to make sure the metadata account is initialized before trying to deserialize, which can be done with something like accounts.token_metadata.data_len() != 0