wow thanks for checking team!
I understand the issue. The transaction value on chain can be 1eth but that doesn’t in all cases mean this was the value of the NFT, since the contract could have other things at the same time.
I ended up using this if anyone is looking to list the transaction history of an NFT:
// get transaction history
Moralis.Cloud.define('getTransactionHistory', async (request) => {
const query = new Moralis.Query(request.params.network+'NFTTransfers');
query.equalTo('token_id', request.params.token_id);
query.equalTo('token_address', request.params.token_address);
query.equalTo('confirmed', true)
query.descending('createdAt')
const pipeline = [
{
lookup: {
from: request.params.network+'Transactions',
let: { transaction_hash: '$transaction_hash' },
pipeline: [
{ $match: { $expr: { $eq: [ '$$transaction_hash', '$hash' ] } }},
{ $project: { value: 1 }}
],
as: 'value'
}
},
{
project: {
value: { $first: '$value.value' },
to_address: 1,
from_address: 1,
createdAt: 1,
transaction_hash: 1,
}
},
]
const results = await query.aggregate(pipeline);
let items = []
if (results) {
results.reverse() // for some reason query order is reversed by pipeline
// add user data
for (let i = 0; i < results.length; i++) {
const receiverQuery = new Moralis.Query(Moralis.User)
receiverQuery.equalTo('accounts', results[i].to_address)
const receiver = await receiverQuery.first({useMasterKey:true})
const senderQuery = new Moralis.Query(Moralis.User)
senderQuery.equalTo('accounts', results[i].from_address)
const sender = await senderQuery.first({useMasterKey:true})
if (sender) results[i].sender = { username: sender.attributes.username, avatar: sender.attributes.avatar ? sender.attributes.avatar.url() : null }
if (receiver) results[i].receiver = { username: receiver.attributes.username, avatar: receiver.attributes.avatar ? receiver.attributes.avatar.url() : null }
items.push(results[i])
}
}
return items
},{
fields : ['network','token_id','token_address'],
requireUser: true
})
Note that I still add the User data after the pipeline, sadly getting the right User data doesn’t work fully in such a pipeline. But it works, just wondering if it matters at all in performance. For my use case totally fine.
See here:
By looking at the value, to_address and from_address you can see if a transaction was a sale, normal transfer, mint (from 0x000…) or burn (to 0x000…).