Ethereum Web3.js Integration Guide
Web3.js is the original and most widely-used JavaScript library for interacting with the Ethereum blockchain. This guide covers everything from basic setup to advanced patterns using BlockEden.xyz's Ethereum infrastructure.
Overview
Web3.js provides a complete JavaScript API for Ethereum, including:
- Account Management: Create, import, and manage Ethereum accounts
- Smart Contract Interaction: Deploy and call smart contracts
- Transaction Handling: Send, sign, and monitor transactions
- Event Monitoring: Subscribe to blockchain events
- Utility Functions: Format conversions, hashing, and validation
Installation & Setup
Installation
# Using npm
npm install web3
# Using yarn
yarn add web3
# Using pnpm
pnpm add web3
Basic Setup
import { Web3 } from 'web3';
// Initialize with BlockEden.xyz endpoint
const web3 = new Web3('https://ethereum-mainnet.blockeden.xyz/<your-api-key>');
// Verify connection
async function testConnection() {
try {
const blockNumber = await web3.eth.getBlockNumber();
console.log('Current block number:', blockNumber);
console.log('Web3.js version:', web3.version);
} catch (error) {
console.error('Connection failed:', error);
}
}
testConnection();
Environment Configuration
// config/web3.js
import { Web3 } from 'web3';
const networks = {
mainnet: 'https://ethereum-mainnet.blockeden.xyz',
sepolia: 'https://ethereum-sepolia.blockeden.xyz',
polygon: 'https://polygon-mainnet.blockeden.xyz',
arbitrum: 'https://arbitrum-mainnet.blockeden.xyz'
};
export function createWeb3Instance(network = 'mainnet', apiKey) {
const rpcUrl = `${networks[network]}/${apiKey}`;
return new Web3(rpcUrl);
}
// Usage
const web3 = createWeb3Instance('mainnet', process.env.BLOCKEDEN_API_KEY);
Account Management
Creating Accounts
// Create a new account
const account = web3.eth.accounts.create();
console.log('Address:', account.address);
console.log('Private Key:', account.privateKey);
// Create multiple accounts
const accounts = web3.eth.accounts.create(5); // Creates 5 accounts
console.log('Generated accounts:', accounts);
// Create from entropy
const entropy = web3.utils.randomHex(32);
const accountFromEntropy = web3.eth.accounts.create(entropy);
Account Recovery
// Recover account from private key
const privateKey = '0x1234567890abcdef...';
const account = web3.eth.accounts.privateKeyToAccount(privateKey);
// Recover from mnemonic (requires additional library)
import { generateMnemonic, mnemonicToSeedSync } from 'bip39';
import { hdkey } from 'ethereumjs-wallet';
function recoverFromMnemonic(mnemonic, index = 0) {
const seed = mnemonicToSeedSync(mnemonic);
const hdwallet = hdkey.fromMasterSeed(seed);
const path = `m/44'/60'/0'/0/${index}`;
const wallet = hdwallet.derivePath(path).getWallet();
return web3.eth.accounts.privateKeyToAccount('0x' + wallet.getPrivateKey().toString('hex'));
}
// Usage
const mnemonic = 'your twelve word mnemonic phrase here...';
const account = recoverFromMnemonic(mnemonic, 0);
Wallet Management
class EthereumWallet {
constructor(web3Instance) {
this.web3 = web3Instance;
this.accounts = new Map();
}
// Add account to wallet
addAccount(privateKey, password) {
const account = this.web3.eth.accounts.privateKeyToAccount(privateKey);
const encrypted = this.web3.eth.accounts.encrypt(privateKey, password);
this.accounts.set(account.address.toLowerCase(), {
account,
encrypted
});
return account.address;
}
// Get account by address
getAccount(address) {
return this.accounts.get(address.toLowerCase())?.account;
}
// Sign transaction
async signTransaction(txObject, fromAddress, password) {
const accountData = this.accounts.get(fromAddress.toLowerCase());
if (!accountData) {
throw new Error('Account not found in wallet');
}
const decrypted = this.web3.eth.accounts.decrypt(accountData.encrypted, password);
return await this.web3.eth.accounts.signTransaction(txObject, decrypted.privateKey);
}
// Get all addresses
getAddresses() {
return Array.from(this.accounts.keys());
}
// Remove account
removeAccount(address) {
return this.accounts.delete(address.toLowerCase());
}
}
// Usage
const wallet = new EthereumWallet(web3);
const address = wallet.addAccount('0x1234...', 'password123');
console.log('Added account:', address);
Reading Blockchain Data
Account Information
// Get account balance
async function getAccountInfo(address) {
try {
// Balance in wei
const balanceWei = await web3.eth.getBalance(address);
// Convert to ether
const balanceEth = web3.utils.fromWei(balanceWei, 'ether');
// Transaction count (nonce)
const nonce = await web3.eth.getTransactionCount(address);
// Check if it's a contract
const code = await web3.eth.getCode(address);
const isContract = code !== '0x';
return {
address,
balance: {
wei: balanceWei,
eth: balanceEth
},
nonce,
isContract
};
} catch (error) {
console.error('Error getting account info:', error);
throw error;
}
}
// Usage
const info = await getAccountInfo('0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4');
console.log('Account info:', info);
Block Information
// Get latest block
async function getLatestBlock() {
const block = await web3.eth.getBlock('latest', true); // true = include transactions
return {
number: block.number,
hash: block.hash,
timestamp: new Date(Number(block.timestamp) * 1000),
gasUsed: block.gasUsed,
gasLimit: block.gasLimit,
transactionCount: block.transactions.length,
miner: block.miner
};
}
// Get block by number
async function getBlockByNumber(blockNumber) {
const block = await web3.eth.getBlock(blockNumber, false); // false = only tx hashes
return block;
}
// Get block range
async function getBlockRange(startBlock, endBlock) {
const blocks = [];
for (let i = startBlock; i <= endBlock; i++) {
const block = await web3.eth.getBlock(i, false);
blocks.push(block);
}
return blocks;
}
Transaction Information
// Get transaction details
async function getTransactionInfo(txHash) {
try {
// Get transaction
const tx = await web3.eth.getTransaction(txHash);
if (!tx) {
throw new Error('Transaction not found');
}
// Get receipt (only available for mined transactions)
const receipt = await web3.eth.getTransactionReceipt(txHash);
return {
hash: tx.hash,
status: receipt ? (receipt.status ? 'success' : 'failed') : 'pending',
blockNumber: tx.blockNumber,
from: tx.from,
to: tx.to,
value: web3.utils.fromWei(tx.value, 'ether'),
gasUsed: receipt ? receipt.gasUsed : null,
gasPrice: web3.utils.fromWei(tx.gasPrice, 'gwei'),
nonce: tx.nonce,
data: tx.input,
logs: receipt ? receipt.logs : null
};
} catch (error) {
console.error('Error getting transaction info:', error);
throw error;
}
}
// Monitor transaction status
async function waitForTransaction(txHash, timeout = 300000) { // 5 minutes default
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
try {
const receipt = await web3.eth.getTransactionReceipt(txHash);
if (receipt) {
return {
success: receipt.status,
receipt
};
}
// Wait 2 seconds before checking again
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
console.error('Error checking transaction:', error);
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
throw new Error('Transaction timeout');
}
Sending Transactions
Basic Ether Transfer
// Send Ether using private key
async function sendEther(fromPrivateKey, toAddress, amountEth) {
try {
const account = web3.eth.accounts.privateKeyToAccount(fromPrivateKey);
// Get current gas price
const gasPrice = await web3.eth.getGasPrice();
// Get nonce
const nonce = await web3.eth.getTransactionCount(account.address, 'pending');
// Build transaction
const tx = {
from: account.address,
to: toAddress,
value: web3.utils.toWei(amountEth, 'ether'),
gas: 21000, // Standard gas limit for ETH transfer
gasPrice: gasPrice,
nonce: nonce
};
// Sign transaction
const signedTx = await web3.eth.accounts.signTransaction(tx, fromPrivateKey);
// Send transaction
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
return {
txHash: receipt.transactionHash,
blockNumber: receipt.blockNumber,
gasUsed: receipt.gasUsed,
status: receipt.status
};
} catch (error) {
console.error('Error sending ether:', error);
throw error;
}
}
// Usage
const result = await sendEther(
'0x1234567890abcdef...', // private key
'0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4', // to address
'0.1' // amount in ETH
);
console.log('Transaction sent:', result);
EIP-1559 Transactions
// Send EIP-1559 transaction with dynamic fees
async function sendEIP1559Transaction(fromPrivateKey, toAddress, amountEth) {
try {
const account = web3.eth.accounts.privateKeyToAccount(fromPrivateKey);
// Get fee data
const feeHistory = await web3.eth.getFeeHistory(4, 'latest', [25, 50, 75]);
const baseFee = BigInt(feeHistory.baseFeePerGas[feeHistory.baseFeePerGas.length - 1]);
// Calculate priority fee (tip)
const maxPriorityFeePerGas = web3.utils.toWei('2', 'gwei'); // 2 gwei tip
// Max fee = base fee * 2 + priority fee (with buffer)
const maxFeePerGas = (baseFee * BigInt(2)) + BigInt(maxPriorityFeePerGas);
const nonce = await web3.eth.getTransactionCount(account.address, 'pending');
const tx = {
from: account.address,
to: toAddress,
value: web3.utils.toWei(amountEth, 'ether'),
gas: 21000,
maxFeePerGas: maxFeePerGas.toString(),
maxPriorityFeePerGas: maxPriorityFeePerGas,
nonce: nonce,
type: 2 // EIP-1559 transaction type
};
const signedTx = await web3.eth.accounts.signTransaction(tx, fromPrivateKey);
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
return receipt;
} catch (error) {
console.error('Error sending EIP-1559 transaction:', error);
throw error;
}
}
Gas Estimation
// Estimate gas for transaction
async function estimateTransactionGas(txObject) {
try {
const gasEstimate = await web3.eth.estimateGas(txObject);
const gasPrice = await web3.eth.getGasPrice();
// Add 20% buffer to gas estimate
const gasLimit = Math.ceil(gasEstimate * 1.2);
const cost = {
gasEstimate,
gasLimit,
gasPrice,
totalCostWei: BigInt(gasLimit) * BigInt(gasPrice),
totalCostEth: web3.utils.fromWei((BigInt(gasLimit) * BigInt(gasPrice)).toString(), 'ether')
};
return cost;
} catch (error) {
console.error('Error estimating gas:', error);
throw error;
}
}
// Usage
const txObject = {
from: '0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4',
to: '0xA0b86a33E6c0e4A2a2a5FB1C6A6D6a30BF8b6B3a',
value: web3.utils.toWei('1', 'ether')
};
const gasCost = await estimateTransactionGas(txObject);
console.log('Gas estimation:', gasCost);