---
title: "Mantle Web3.js Integration Guide"
sidebar_position: 24
tags: [Mantle, EVM, JSON-RPC, blockchain, API]
keywords: [Mantle RPC, Mantle API, MNT, EVM, blockchain infrastructure, smart contracts, Web3]
description: "Mantle is an Ethereum Layer 2 scaling solution utilizing optimistic rollups and modular architecture, designed to provide low-cost, high-throughput tr"
last_updated: 2026-08-19
---

# Mantle Web3.js Integration Guide

Web3.js is the original and most widely-used JavaScript library for interacting with the Mantle blockchain. This guide covers everything from basic setup to advanced patterns using bex.co's Mantle infrastructure.

## Overview

Web3.js provides a complete JavaScript API for Mantle, including:
- **Account Management**: Create, import, and manage Mantle 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://api.bex.co/mantle/${accessKey}');

// 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 MantleWallet {
  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 MantleWallet(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

- Explore [Ethers.js Integration]./mantle-ethers-integration.md for modern alternative patterns
- Learn about advanced smart contract interaction patterns
- Check out [WebSocket Guide]./mantle-websockets.md for real-time features
- Follow [JSON-RPC API Reference]./mantle-json-rpc-api.md for low-level operations

## Resources

- [Web3.js Official Documentation](https://web3js.readthedocs.io/)
- [Mantle JavaScript API](https://ethereum.org/en/developers/docs/apis/javascript/)
- [Web3.js GitHub Repository](https://github.com/web3/web3.js)
- [bex.co Dashboard](https://bex.co/dash/)
- [Web3.js Examples Repository](https://github.com/blockeden-xyz/web3js-examples)

---

**Cost**: 300 CUs / req
