NFT Trades
The NFT Trades project, developed by TopLedger, extracts NFT trades from different Solana exchanges, such as Tensor, MagicEden, or HadeSwap.
About TopLedger
TopLedger is SQL-based data discovery and analytics platform focused on Solana. By using Substreams, TopLedger has been able to extract data from the main Solana dapps, thus providing rich analytics products.
TopLedger is an active contributor to the Substreams community and has developed several useful ready-to-use Substreams.
Before You Begin
The NFT Trades Substreams requires medium to advanced Substreams knowledge. If this is the first time you are using Substreams, make sure you:
Read the Develop Substreams section, which will teach you the basics of the developing Substreams modules.
Complete the Explore Solana tutorial, which will assist you in understanding the main pieces of the Solana Substreams.
Clone the TopLedger Solana Programs project and navigate to the nft-trades folder, which contains the code of the Substreams.
Inspect the Project
The Substreams contains only one module, map_block:
modules:
- name: map_block
kind: map
inputs:
- source: sf.solana.type.v1.Block
output:
type: proto:sf.solana.nft.trades.v1.OutputThe Output object provided as the Substreams output is defined in the proto/output.proto file:
The TradeData object contains information about every trade executed, such as amount, buyer or seller.
Every exchange handles data differently, so there is no unique way to decode the data. Therefore, it is necessary to create a custom decode function for every exchange supported by the Substreams. If you navigate to the nft-trades/dapps folder, you will find a file for every exchange.
Every dapp file has a parse_trade_instruction function, which is responsible for decoding the data.
Run the Substreams
You can use the Substreams CLI to run the project:
Inspect the Code
The src/lib.rs file contains the declaration of the Substreams module, map_block. This function is executed for every block of the blockchain.
Create an array of
TradeDataobjects, where the trading data will be stored.Iterate over the transactions of the block.
Get accounts of the transaction (the
resolved_accounts()method contains also accounts stored in the Address Lookup Tables).Unwrap transaction
Iterate over the instructions of the transaction.
Get the program account. The
instruction.program_id_indexindicates the position of the program account in the accounts array.Pass the data to the
get_trade_datafunction. This function verifies if the instruction executed is from one of the NFT exchanges that you want to track. The return type isOption<TradeData>. TheOptionwill only be populated if the instruction belongs to one of the NFT exchanges.
Because every exchange handles the NFT data differently, there must be a custom decoding function for every exchange. The dapps folder of the project contains a file for every exchange, declaring the parse_trade_instruction function.
Based on the
account_indicesparameter passed, create an in-order array of accounts.The
dapp_addressparameter passed is the program account. For every NFT program, you handle the decoding differently.For example, the
TSWAPaqyCSx2KABk68Shruf4rp7CxcNi8hAsbdwmHbNaccount represents the Tensor exchange.If the program account does not match any of the NFT exchanges, then an empty
Option<TradeData>object is returned.
Last updated
Was this helpful?

