Reading and Listening to Transactions on VeChainThor

Blockchain applications often need to answer two simple questions: what happened, and when? Whether you're building dashboards, smart contract backends, or user wallets, getting transaction data is critical.

This guide walks you through two essential ways to work with transaction data on VeChainThor:

  • Reading transactions to inspect on-chain history

  • Listening for transactions in real time to power reactive applications

Let’s break down how each works, when to use them, and how to get started.

What Is a Transaction on VeChain?

A transaction on VeChainThor represents a request to make a change on the blockchain. This can be:

  • A simple VET transfer

  • A contract deployment

  • A function call to an existing smart contract

Each transaction can include multiple instructions (known as clauses), meaning a single transaction can interact with multiple recipients.

Key fields to understand:

  • id: The unique hash of the transaction

  • chainTag: Identifier of the blockchain network

  • blockRef: The block this transaction references

  • expiration: Number of blocks until the transaction becomes invalid

  • dependsOn: If present, the transaction ID this one depends on

  • origin: The address that initiated the transaction

  • meta: Block-level info, including timestamp and block number

  • reverted: Whether the transaction was reverted (failed)

  • clauses: List of instructions and data sent

  • outputs: All events or VET transfers triggered by the clauses

Full Transaction Details

When reading a transaction, there are two key components:

  1. Transaction Object: Contains input data and metadata

  2. Transaction Receipt: Contains results of execution, including:

  • Events emitted

  • VET transfers

  • Deployed contract addresses

  • Whether the transaction reverted

Code Example: Reading a Transaction

import { ThorClient } from '@vechain/sdk-network';
const nodeUrl = 'https://mainnet.vechain.org'; // Replace with the testnet or Solo node endpoint
console.log('Connecting to', nodeUrl);
const thor = ThorClient.at(nodeUrl);
// Replace with your transaction ID or use default
const txId = process.argv[2] ??
'0xfc99fe103fccbe61b3c042c1da3499b883d1b17fb40160ed1170ad5e63751e07';
// Fetch transaction details
const tx = await thor.transactions.getTransaction(txId);
console.log(tx);
// Fetch transaction receipt (execution result)
const txReceipt = await thor.transactions.getTransactionReceipt(txId);
console.log(txReceipt);

Listening Instead of Reading

While reading transactions gives you access to past and static data, sometimes you need to respond to blockchain activity as it happens. For example, tracking token movements in real time. That’s where listening comes in.

VeChain offers a native WebSocket-based system for subscribing to VET transfers.

You can connect to a node and subscribe to live VET transfer events like this:

import WebSocket from 'ws';
const ws = new WebSocket('wss://mainnet.vechain.org/subscriptions/transfer');
ws.onmessage = (message) => {
console.log('New transfer:', message.data);
};

This will return every VET transfer on the network as a JSON string.

To narrow your stream and only receive transfers relevant to your dApp, use the SDK’s helper:

const wsUrl = subscriptions.getVETtransfersSubscriptionUrl(
'https://mainnet.vechain.org',
{
blockID: undefined, // block id to start from, defaults to the best block.
signerAddress: undefined, // The address of the signer/origin of the transaction to filter transfers by.
sender: undefined, // The sender address to filter transfers by.
recipient: undefined, // The recipient address to filter transfers by.
}
);
// connect the WebSocket
console.log('Connecting to', wsUrl);
const ws = new WebSocket(wsUrl);

Each message includes:

{
"sender": "0xff5ba8...",
"recipient": "0xf1663a...",
"amount": "0xa7b7a750ac2f0400",
"meta": {
"blockNumber": 18341836,
"txID": "0xb5dc02...",
"blockTimestamp": 1713946150
}
}

You can decode the amount like this:

const readableAmount = BigInt(transferLog.amount); // In wei

This is especially useful in dApps that need to track payments or wallet activity in real time.

For more practical examples and testable snippets, explore the full Developer Fundamentals module on the VeChain Builders Academy.