A basic library focused on fetching data from the Solana blockchain and parsing NFT transactions.
Solana Lib
A basic library focused on fetching data from the Solana blockchain and parsing NFT transactions.
Setup
python -m venv .venv
Compile requirements
(you don't need to do this)
pip-compile requirements/common.in --output-file=- > requirements/common.txt pip-compile requirements/lint.in --output-file=- > requirements/lint.txt pip-compile requirements/test.in --output-file=- > requirements/test.txt
Install requirements
pip install -r requirements/common.txt -r requirements/lint.txt -r requirements/test.txt
Run linter
pylama solanalib
Run tests
python -m pytest tests
Comments
Current Workflow to get NFTs
Get Program Accounts Filter with memcp and look for the creator account at offset 326 More info on the structure of metaplex accounts here https://docs.metaplex.com/architecture/deep_dive/overview
- pubkey of the result is the account that holds metadata info
- parse account data to get the mint (nft address)
- then get the mint with unpackmetatdataaccount
- Find associate token account
from solana.publickey import PublicKey seeds = [ base58.b58decode(str("6Y2Scqw11m2WUZ7qiS16e3Z9vsw6xsrrGzxktLrMX4BJ")), base58.b58decode(str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")), base58.b58decode(str("FDNXh1uCkQ3FE9BFVJMqeimQGUTAUinjdcgvaavufBzC")), ] associatetokenaccount = PublicKey.findprogramaddress( seeds=seeds, programid=ASSOCIATETOKEN_PROGRAM, ) associatetokenaccount -> CpkL4HybWzJFqwHWZRR6kZ6SdK2exE1goQhu3Pt3JQFP
To get the Associate Token Account use getTokenLargestAccounts with mint as key * Problem: Multiple accounts are returned * Need to find the "first" account, the one that was involved in the mint * Then iteratively parse transactions to find the next, and next, and next token account
Get the nft metadata address if you have the mint, with metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s as the Metaplex Metadata Token program id.
from solana.publickey import PublicKey seeds = [ 'metadata'.encode(), base58.b58decode(str("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")), base58.b58decode(str("FDNXh1uCkQ3FE9BFVJMqeimQGUTAUinjdcgvaavufBzC")), ] metadataaccount = PublicKey.findprogram_address( seeds=seeds, program_id=PublicKey("metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"), ) metadata_account -> 87PYEqehWWRPbS4JfqdY8ggzAAuoM35meCMzMScx31j4
Problems that arrised and my solution
How to decode unkown instruction data
I wanted to find the listing price for the MEV2 contract from the instruction data. 2B3vSpRNKZZWsFek5ah7xe9uickZUbsaBjoqxVQF3Wq8ngW
First, base58 decode the instruction data and convert to hex
base58.b58decode("2B3vSpRNKZZWsFek5ah7xe9uickZUbsaBjoqxVQF3Wq8ngW").hex() > 33e685a4017f83adfefa805470be010000000100000000000000ffffffffffffffff
I then went to an online hex converter (https://www.scadacore.com/tools/programming-calculators/online-hex-converter/)
- No luck
- listing price was 7490000000
- 805470BE01
- Nice! This is in the instruction data
I then took the same route as the V1 contract, convert this hex to little endian and eventually to int
pricelittleendian = tolittleendianfromhex("805470be01") pricelamports = int(pricelittle_endian, 16)