Adding this post for documentation purpose
Here is sample code that works to decode a Streams API transaction
Test result:
npx ts-node streams-parse-data.ts
Decoded logs:
[
{
tokenId: BigNumber { _hex: '0x16', _isBigNumber: true },
ownerAddress: '0xF875570D1F34BE1d257652edcB555563D9a1bEBD',
price: BigNumber { _hex: '0x016345785d8a0000', _isBigNumber: true }
}
]
Decoded logs hex to String:
22 0xF875570D1F34BE1d257652edcB555563D9a1bEBD 100000000000000000
- We can see that it returns the decoded price of the nft, which was included in this particular transaction:
100000000000000000
Code:
import Moralis from 'moralis';
import { BigNumber } from '@moralisweb3/core';
import Web3 from "web3";
const test = async () => {
interface URI {
tokenId: BigNumber;
ownerAddress: string;
price: BigNumber;
}
const webhookData = {
"confirmed": true,
"chainId": "0x89",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "address",
"name": "ownerAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "price",
"type": "uint256"
}
],
"name": "TokenMinted",
"type": "event"
}
],
"streamId": "64369ded-7b7f-457c-b197-a21f23596eb6",
"tag": "demo",
"retries": 0,
"block": {
"number": "43026298",
"hash": "0x09a8436dbd0af482a85f43a0f0bd86c3abaf6a9a985ad80bb52e71d76e704229",
"timestamp": "1684790720"
},
"logs": [
{
"logIndex": "2",
"transactionHash": "0x0e2c6856dfce372f2fc9d45b0a3faa8e0e3908810f9af8e20a74ad008a1d7f16",
"address": "0xaf6383b404c2dc5ec742863076043c57cddaf61d",
"data": "0x000000000000000000000000f875570d1f34be1d257652edcb555563d9a1bebd000000000000000000000000000000000000000000000000016345785d8a0000",
"topic0": "0x2d03118aa776f7008445f6ca8490a6782ede2db364d741513555ba656ab1879f",
"topic1": "0x0000000000000000000000000000000000000000000000000000000000000016",
"topic2": null,
"topic3": null
},
{
"logIndex": "0",
"transactionHash": "0x0e2c6856dfce372f2fc9d45b0a3faa8e0e3908810f9af8e20a74ad008a1d7f16",
"address": "0xaf6383b404c2dc5ec742863076043c57cddaf61d",
"data": "0x",
"topic0": "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"topic1": "0x0000000000000000000000000000000000000000000000000000000000000000",
"topic2": "0x000000000000000000000000f875570d1f34be1d257652edcb555563d9a1bebd",
"topic3": "0x0000000000000000000000000000000000000000000000000000000000000016"
},
{
"logIndex": "1",
"transactionHash": "0x0e2c6856dfce372f2fc9d45b0a3faa8e0e3908810f9af8e20a74ad008a1d7f16",
"address": "0xaf6383b404c2dc5ec742863076043c57cddaf61d",
"data": "0x000000000000000000000000000000000000000000000000016345785d8a0000",
"topic0": "0x945c1c4e99aa89f648fbfe3df471b916f719e16d960fcec0737d4d56bd696838",
"topic1": "0x0000000000000000000000000000000000000000000000000000000000000016",
"topic2": null,
"topic3": null
},
{
"logIndex": "3",
"transactionHash": "0x0e2c6856dfce372f2fc9d45b0a3faa8e0e3908810f9af8e20a74ad008a1d7f16",
"address": "0x0000000000000000000000000000000000001010",
"data": "0x000000000000000000000000000000000000000000000000010339c9efcc534c0000000000000000000000000000000000000000000000001a5b32062e9c8c000000000000000000000000000000000000000000000018a25734fc0dfdd534b90000000000000000000000000000000000000000000000001957f83c3ed038b40000000000000000000000000000000000000000000018a2583835d7eda18805",
"topic0": "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
"topic1": "0x0000000000000000000000000000000000000000000000000000000000001010",
"topic2": "0x000000000000000000000000f875570d1f34be1d257652edcb555563d9a1bebd",
"topic3": "0x00000000000000000000000067b94473d81d0cd00849d563c94d0432ac988b49"
}
,
],
txs: [],
txsInternal: [],
erc20Transfers: [],
erc20Approvals: [],
nftApprovals: { ERC1155: [], ERC721: [] },
nftTransfers: [],
nativeBalances: [],
nftTokenApprovals: []
};
const { logs } = webhookData;
const eventSignature = "TokenMinted(uint256,address,uint256)";
const eventHash = Web3.utils.keccak256(eventSignature);
const matchedLog = logs.find((log) => log.topic0 === eventHash);
webhookData.logs = matchedLog ? [matchedLog] : [];
console.log("\nDecoded logs:")
const decodedLogs: Array<URI> = Moralis.Streams.parsedLogs<URI>(webhookData);
const { tokenId, ownerAddress, price } = decodedLogs[0];
console.log(decodedLogs);
console.log("\nDecoded logs hex to String:")
console.log(tokenId.toString(), ownerAddress, price.toString());
};
test();
Where does this code go? In the webhook? My webhook is on AWSβ¦
Hi @futurehelp this code is to be run in a server-side environment such as node.js server like express.js or AWS Lambda function that would trigger based on when the webhook is received to process the data using the example code logic above.
This wonβt work on lambda or be inefficient for testing as we are on mainnet and all of the dependencies are too big for inline coding. We would have to edit, upload, test with real money, hope it works, and if it fails, repeat the entire process for every new line of code we change. This is just not efficient =(
@futurehelp setting up an online development environment with AWS Cloud9 should help alleviate the development cycle, this is intended to deploy to Lambda using external libraries what is needed in this case: https://repost.aws/knowledge-center/cloud9-deploy-lambda-external-libraries
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.