Skip to main content

Ethereum Web3.js Integration Guide

Complete guide to integrating Ethereum blockchain functionality using Web3.js library with bex.co infrastructure. From basic setup to advanced patterns.

Share
Last updated on August 19, 2026

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 bex.co'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

bash
# Using npm
npm install web3
 
# Using yarn
yarn add web3
 
# Using pnpm
pnpm add web3

Basic Setup

javascript
import { Web3 } from 'web3';
 
// Initialize with bex.co endpoint
const web3 = new Web3('https://ethereum-mainnet.bex.co/<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

javascript
// config/web3.js
import { Web3 } from 'web3';
 
const networks = {
  mainnet: 'https://ethereum-mainnet.bex.co',
  sepolia: 'https://ethereum-sepolia.bex.co',
  polygon: 'https://polygon-mainnet.bex.co',
  arbitrum: 'https://arbitrum-mainnet.bex.co'
};
 
export function createWeb3Instance(network = 'mainnet', apiKey) {
  const rpcUrl = `${networks[network]}/${apiKey}`;
  return new Web3(rpcUrl);
}
 
// Usage
const web3 = createWeb3Instance('mainnet', process.env.BEX_API_KEY);

Account Management

Creating Accounts

javascript
// 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

javascript
// 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

javascript
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

javascript
// 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

javascript
// 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

javascript
// 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

javascript
// 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

javascript
// 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

javascript
// 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);

Smart Contract Interaction

Contract Instance Creation

javascript
// ERC-20 Token ABI (simplified)
const erc20ABI = [
  {
    "constant": true,
    "inputs": [],
    "name": "name",
    "outputs": [{"name": "", "type": "string"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "symbol",
    "outputs": [{"name": "", "type": "string"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [],
    "name": "decimals",
    "outputs": [{"name": "", "type": "uint8"}],
    "type": "function"
  },
  {
    "constant": true,
    "inputs": [{"name": "_owner", "type": "address"}],
    "name": "balanceOf",
    "outputs": [{"name": "balance", "type": "uint256"}],
    "type": "function"
  },
  {
    "constant": false,
    "inputs": [
      {"name": "_to", "type": "address"},
      {"name": "_value", "type": "uint256"}
    ],
    "name": "transfer",
    "outputs": [{"name": "", "type": "bool"}],
    "type": "function"
  },
  {
    "anonymous": false,
    "inputs": [
      {"indexed": true, "name": "from", "type": "address"},
      {"indexed": true, "name": "to", "type": "address"},
      {"indexed": false, "name": "value", "type": "uint256"}
    ],
    "name": "Transfer",
    "type": "event"
  }
];
 
// Create contract instance
const tokenAddress = '0xA0b86a33E6c0e4A2a2a5FB1C6A6D6a30BF8b6B3a'; // USDC example
const tokenContract = new web3.eth.Contract(erc20ABI, tokenAddress);

Reading from Contracts

javascript
// Read token information
async function getTokenInfo(tokenContract) {
  try {
    const [name, symbol, decimals] = await Promise.all([
      tokenContract.methods.name().call(),
      tokenContract.methods.symbol().call(),
      tokenContract.methods.decimals().call()
    ]);
    
    return {
      name,
      symbol,
      decimals: parseInt(decimals)
    };
  } catch (error) {
    console.error('Error reading token info:', error);
    throw error;
  }
}
 
// Get token balance
async function getTokenBalance(tokenContract, address) {
  try {
    const balance = await tokenContract.methods.balanceOf(address).call();
    const decimals = await tokenContract.methods.decimals().call();
    
    // Convert from wei to token units
    const formattedBalance = balance / Math.pow(10, decimals);
    
    return {
      raw: balance,
      formatted: formattedBalance.toString()
    };
  } catch (error) {
    console.error('Error getting token balance:', error);
    throw error;
  }
}
 
// Usage
const tokenInfo = await getTokenInfo(tokenContract);
console.log('Token info:', tokenInfo);
 
const balance = await getTokenBalance(tokenContract, '0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4');
console.log('Token balance:', balance);

Writing to Contracts

javascript
// Transfer tokens
async function transferTokens(tokenContract, fromPrivateKey, toAddress, amount) {
  try {
    const account = web3.eth.accounts.privateKeyToAccount(fromPrivateKey);
    
    // Get token decimals
    const decimals = await tokenContract.methods.decimals().call();
    
    // Convert amount to wei equivalent
    const amountWei = (amount * Math.pow(10, decimals)).toString();
    
    // Encode the function call
    const data = tokenContract.methods.transfer(toAddress, amountWei).encodeABI();
    
    // Estimate gas
    const gasEstimate = await tokenContract.methods.transfer(toAddress, amountWei).estimateGas({
      from: account.address
    });
    
    // Get 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: tokenContract.options.address,
      data: data,
      gas: Math.ceil(gasEstimate * 1.2), // Add 20% buffer
      gasPrice: gasPrice,
      nonce: nonce
    };
    
    // Sign and send
    const signedTx = await web3.eth.accounts.signTransaction(tx, fromPrivateKey);
    const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
    
    return receipt;
    
  } catch (error) {
    console.error('Error transferring tokens:', error);
    throw error;
  }
}
 
// Usage
const transferReceipt = await transferTokens(
  tokenContract,
  '0x1234567890abcdef...', // private key
  '0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4', // to address
  100 // amount of tokens
);
console.log('Transfer completed:', transferReceipt.transactionHash);

Contract Deployment

javascript
// Deploy a simple contract
async function deployContract(abi, bytecode, constructorArgs, fromPrivateKey) {
  try {
    const account = web3.eth.accounts.privateKeyToAccount(fromPrivateKey);
    
    // Create contract instance
    const contract = new web3.eth.Contract(abi);
    
    // Get deployment data
    const deployData = contract.deploy({
      data: bytecode,
      arguments: constructorArgs
    }).encodeABI();
    
    // Estimate gas for deployment
    const gasEstimate = await web3.eth.estimateGas({
      from: account.address,
      data: deployData
    });
    
    const gasPrice = await web3.eth.getGasPrice();
    const nonce = await web3.eth.getTransactionCount(account.address, 'pending');
    
    // Build deployment transaction
    const tx = {
      from: account.address,
      data: deployData,
      gas: Math.ceil(gasEstimate * 1.2),
      gasPrice: gasPrice,
      nonce: nonce
    };
    
    // Sign and send
    const signedTx = await web3.eth.accounts.signTransaction(tx, fromPrivateKey);
    const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
    
    // Return deployed contract address
    return {
      contractAddress: receipt.contractAddress,
      transactionHash: receipt.transactionHash,
      gasUsed: receipt.gasUsed
    };
    
  } catch (error) {
    console.error('Error deploying contract:', error);
    throw error;
  }
}

Event Monitoring

Listening to Contract Events

javascript
// Listen to Transfer events
function listenToTransferEvents(tokenContract, callback) {
  const transferEvent = tokenContract.events.Transfer({
    filter: {}, // Can filter by indexed parameters
    fromBlock: 'latest'
  });
  
  transferEvent.on('data', (event) => {
    const { from, to, value } = event.returnValues;
    
    callback({
      from,
      to,
      value,
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash,
      logIndex: event.logIndex
    });
  });
  
  transferEvent.on('error', (error) => {
    console.error('Event error:', error);
  });
  
  return transferEvent; // Return for cleanup
}
 
// Usage
const eventSubscription = listenToTransferEvents(tokenContract, (transferData) => {
  console.log('Token transfer detected:', transferData);
});
 
// Stop listening
// eventSubscription.unsubscribe();

Historical Event Queries

javascript
// Get historical events
async function getHistoricalTransfers(tokenContract, fromBlock, toBlock, addresses = []) {
  try {
    const events = await tokenContract.getPastEvents('Transfer', {
      filter: addresses.length > 0 ? { from: addresses } : {},
      fromBlock: fromBlock,
      toBlock: toBlock
    });
    
    return events.map(event => ({
      from: event.returnValues.from,
      to: event.returnValues.to,
      value: event.returnValues.value,
      blockNumber: event.blockNumber,
      transactionHash: event.transactionHash,
      timestamp: null // You'd need to fetch block to get timestamp
    }));
  } catch (error) {
    console.error('Error getting historical events:', error);
    throw error;
  }
}
 
// Get events with block timestamps
async function getTransfersWithTimestamps(tokenContract, fromBlock, toBlock) {
  const events = await getHistoricalTransfers(tokenContract, fromBlock, toBlock);
  
  // Get unique block numbers
  const blockNumbers = [...new Set(events.map(e => e.blockNumber))];
  
  // Fetch block information
  const blocks = await Promise.all(
    blockNumbers.map(blockNum => web3.eth.getBlock(blockNum))
  );
  
  // Create block timestamp lookup
  const blockTimestamps = Object.fromEntries(
    blocks.map(block => [block.number, Number(block.timestamp)])
  );
  
  // Add timestamps to events
  return events.map(event => ({
    ...event,
    timestamp: blockTimestamps[event.blockNumber]
  }));
}

Utility Functions & Helpers

Format Conversions

javascript
// Common format conversions
const utils = {
  // Wei conversions
  toWei: (amount, unit = 'ether') => web3.utils.toWei(amount.toString(), unit),
  fromWei: (amount, unit = 'ether') => web3.utils.fromWei(amount.toString(), unit),
  
  // Unit conversions
  toGwei: (wei) => web3.utils.fromWei(wei.toString(), 'gwei'),
  fromGwei: (gwei) => web3.utils.toWei(gwei.toString(), 'gwei'),
  
  // Number formatting
  toBN: (value) => web3.utils.toBN(value),
  toHex: (value) => web3.utils.toHex(value),
  fromHex: (hex) => web3.utils.hexToNumber(hex),
  
  // Address utilities
  isAddress: (address) => web3.utils.isAddress(address),
  toChecksumAddress: (address) => web3.utils.toChecksumAddress(address),
  
  // Hash utilities
  keccak256: (value) => web3.utils.keccak256(value),
  soliditySha3: (...values) => web3.utils.soliditySha3(...values),
  
  // Random utilities
  randomHex: (size) => web3.utils.randomHex(size),
  
  // Encoding utilities
  encodeParameter: (type, value) => web3.eth.abi.encodeParameter(type, value),
  decodeParameter: (type, hex) => web3.eth.abi.decodeParameter(type, hex),
  encodeParameters: (types, values) => web3.eth.abi.encodeParameters(types, values),
  decodeParameters: (types, hex) => web3.eth.abi.decodeParameters(types, hex)
};
 
// Usage examples
console.log('1 ETH in wei:', utils.toWei('1'));
console.log('Gas price in gwei:', utils.toGwei('20000000000'));
console.log('Is valid address:', utils.isAddress('0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4'));

Error Handling

javascript
// Comprehensive error handler
class Web3ErrorHandler {
  static handle(error) {
    if (error.code) {
      switch (error.code) {
        case 4001:
          return 'User rejected the request';
        case 4100:
          return 'The requested account and/or method has not been authorized';
        case 4200:
          return 'The requested method is not supported';
        case 4900:
          return 'The provider is disconnected';
        case 4901:
          return 'The provider is disconnected from all chains';
        case -32700:
          return 'Parse error - Invalid JSON';
        case -32600:
          return 'Invalid Request';
        case -32601:
          return 'Method not found';
        case -32602:
          return 'Invalid params';
        case -32603:
          return 'Internal error';
        default:
          return `Unknown error code: ${error.code}`;
      }
    }
    
    if (error.message) {
      if (error.message.includes('insufficient funds')) {
        return 'Insufficient funds for transaction';
      }
      if (error.message.includes('gas too low')) {
        return 'Gas limit too low';
      }
      if (error.message.includes('nonce too low')) {
        return 'Nonce too low - transaction may have been sent already';
      }
      if (error.message.includes('replacement transaction underpriced')) {
        return 'Replacement transaction underpriced';
      }
    }
    
    return error.message || 'Unknown error occurred';
  }
  
  static async handleWithRetry(fn, maxRetries = 3, delay = 1000) {
    for (let i = 0; i < maxRetries; i++) {
      try {
        return await fn();
      } catch (error) {
        if (i === maxRetries - 1) {
          throw new Error(this.handle(error));
        }
        
        console.warn(`Attempt ${i + 1} failed, retrying in ${delay}ms:`, this.handle(error));
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 2; // Exponential backoff
      }
    }
  }
}
 
// Usage
try {
  const result = await Web3ErrorHandler.handleWithRetry(async () => {
    return await web3.eth.getBalance('0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4');
  });
  console.log('Balance:', result);
} catch (error) {
  console.error('Final error:', error.message);
}

Performance Optimization

Batch Requests

javascript
// Batch multiple requests
async function batchRequests(requests) {
  const batch = new web3.BatchRequest();
  const promises = [];
  
  requests.forEach(({ method, params }) => {
    promises.push(new Promise((resolve, reject) => {
      const request = web3.eth[method].request(...params, (error, result) => {
        if (error) reject(error);
        else resolve(result);
      });
      batch.add(request);
    }));
  });
  
  batch.execute();
  return Promise.all(promises);
}
 
// Usage
const results = await batchRequests([
  { method: 'getBalance', params: ['0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4'] },
  { method: 'getTransactionCount', params: ['0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4'] },
  { method: 'getBlockNumber', params: [] }
]);
 
console.log('Batch results:', results);

Connection Pooling

javascript
// Simple connection pool
class Web3Pool {
  constructor(endpoints, maxConnections = 5) {
    this.endpoints = endpoints;
    this.maxConnections = maxConnections;
    this.connections = [];
    this.currentIndex = 0;
    
    this.initializePool();
  }
  
  initializePool() {
    for (let i = 0; i < this.maxConnections; i++) {
      const endpoint = this.endpoints[i % this.endpoints.length];
      this.connections.push(new Web3(endpoint));
    }
  }
  
  getConnection() {
    const connection = this.connections[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.connections.length;
    return connection;
  }
  
  async executeWithLoadBalancing(method, ...params) {
    const connection = this.getConnection();
    return await connection.eth[method](...params);
  }
}
 
// Usage
const pool = new Web3Pool([
  'https://ethereum-mainnet.bex.co/api-key-1',
  'https://ethereum-mainnet.bex.co/api-key-2',
  'https://ethereum-mainnet.bex.co/api-key-3'
]);
 
const balance = await pool.executeWithLoadBalancing('getBalance', '0x742D5Cc6bF2442E8C7c74c7b4Be6AB9d6f10f5B4');

Next Steps

Resources

One API key for 30+ chains

bex router is a single multi-chain gateway — one key, one bill, metered in compute units instead of an account per network.

Explore bex router