blockchain-api
Version:
API utilities for interacting with the Exatechl2 blockchain
186 lines (149 loc) ⢠7.55 kB
text/typescript
import {
getLatestBlocks,
getLatestBlockNumber,
getBlockByNumber,
formatNumber,
parseHexToDecimal,
formatRelativeTime,
calculateGasPercentage,
formatGasValue,
truncateString
} from '../src';
// Import FormattedBlock type to properly handle the block data
import { FormattedBlock } from '../src/modules/blocks/utils';
/**
* Display blocks in a card-like format
*/
async function displayBlocks() {
try {
console.log('\nš Fetching latest blocks from Exatechl2 blockchain...');
// Pagination parameters
const page = 1;
const perPage = 10;
const includeTransactions = false;
// Get paginated blocks from the blockchain explorer
const { blocks, totalCount, totalPages } = await getLatestBlocks(page, perPage, includeTransactions);
// Format and display block data
console.log(`\nš Latest Blocks (Page ${page}/${totalPages}, Total: ${formatNumber(totalCount)})`);
console.log('Block\tAge\tTxn\tSize\tGas Used\tGas Limit\tBase Fee\tBatch ID\tStatus');
blocks.forEach((block: FormattedBlock, index) => {
// Get proper relative time
const relativeTime = formatRelativeTime(block.timestamp).split(' ').slice(0, 3).join(' ');
// Format gas values
const gasUsed = formatNumber(parseInt(block.gasUsed || '0'));
const gasPercentage = block.gasUsedPercentage !== undefined ? `(${block.gasUsedPercentage.toFixed(1)}%)` : '(0%)';
const gasLimit = formatNumber(parseInt(block.gasLimit || '0'));
// Format base fee with Gwei unit
const baseFee = block.baseFee ? `${block.baseFee} Gwei` : 'N/A';
// Format batch ID with # prefix
const batchId = block.batchId ? `#${block.batchId}` : 'N/A';
// Format status with capitalization
const status = block.status ? block.status.charAt(0).toUpperCase() + block.status.slice(1).toLowerCase() : 'N/A';
// Print block in card-like format
console.log(`${block.numberDecimal}`);
console.log(`${relativeTime}`);
console.log(`${block.txCount || 0}\t${block.size || 'N/A'}`);
console.log(`${gasUsed}`);
console.log(`${gasPercentage}`);
console.log(`${gasLimit}`);
console.log(`${baseFee}`);
console.log(`${batchId}`);
console.log(`${status}`);
// Add separator between blocks if not the last one
if (index < blocks.length - 1) {
console.log('ā'.repeat(40));
}
});
console.log(`\nShowing ${blocks.length} of ${formatNumber(totalCount)} blocks\n`);
// Get the very latest block from the chain using RPC
const latestBlockNumber = await getLatestBlockNumber();
console.log(`š“ Latest block via RPC: #${parseHexToDecimal(latestBlockNumber)}`);
// Get detailed information about the latest block
const blockDetails = await getBlockByNumber(latestBlockNumber, true);
// Format the values for display
const gasUsed = parseHexToDecimal(blockDetails.gasUsed || '0x0');
const gasLimit = parseHexToDecimal(blockDetails.gasLimit || '0x0');
const gasPercentage = calculateGasPercentage(blockDetails.gasUsed, blockDetails.gasLimit);
const baseFeePerGas = formatGasValue(blockDetails.baseFeePerGas || '0x0', 'gwei', 2);
console.log('\nš Latest Block Details:');
console.log(' Block Number:', parseHexToDecimal(blockDetails.number));
console.log(' Hash:', blockDetails.hash);
console.log(' Timestamp:', formatRelativeTime(blockDetails.timestamp));
console.log(' Transactions:', blockDetails.transactions.length);
console.log(' Gas Used:', formatNumber(gasUsed), `(${gasPercentage.toFixed(1)}%)`);
console.log(' Gas Limit:', formatNumber(gasLimit));
console.log(' Base Fee Per Gas:', baseFeePerGas);
console.log(' Batch ID:', blockDetails.batchId ? `#${blockDetails.batchId}` : 'N/A');
const status = blockDetails.status || blockDetails.batchStatus || 'N/A';
console.log(' Status:', status.charAt(0).toUpperCase() + status.slice(1).toLowerCase());
console.log(' Miner/Validator:', blockDetails.miner || blockDetails.validator || 'Unknown');
if (blockDetails.transactions.length > 0) {
console.log('\nš° First 3 Transactions:');
blockDetails.transactions.slice(0, 3).forEach((tx, index) => {
if (typeof tx === 'string') {
console.log(` ${index + 1}. ${tx}`);
} else {
console.log(` ${index + 1}. ${tx.hash} (From: ${truncateString(tx.from, 6, 4)} To: ${tx.to ? truncateString(tx.to, 6, 4) : 'Contract Creation'})`);
}
});
}
} catch (error) {
console.error('ā Error fetching blocks:', error);
}
}
/**
* Function to watch for new blocks in real-time
*/
async function watchBlocks(duration = 60000, interval = 5000) {
try {
console.log(`\nā±ļø Watching for new blocks for ${duration/1000} seconds...`);
let lastBlockNumber = await getLatestBlockNumber();
console.log(`Starting at block #${parseHexToDecimal(lastBlockNumber)}`);
const endTime = Date.now() + duration;
const intervalId = setInterval(async () => {
try {
const currentBlockNumber = await getLatestBlockNumber();
if (currentBlockNumber !== lastBlockNumber) {
console.log(`New block detected: #${parseHexToDecimal(currentBlockNumber)}`);
// Get block details
const block = await getBlockByNumber(currentBlockNumber, false);
// Format the values
const gasUsed = parseHexToDecimal(block.gasUsed || '0x0');
const gasLimit = parseHexToDecimal(block.gasLimit || '0x0');
const gasPercentage = calculateGasPercentage(block.gasUsed, block.gasLimit);
const status = block.status || block.batchStatus || 'N/A';
const statusFormatted = status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();
console.log(` Timestamp: ${formatRelativeTime(block.timestamp)}`);
console.log(` Transactions: ${block.transactions.length}`);
console.log(` Gas Used: ${formatNumber(gasUsed)} (${gasPercentage.toFixed(1)}%)`);
console.log(` Gas Limit: ${formatNumber(gasLimit)}`);
console.log(` Batch ID: ${block.batchId ? `#${block.batchId}` : 'N/A'}`);
console.log(` Status: ${statusFormatted}`);
lastBlockNumber = currentBlockNumber;
}
if (Date.now() >= endTime) {
clearInterval(intervalId);
console.log('\nā¹ļø Block watching complete');
}
} catch (error) {
console.error(' Error checking for new blocks:', error);
}
}, interval);
// Allow the function to complete after duration
await new Promise(resolve => setTimeout(resolve, duration + 100));
} catch (error) {
console.error('ā Error watching blocks:', error);
}
}
// Main function to run example
async function main() {
console.log('='.repeat(120));
console.log('š BLOCKCHAIN-API EXAMPLE: LIST BLOCKS');
console.log('='.repeat(120));
await displayBlocks();
// Uncomment to watch for new blocks in real-time
// await watchBlocks(30000); // Watch for 30 seconds
console.log('\nā
Example complete');
}
// Run the example
main().catch(console.error);