5

I'm currently attempting to retrieve the collection field from the Metaplex metadata of a NFT in python. My results are half correct but the collection key deserialized is entirely different than what is show on-chain. Below is an example of my code:

import asyncio
import base64

from rpc_client import Rpc
from helper import Helper
from borsh_construct import CStruct, U8, Bool, Enum, Option
from anchorpy.borsh_extension import BorshPubkey

async def main():

    Pubkey = BorshPubkey

    rpc = Rpc("https://ssc-dao.genesysgo.net/")

    helper = Helper(rpc)

    mint_hash = "EoBKaS2YwesLUAmBCaAx8vg67pBEpcWQqP9b6xz46DWT"

    pda_data = await helper.nft_pda(mint_hash) # Derives the PDA and returns the account data of it

    struct = CStruct(

            "collection" / CStruct("verified" / Bool, "key" / Pubkey)

            )

    metadata = struct.parse(base64.b64decode(pda_data))


asyncio.run(main())

The above code returns the following:

Container: 
    collection = Container: 
        verified = True
        key = 4bUf8AByHXNMawak1nyhMAaDHuJpRJPCxBUuHMyVKfwQ

While the verified key is correct, key is not correct. The correct key for this collection is YAbo2pkkkFdpqBvGT9XNPHsW1GNH9wxFZ8h3YC3fgf2.

Here is a link to the NFT on solscan to see the difference in collection keys.

Would anyone happen to have any suggestions on what might be causing this?

5
  • What does your helper.nft_pda() do? I'm not sure it's getting back the metadata account.
    – sohrab
    Jul 21, 2022 at 3:43
  • The function derives the PDA address then calls getAccountInfo on that address and returns the stored account data from that call.
    – Greg7390
    Jul 21, 2022 at 4:45
  • Its not possible to replicate the code with the provided code, but would like to know which seeds are you providing to deserialize the metadata account that you are providing to get the collection Jul 21, 2022 at 15:40
  • Just skimming through your code the thing that strikes me is the base64. Usually we use base58 (but I'm not sure how the RPC is configured and I didn't try the script myself). Maybe that helps. My other idea was that it could be a big-endian vs little-endian thing (but I don't really see that here).
    – Solandy
    Jul 24, 2022 at 20:08
  • where did you get the CStruct definition from? I thought the metadata struct on-chain has a couple other fields before the collection field? Definitions here. You might be interpreting the bytes that make up the initial fields like name and symbol as verified and key
    – billy
    Jul 27, 2022 at 12:49

1 Answer 1

2

Metaplex Metadata accounts come in a few different versions that are serialized differently. A very small number of accounts contains corrupt data due to a historical bug.

The Metaplex program library contains a reference deserialization algorithm and type definitions you could use: https://github.com/metaplex-foundation/metaplex-program-library/blob/0d63c8b3c6ac077dba63519c78a8da7a58b285a1/token-metadata/program/src/deser.rs#L12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.