wallet/getnowblock
Real-Time Block Data
Dwellir's TRON endpoints deliver the latest block information in under 20ms with 99.9% uptime. Stay synchronized with TRON's 3-second block times for real-time applications.
Retrieves the latest block information from the TRON network, including block number, timestamp, transactions, and block hash.
When to Use This Method
wallet/getnowblock
is essential for:
- Real-Time Monitoring - Track latest network activity and block production
- Block Synchronization - Keep applications synchronized with network state
- Transaction Confirmation - Monitor for transaction inclusion in new blocks
- Network Health Monitoring - Check block times and network performance
- Block Explorer Development - Display latest blocks and transactions
Parameters
No parameters required - This method returns the current latest block.
// No request body needed for this method
Returns
Block Object containing:
blockID
- Unique block identifier (hash)block_header
- Block header with metadatatransactions
- Array of transactions in the block
Block Header Structure
raw_data
- Raw block datanumber
- Block numbertxTrieRoot
- Transaction merkle rootwitness_address
- Block producer addressparentHash
- Previous block hashversion
- Protocol versiontimestamp
- Block timestamp in milliseconds
witness_signature
- Block producer signature
Implementation Examples
- JavaScript
- Python
- cURL
const TRON_API = 'https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY';
// Get the latest block
async function getLatestBlock() {
const response = await fetch(`${TRON_API}/wallet/getnowblock`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
// Enhanced block info with formatted data
async function getBlockInfo() {
try {
const block = await getLatestBlock();
return {
blockNumber: block.block_header.raw_data.number,
blockHash: block.blockID,
timestamp: block.block_header.raw_data.timestamp,
datetime: new Date(block.block_header.raw_data.timestamp).toISOString(),
transactionCount: block.transactions ? block.transactions.length : 0,
producer: block.block_header.raw_data.witness_address,
parentHash: block.block_header.raw_data.parentHash,
version: block.block_header.raw_data.version,
merkleRoot: block.block_header.raw_data.txTrieRoot,
transactions: block.transactions || []
};
} catch (error) {
console.error('Error fetching block info:', error);
throw error;
}
}
// Block monitoring with real-time updates
class TronBlockMonitor {
constructor(apiKey, pollInterval = 3000) {
this.apiKey = apiKey;
this.pollInterval = pollInterval;
this.lastBlockNumber = 0;
this.isRunning = false;
this.listeners = {
newBlock: [],
transaction: [],
error: []
};
}
on(event, callback) {
if (this.listeners[event]) {
this.listeners[event].push(callback);
}
}
emit(event, data) {
if (this.listeners[event]) {
this.listeners[event].forEach(callback => callback(data));
}
}
async start() {
this.isRunning = true;
console.log('Starting TRON block monitor...');
while (this.isRunning) {
try {
const blockInfo = await getBlockInfo();
if (blockInfo.blockNumber > this.lastBlockNumber) {
console.log(`New block #${blockInfo.blockNumber} with ${blockInfo.transactionCount} transactions`);
this.emit('newBlock', blockInfo);
// Emit transaction events
if (blockInfo.transactions) {
blockInfo.transactions.forEach(tx => {
this.emit('transaction', {
txId: tx.txID,
blockNumber: blockInfo.blockNumber,
transaction: tx
});
});
}
this.lastBlockNumber = blockInfo.blockNumber;
}
} catch (error) {
console.error('Block monitoring error:', error);
this.emit('error', error);
}
await new Promise(resolve => setTimeout(resolve, this.pollInterval));
}
}
stop() {
this.isRunning = false;
console.log('Block monitor stopped');
}
}
// Network performance analyzer
async function analyzeNetworkPerformance(sampleBlocks = 10) {
const blocks = [];
try {
// Get current block
let currentBlock = await getBlockInfo();
blocks.push(currentBlock);
// Get previous blocks (would need getBlockByNumber for historical data)
// This is a simplified example
console.log(`Analyzing network performance based on latest block...`);
const analysis = {
latestBlock: currentBlock.blockNumber,
timestamp: currentBlock.datetime,
transactionThroughput: currentBlock.transactionCount,
estimatedTPS: currentBlock.transactionCount / 3, // 3-second blocks
producer: currentBlock.producer,
blockTime: 3000, // TRON's target block time
networkHealth: currentBlock.transactionCount > 0 ? 'active' : 'low_activity'
};
return analysis;
} catch (error) {
console.error('Network analysis failed:', error);
throw error;
}
}
// Transaction finder - check if transaction is in latest blocks
async function findTransactionInRecentBlocks(txId, maxBlocks = 20) {
const foundIn = {
found: false,
blockNumber: null,
blockHash: null,
position: null
};
try {
// Check latest block
const block = await getLatestBlock();
if (block.transactions) {
const txIndex = block.transactions.findIndex(tx => tx.txID === txId);
if (txIndex !== -1) {
foundIn.found = true;
foundIn.blockNumber = block.block_header.raw_data.number;
foundIn.blockHash = block.blockID;
foundIn.position = txIndex;
}
}
return foundIn;
} catch (error) {
console.error('Transaction search failed:', error);
throw error;
}
}
// Usage examples
(async () => {
try {
// Get latest block info
const blockInfo = await getBlockInfo();
console.log('Latest block:', blockInfo.blockNumber);
console.log('Transactions:', blockInfo.transactionCount);
console.log('Timestamp:', blockInfo.datetime);
// Start block monitoring
const monitor = new TronBlockMonitor('YOUR_API_KEY');
monitor.on('newBlock', (block) => {
console.log(`📦 New block: #${block.blockNumber} (${block.transactionCount} txs)`);
});
monitor.on('transaction', (tx) => {
console.log(`💸 New transaction: ${tx.txId} in block ${tx.blockNumber}`);
});
// Start monitoring (comment out for non-continuous examples)
// await monitor.start();
// Analyze network performance
const performance = await analyzeNetworkPerformance();
console.log('Network performance:', performance);
} catch (error) {
console.error('Error:', error);
}
})();
import requests
import json
import time
import threading
from datetime import datetime
from typing import Dict, List, Optional, Callable
class TronBlockClient:
def __init__(self, api_key: str):
self.base_url = f"https://api-tron-mainnet.n.dwellir.com/{api_key}"
self.headers = {
'Content-Type': 'application/json'
}
def get_latest_block(self) -> Dict:
"""Get the latest block from TRON network"""
url = f"{self.base_url}/wallet/getnowblock"
response = requests.post(url, headers=self.headers)
response.raise_for_status()
return response.json()
def get_block_info(self) -> Dict:
"""Get formatted block information"""
try:
block = self.get_latest_block()
return {
'block_number': block['block_header']['raw_data']['number'],
'block_hash': block['blockID'],
'timestamp': block['block_header']['raw_data']['timestamp'],
'datetime': datetime.fromtimestamp(
block['block_header']['raw_data']['timestamp'] / 1000
).isoformat(),
'transaction_count': len(block.get('transactions', [])),
'producer': block['block_header']['raw_data']['witness_address'],
'parent_hash': block['block_header']['raw_data']['parentHash'],
'version': block['block_header']['raw_data']['version'],
'merkle_root': block['block_header']['raw_data']['txTrieRoot'],
'transactions': block.get('transactions', [])
}
except requests.RequestException as e:
print(f"Error fetching block info: {e}")
raise
def analyze_network_performance(self, sample_blocks: int = 10) -> Dict:
"""Analyze network performance based on latest block"""
try:
block_info = self.get_block_info()
analysis = {
'latest_block': block_info['block_number'],
'timestamp': block_info['datetime'],
'transaction_throughput': block_info['transaction_count'],
'estimated_tps': block_info['transaction_count'] / 3, # 3-second blocks
'producer': block_info['producer'],
'block_time_ms': 3000, # TRON's target block time
'network_health': 'active' if block_info['transaction_count'] > 0 else 'low_activity'
}
return analysis
except Exception as e:
print(f"Network analysis failed: {e}")
raise
def find_transaction_in_latest_block(self, tx_id: str) -> Dict:
"""Check if transaction is in the latest block"""
found_in = {
'found': False,
'block_number': None,
'block_hash': None,
'position': None
}
try:
block = self.get_latest_block()
if 'transactions' in block:
for index, tx in enumerate(block['transactions']):
if tx['txID'] == tx_id:
found_in['found'] = True
found_in['block_number'] = block['block_header']['raw_data']['number']
found_in['block_hash'] = block['blockID']
found_in['position'] = index
break
return found_in
except Exception as e:
print(f"Transaction search failed: {e}")
raise
class TronBlockMonitor:
def __init__(self, api_key: str, poll_interval: int = 3):
self.client = TronBlockClient(api_key)
self.poll_interval = poll_interval
self.last_block_number = 0
self.is_running = False
self.listeners = {
'new_block': [],
'transaction': [],
'error': []
}
self.monitor_thread = None
def on(self, event: str, callback: Callable):
"""Register event listener"""
if event in self.listeners:
self.listeners[event].append(callback)
def emit(self, event: str, data):
"""Emit event to listeners"""
if event in self.listeners:
for callback in self.listeners[event]:
callback(data)
def start(self):
"""Start block monitoring in background thread"""
if self.is_running:
return
self.is_running = True
self.monitor_thread = threading.Thread(target=self._monitor_loop)
self.monitor_thread.daemon = True
self.monitor_thread.start()
print("TRON block monitor started")
def stop(self):
"""Stop block monitoring"""
self.is_running = False
if self.monitor_thread:
self.monitor_thread.join()
print("TRON block monitor stopped")
def _monitor_loop(self):
"""Main monitoring loop"""
while self.is_running:
try:
block_info = self.client.get_block_info()
if block_info['block_number'] > self.last_block_number:
print(f"New block #{block_info['block_number']} "
f"with {block_info['transaction_count']} transactions")
self.emit('new_block', block_info)
# Emit transaction events
for tx in block_info['transactions']:
self.emit('transaction', {
'tx_id': tx['txID'],
'block_number': block_info['block_number'],
'transaction': tx
})
self.last_block_number = block_info['block_number']
except Exception as e:
print(f"Block monitoring error: {e}")
self.emit('error', e)
time.sleep(self.poll_interval)
class TronNetworkStats:
def __init__(self, api_key: str):
self.client = TronBlockClient(api_key)
self.stats_history = []
def collect_stats(self, duration_minutes: int = 10):
"""Collect network statistics over time"""
start_time = time.time()
end_time = start_time + (duration_minutes * 60)
print(f"Collecting TRON network stats for {duration_minutes} minutes...")
while time.time() < end_time:
try:
block_info = self.client.get_block_info()
stats = {
'timestamp': time.time(),
'block_number': block_info['block_number'],
'transaction_count': block_info['transaction_count'],
'producer': block_info['producer']
}
self.stats_history.append(stats)
print(f"Block #{block_info['block_number']}: "
f"{block_info['transaction_count']} transactions")
time.sleep(3) # Check every 3 seconds (block time)
except Exception as e:
print(f"Stats collection error: {e}")
time.sleep(1)
return self.analyze_collected_stats()
def analyze_collected_stats(self) -> Dict:
"""Analyze collected statistics"""
if not self.stats_history:
return {'error': 'No statistics collected'}
total_transactions = sum(stat['transaction_count'] for stat in self.stats_history)
total_blocks = len(self.stats_history)
duration_seconds = (self.stats_history[-1]['timestamp'] -
self.stats_history[0]['timestamp'])
producers = {}
for stat in self.stats_history:
producer = stat['producer']
producers[producer] = producers.get(producer, 0) + 1
analysis = {
'total_blocks_observed': total_blocks,
'total_transactions': total_transactions,
'average_tx_per_block': total_transactions / total_blocks if total_blocks > 0 else 0,
'average_tps': total_transactions / duration_seconds if duration_seconds > 0 else 0,
'duration_seconds': duration_seconds,
'block_producers': producers,
'most_active_producer': max(producers.items(), key=lambda x: x[1])[0] if producers else None
}
return analysis
# Usage examples
if __name__ == "__main__":
client = TronBlockClient('YOUR_API_KEY')
try:
# Get latest block info
block_info = client.get_block_info()
print(f"Latest block: #{block_info['block_number']}")
print(f"Transactions: {block_info['transaction_count']}")
print(f"Timestamp: {block_info['datetime']}")
# Analyze network performance
performance = client.analyze_network_performance()
print(f"Network performance: {performance}")
# Set up block monitoring
monitor = TronBlockMonitor('YOUR_API_KEY')
def on_new_block(block):
print(f"📦 New block: #{block['block_number']} "
f"({block['transaction_count']} txs)")
def on_transaction(tx):
print(f"💸 New transaction: {tx['tx_id']} "
f"in block {tx['block_number']}")
monitor.on('new_block', on_new_block)
monitor.on('transaction', on_transaction)
# Start monitoring (uncomment for continuous monitoring)
# monitor.start()
# time.sleep(30) # Monitor for 30 seconds
# monitor.stop()
# Collect network statistics
stats_collector = TronNetworkStats('YOUR_API_KEY')
# stats = stats_collector.collect_stats(1) # Collect for 1 minute
# print(f"Network statistics: {stats}")
except Exception as e:
print(f"Error: {e}")
# Get the latest block
curl -X POST "https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getnowblock" \
-H "Content-Type: application/json"
# Extract key information from latest block
curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/YOUR_API_KEY/wallet/getnowblock" \
-H "Content-Type: application/json" | jq '{
block_number: .block_header.raw_data.number,
block_hash: .blockID,
timestamp: .block_header.raw_data.timestamp,
datetime: (.block_header.raw_data.timestamp / 1000 | strftime("%Y-%m-%d %H:%M:%S")),
transaction_count: (.transactions // [] | length),
producer: .block_header.raw_data.witness_address
}'
# Monitor for new blocks (bash script)
#!/bin/bash
API_KEY="YOUR_API_KEY"
LAST_BLOCK=0
echo "Starting TRON block monitor..."
while true; do
# Get latest block
RESPONSE=$(curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/$API_KEY/wallet/getnowblock" \
-H "Content-Type: application/json")
# Extract block number
CURRENT_BLOCK=$(echo "$RESPONSE" | jq -r '.block_header.raw_data.number')
if [ "$CURRENT_BLOCK" != "null" ] && [ "$CURRENT_BLOCK" -gt "$LAST_BLOCK" ]; then
# Extract block info
BLOCK_HASH=$(echo "$RESPONSE" | jq -r '.blockID')
TIMESTAMP=$(echo "$RESPONSE" | jq -r '.block_header.raw_data.timestamp')
TX_COUNT=$(echo "$RESPONSE" | jq -r '(.transactions // [] | length)')
PRODUCER=$(echo "$RESPONSE" | jq -r '.block_header.raw_data.witness_address')
# Convert timestamp to readable format
DATETIME=$(date -d "@$((TIMESTAMP / 1000))" "+%Y-%m-%d %H:%M:%S")
echo "📦 Block #$CURRENT_BLOCK | $TX_COUNT txs | $DATETIME | Producer: $PRODUCER"
# Log transactions in block
if [ "$TX_COUNT" -gt 0 ]; then
echo "$RESPONSE" | jq -r '.transactions[]?.txID' | while read -r txid; do
echo " 💸 Transaction: $txid"
done
fi
LAST_BLOCK=$CURRENT_BLOCK
fi
sleep 3 # Check every 3 seconds (TRON block time)
done
# Network performance analysis script
#!/bin/bash
API_KEY="YOUR_API_KEY"
DURATION=${1:-60} # Duration in seconds, default 60
echo "Collecting TRON network statistics for $DURATION seconds..."
START_TIME=$(date +%s)
END_TIME=$((START_TIME + DURATION))
TOTAL_BLOCKS=0
TOTAL_TXS=0
BLOCKS_FILE="/tmp/tron_blocks.json"
> "$BLOCKS_FILE" # Clear file
while [ $(date +%s) -lt $END_TIME ]; do
RESPONSE=$(curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/$API_KEY/wallet/getnowblock" \
-H "Content-Type: application/json")
BLOCK_NUMBER=$(echo "$RESPONSE" | jq -r '.block_header.raw_data.number')
TX_COUNT=$(echo "$RESPONSE" | jq -r '(.transactions // [] | length)')
if [ "$BLOCK_NUMBER" != "null" ]; then
echo "$RESPONSE" >> "$BLOCKS_FILE"
echo "Block #$BLOCK_NUMBER with $TX_COUNT transactions"
((TOTAL_BLOCKS++))
TOTAL_TXS=$((TOTAL_TXS + TX_COUNT))
fi
sleep 3
done
# Calculate statistics
if [ $TOTAL_BLOCKS -gt 0 ]; then
AVG_TXS_PER_BLOCK=$((TOTAL_TXS / TOTAL_BLOCKS))
AVG_TPS=$((TOTAL_TXS / DURATION))
echo ""
echo "=== TRON Network Statistics ==="
echo "Duration: $DURATION seconds"
echo "Total blocks observed: $TOTAL_BLOCKS"
echo "Total transactions: $TOTAL_TXS"
echo "Average transactions per block: $AVG_TXS_PER_BLOCK"
echo "Average TPS: $AVG_TPS"
# Find most active producer
echo ""
echo "Block producers:"
jq -r '.block_header.raw_data.witness_address' "$BLOCKS_FILE" | sort | uniq -c | sort -nr | head -5
else
echo "No blocks collected during monitoring period"
fi
# Cleanup
rm -f "$BLOCKS_FILE"
# Real-time transaction finder
find_transaction_in_blocks() {
local TX_ID=$1
local MAX_CHECKS=${2:-20}
local CHECK_COUNT=0
echo "Searching for transaction $TX_ID in recent blocks..."
while [ $CHECK_COUNT -lt $MAX_CHECKS ]; do
RESPONSE=$(curl -s -X POST "https://api-tron-mainnet.n.dwellir.com/$API_KEY/wallet/getnowblock" \
-H "Content-Type: application/json")
# Check if transaction is in this block
FOUND=$(echo "$RESPONSE" | jq -r --arg txid "$TX_ID" '
.transactions[]? | select(.txID == $txid) | .txID
')
if [ "$FOUND" = "$TX_ID" ]; then
BLOCK_NUMBER=$(echo "$RESPONSE" | jq -r '.block_header.raw_data.number')
BLOCK_HASH=$(echo "$RESPONSE" | jq -r '.blockID')
echo "✓ Transaction found in block #$BLOCK_NUMBER ($BLOCK_HASH)"
return 0
fi
echo "Checking block... ($((CHECK_COUNT + 1))/$MAX_CHECKS)"
((CHECK_COUNT++))
sleep 3
done
echo "✗ Transaction not found in the last $MAX_CHECKS blocks"
return 1
}
# Usage examples:
# ./script.sh # Monitor blocks
# ./script.sh performance 120 # Collect stats for 2 minutes
# ./script.sh find TX_ID_HERE # Find transaction in recent blocks
case "${1:-monitor}" in
"performance")
# Run performance analysis
;;
"find")
find_transaction_in_blocks "$2"
;;
*)
# Default: monitor blocks
;;
esac
Response Examples
Latest Block Response
{
"blockID": "00000000032a9c4bd8b6b8e1a8e8d6c4b2a09f8e7d6c5b4a39291807f6e5d4c3b2",
"block_header": {
"raw_data": {
"number": 52895819,
"txTrieRoot": "0000000000000000000000000000000000000000000000000000000000000000",
"witness_address": "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
"parentHash": "00000000032a9c4a9d8b6b8e1a8e8d6c4b2a09f8e7d6c5b4a39291807f6e5d4c3",
"version": 27,
"timestamp": 1734567890000
},
"witness_signature": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890"
},
"transactions": [
{
"ret": [{"contractRet": "SUCCESS"}],
"signature": ["7a8b9c0d1e2f3456789012345678901234567890123456789012345678901234567890"],
"txID": "94eea63bb6774c8fc4f4c9d1b62c1e8c2f7c8c2e4d3a2b1c0d9e8f7a6b5c4d3e2f1",
"raw_data": {
"contract": [
{
"parameter": {
"value": {
"amount": 1000000,
"owner_address": "TJmmqjb1DK9TTZbQXzRQ2AuA94z4gKAPFh",
"to_address": "TRX6Q82wMqWNbCCmJPLz9mR8AZwqvUU2pN"
},
"type_url": "type.googleapis.com/protocol.TransferContract"
},
"type": "TransferContract"
}
],
"ref_block_bytes": "9c4a",
"ref_block_hash": "b8e1a8e8d6c4b2a0",
"expiration": 1734567950000,
"timestamp": 1734567890000
}
}
]
}
Empty Block Response
{
"blockID": "00000000032a9c4bd8b6b8e1a8e8d6c4b2a09f8e7d6c5b4a39291807f6e5d4c3b2",
"block_header": {
"raw_data": {
"number": 52895820,
"txTrieRoot": "0000000000000000000000000000000000000000000000000000000000000000",
"witness_address": "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
"parentHash": "00000000032a9c4a9d8b6b8e1a8e8d6c4b2a09f8e7d6c5b4a39291807f6e5d4c3",
"version": 27,
"timestamp": 1734567893000
},
"witness_signature": "a1b2c3d4e5f6789012345678901234567890123456789012345678901234567890"
}
}
Common Use Cases
1. Real-Time Block Explorer
class TronBlockExplorer {
constructor(apiKey) {
this.client = new TronBlockClient(apiKey);
this.blockCache = new Map();
this.subscribers = new Set();
}
async getLatestBlockData() {
try {
const blockInfo = await this.client.getBlockInfo();
// Cache block data
this.blockCache.set(blockInfo.blockNumber, blockInfo);
// Keep only last 100 blocks in cache
if (this.blockCache.size > 100) {
const oldestBlock = Math.min(...this.blockCache.keys());
this.blockCache.delete(oldestBlock);
}
return {
...blockInfo,
cached: false,
timeAgo: this.calculateTimeAgo(blockInfo.timestamp)
};
} catch (error) {
console.error('Failed to fetch block data:', error);
throw error;
}
}
calculateTimeAgo(timestamp) {
const now = Date.now();
const diff = now - timestamp;
if (diff < 10000) return 'just now';
if (diff < 60000) return `${Math.floor(diff / 1000)}s ago`;
if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
return `${Math.floor(diff / 3600000)}h ago`;
}
subscribeToBlocks(callback) {
this.subscribers.add(callback);
return () => this.subscribers.delete(callback);
}
async startRealTimeUpdates() {
setInterval(async () => {
try {
const blockData = await this.getLatestBlockData();
this.subscribers.forEach(callback => callback(blockData));
} catch (error) {
console.error('Real-time update failed:', error);
}
}, 3000);
}
}
2. Transaction Confirmation Tracker
class TransactionConfirmationTracker {
constructor(apiKey) {
this.client = new TronBlockClient(apiKey);
this.pendingTransactions = new Map();
this.confirmedTransactions = new Map();
}
async trackTransaction(txId, requiredConfirmations = 1) {
this.pendingTransactions.set(txId, {
txId,
requiredConfirmations,
currentConfirmations: 0,
firstSeenBlock: null,
startTime: Date.now()
});
return new Promise((resolve, reject) => {
const checkConfirmation = async () => {
try {
const found = await this.client.findTransactionInLatestBlock(txId);
if (found.found) {
const tracking = this.pendingTransactions.get(txId);
if (!tracking.firstSeenBlock) {
tracking.firstSeenBlock = found.blockNumber;
}
// Calculate confirmations based on current block
const latestBlock = await this.client.getBlockInfo();
const confirmations = latestBlock.blockNumber - tracking.firstSeenBlock + 1;
tracking.currentConfirmations = confirmations;
if (confirmations >= requiredConfirmations) {
this.pendingTransactions.delete(txId);
this.confirmedTransactions.set(txId, {
...tracking,
confirmedAt: Date.now(),
finalBlockNumber: latestBlock.blockNumber
});
resolve({
confirmed: true,
confirmations,
blockNumber: tracking.firstSeenBlock,
confirmationTime: Date.now() - tracking.startTime
});
}
}
// Continue checking
setTimeout(checkConfirmation, 3000);
} catch (error) {
reject(error);
}
};
checkConfirmation();
});
}
getTransactionStatus(txId) {
if (this.confirmedTransactions.has(txId)) {
return { status: 'confirmed', ...this.confirmedTransactions.get(txId) };
}
if (this.pendingTransactions.has(txId)) {
return { status: 'pending', ...this.pendingTransactions.get(txId) };
}
return { status: 'unknown' };
}
}
3. Network Health Monitor
class TronNetworkHealthMonitor {
constructor(apiKey) {
this.client = new TronBlockClient(apiKey);
this.healthMetrics = {
blockTimes: [],
transactionCounts: [],
producers: new Map(),
lastUpdate: null
};
}
async startMonitoring(durationMinutes = 60) {
const endTime = Date.now() + (durationMinutes * 60 * 1000);
let lastBlockNumber = 0;
let lastBlockTime = null;
console.log(`Starting network health monitoring for ${durationMinutes} minutes...`);
while (Date.now() < endTime) {
try {
const blockInfo = await this.client.getBlockInfo();
if (blockInfo.blockNumber > lastBlockNumber) {
// Calculate block time
if (lastBlockTime) {
const blockTime = blockInfo.timestamp - lastBlockTime;
this.healthMetrics.blockTimes.push(blockTime);
}
// Track transaction count
this.healthMetrics.transactionCounts.push(blockInfo.transactionCount);
// Track producer
const producer = blockInfo.producer;
this.healthMetrics.producers.set(
producer,
(this.healthMetrics.producers.get(producer) || 0) + 1
);
lastBlockNumber = blockInfo.blockNumber;
lastBlockTime = blockInfo.timestamp;
console.log(`Block #${blockInfo.blockNumber}: ${blockInfo.transactionCount} txs, Producer: ${producer}`);
}
await new Promise(resolve => setTimeout(resolve, 3000));
} catch (error) {
console.error('Health monitoring error:', error);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
return this.generateHealthReport();
}
generateHealthReport() {
const { blockTimes, transactionCounts, producers } = this.healthMetrics;
const avgBlockTime = blockTimes.length > 0
? blockTimes.reduce((a, b) => a + b, 0) / blockTimes.length
: 0;
const avgTxPerBlock = transactionCounts.length > 0
? transactionCounts.reduce((a, b) => a + b, 0) / transactionCounts.length
: 0;
const totalTx = transactionCounts.reduce((a, b) => a + b, 0);
const avgTPS = totalTx / (blockTimes.length * (avgBlockTime / 1000));
// Analyze producer distribution
const totalBlocks = producers.size > 0
? Array.from(producers.values()).reduce((a, b) => a + b, 0)
: 0;
const producerStats = Array.from(producers.entries())
.map(([address, count]) => ({
address,
blocks: count,
percentage: (count / totalBlocks * 100).toFixed(2)
}))
.sort((a, b) => b.blocks - a.blocks);
return {
monitoringPeriod: {
blocksObserved: blockTimes.length,
totalTransactions: totalTx,
uniqueProducers: producers.size
},
performance: {
averageBlockTime: avgBlockTime.toFixed(2) + 'ms',
targetBlockTime: '3000ms',
blockTimeVariance: this.calculateVariance(blockTimes).toFixed(2),
averageTransactionsPerBlock: avgTxPerBlock.toFixed(2),
averageTPS: avgTPS.toFixed(2)
},
networkHealth: {
status: avgBlockTime < 4000 && avgBlockTime > 2000 ? 'healthy' : 'concerning',
blockTimeHealth: avgBlockTime < 4000 ? 'good' : 'slow',
transactionActivity: avgTxPerBlock > 1 ? 'active' : 'low'
},
producers: producerStats.slice(0, 10), // Top 10 producers
recommendations: this.generateRecommendations(avgBlockTime, avgTxPerBlock, producers.size)
};
}
calculateVariance(values) {
if (values.length === 0) return 0;
const mean = values.reduce((a, b) => a + b, 0) / values.length;
const variance = values.reduce((acc, val) => acc + Math.pow(val - mean, 2), 0) / values.length;
return Math.sqrt(variance);
}
generateRecommendations(avgBlockTime, avgTxPerBlock, producerCount) {
const recommendations = [];
if (avgBlockTime > 4000) {
recommendations.push('Block times are slower than expected - monitor network congestion');
}
if (avgTxPerBlock < 1) {
recommendations.push('Low transaction activity - network may be underutilized');
}
if (producerCount < 20) {
recommendations.push('Limited producer diversity observed - consider longer monitoring period');
}
if (recommendations.length === 0) {
recommendations.push('Network appears to be operating normally');
}
return recommendations;
}
}
4. DApp Synchronization Service
class TronDAppSync {
constructor(apiKey, contractAddresses = []) {
this.client = new TronBlockClient(apiKey);
this.contractAddresses = contractAddresses;
this.lastSyncedBlock = 0;
this.eventHandlers = new Map();
}
onContractEvent(contractAddress, eventType, handler) {
const key = `${contractAddress}:${eventType}`;
if (!this.eventHandlers.has(key)) {
this.eventHandlers.set(key, []);
}
this.eventHandlers.get(key).push(handler);
}
async syncToLatest() {
try {
const latestBlock = await this.client.getBlockInfo();
if (latestBlock.blockNumber > this.lastSyncedBlock) {
console.log(`Syncing to block #${latestBlock.blockNumber}...`);
// Process transactions in the latest block
await this.processBlockTransactions(latestBlock);
this.lastSyncedBlock = latestBlock.blockNumber;
return {
syncedToBlock: latestBlock.blockNumber,
transactionsProcessed: latestBlock.transactionCount,
timestamp: latestBlock.datetime
};
}
return {
syncedToBlock: this.lastSyncedBlock,
message: 'Already up to date'
};
} catch (error) {
console.error('Sync failed:', error);
throw error;
}
}
async processBlockTransactions(blockInfo) {
for (const tx of blockInfo.transactions) {
if (this.isContractTransaction(tx)) {
await this.processContractTransaction(tx, blockInfo.blockNumber);
}
}
}
isContractTransaction(tx) {
if (!tx.raw_data?.contract?.[0]) return false;
const contract = tx.raw_data.contract[0];
const contractAddress = contract.parameter?.value?.contract_address;
return this.contractAddresses.includes(contractAddress);
}
async processContractTransaction(tx, blockNumber) {
const contract = tx.raw_data.contract[0];
const contractAddress = contract.parameter?.value?.contract_address;
const contractType = contract.type;
// Emit events for contract interactions
const eventKey = `${contractAddress}:${contractType}`;
const handlers = this.eventHandlers.get(eventKey) || [];
for (const handler of handlers) {
try {
await handler({
txId: tx.txID,
contractAddress,
contractType,
blockNumber,
transaction: tx
});
} catch (error) {
console.error(`Event handler error for ${eventKey}:`, error);
}
}
}
async startAutoSync(intervalSeconds = 3) {
console.log(`Starting auto-sync every ${intervalSeconds} seconds...`);
const syncInterval = setInterval(async () => {
try {
const result = await this.syncToLatest();
if (result.transactionsProcessed > 0) {
console.log(`Synced: Block #${result.syncedToBlock} (${result.transactionsProcessed} txs)`);
}
} catch (error) {
console.error('Auto-sync error:', error);
}
}, intervalSeconds * 1000);
return () => clearInterval(syncInterval);
}
}
Performance Tips
- Efficient Polling - Use 3-second intervals to match TRON's block time
- Cache Management - Cache recent block data to avoid redundant requests
- Event-Driven Updates - Use real-time monitoring instead of constant polling
- Batch Processing - Process multiple transactions efficiently
// Optimized block monitoring with caching
class OptimizedBlockMonitor {
constructor(apiKey, options = {}) {
this.client = new TronBlockClient(apiKey);
this.cache = new Map();
this.options = {
cacheSize: 100,
pollInterval: 3000,
...options
};
}
async getBlockWithCache(blockNumber = 'latest') {
if (blockNumber === 'latest') {
// Always fetch latest block
const block = await this.client.getBlockInfo();
this.addToCache(block.blockNumber, block);
return block;
}
// Check cache first
if (this.cache.has(blockNumber)) {
return this.cache.get(blockNumber);
}
// Fetch and cache
const block = await this.client.getBlockInfo();
this.addToCache(block.blockNumber, block);
return block;
}
addToCache(blockNumber, block) {
this.cache.set(blockNumber, block);
// Maintain cache size
if (this.cache.size > this.options.cacheSize) {
const oldestKey = Math.min(...this.cache.keys());
this.cache.delete(oldestKey);
}
}
}
Need help? Contact our support team or check the TRON documentation.