Here is an article about the problem encountered when parsing transactions on the Solana blockchain using web3.js:
Title:
Solana Web3.js: ParsedTransaction returns null even though logs are available
Introduction
For you as a developer building applications on the Solana blockchain, parsing transaction details is essential to understand program conditions and trigger custom logic. However, in this article, we’ll address an issue that occurs when you try to access transactions parsed using web3.js on a specific account.
The Problem: ParsedTransaction Returns Null
We’ve written a script that listens to the Solana logs on a specific public key. The code is designed to parse the transaction details when a program condition is met:
const solana = require("solana-web3");
const connection = new solana.Connection();
connection.onLogs(publicKey, (result) => {
const parsedTransaction = result.parsedTransactions;
console.log(parsedTransaction);
});
After configuring the script and connecting to the Solana network, we expect to see the transaction details in the parsedTransactions table. However, when we save the output of this code, we find that it returns an empty object:
{
"error": null,
"info": null,
"status": null,
"result": {
"transactions": []
}
}
What happened?
In Solana, when you get transactions using connection.getEntry, the result is a Web3Transaction object. However, in this case, we are not explicitly retrieving these transactions. Instead, we are relying on the parsedTransactions array provided by web3.js.
The problem occurs because the getEntry method does not guarantee that all transaction entries will be returned when using result.parsedTransactions. If the program condition is met and there is no matching transaction, result.parsedTransactions actually returns an empty array (“[]”). The code we wrote assumes that this array is not empty yet.
Workaround
To solve this problem, you can use a different approach to parsing the transaction details. One way to do this is to retrieve all transactions and then filter out those that do not match your condition:
const solana = require("solana-web3");
const connection = new solana.Connection();
connection.onLogs(publicKey, (result) => {
const parsedTransactions = result.parsedTransactions;
if (!parsedTransactions.length) return; // Ignore empty arrays
const matchingTransactions = parsedTransactions.filter((transaction) => {
// Implement your program condition here
if (/ your condition /) {
returns true;
}
returns false;
});
console.log(matchingtransactions);
});
You can also use the getEntries method to get all transaction entries and then create a mapping from the entry IDs to the corresponding Web3Transaction objects:
const solana = require("solana-web3");
const connection = new solana.Connection();
connection.onLogs(publicKey, (result) => {
const transactions = result.parsedTransactions;
const entryToTransactionMap = {};
for (const transaction of transactions) {
const entryId = transaction.entryId.toString();
if (!entryToTransactionMap[entryId]) {
entryToTransactionMap[entryId] = {};
}
entryToTransactionMap[entryId][transaction.id.toString()] = transaction;
}
console.log(entryToTransactionMap);
});
Using either of these approaches, you should be able to parse transaction details even if the program condition is not met.
Add comment