Docs

Linea - zkEVM Layer 2 Documentation

Complete guide to Linea zkEVM integration with Dwellir RPC. Learn how to build on Linea's zero-knowledge rollup, access JSON-RPC methods, and optimize your dApp performance.

Linea RPC

With Dwellir, you get access to our global Linea network which always routes your API requests to the nearest available location, ensuring low latency and the fastest speeds.

Get your API key

Why Build on Linea?

Linea is ConsenSys's zkEVM Layer 2 solution, leveraging zero-knowledge proofs to deliver unmatched scalability and security. As a Type 2 zkEVM, Linea offers complete EVM equivalence with powerful scaling benefits:

Zero-Knowledge Performance

  • 12-second block times - Fast finality with zkProof generation
  • Up to 100x lower costs than Ethereum mainnet
  • 3,000+ TPS capacity - High throughput for demanding applications

Cryptographic Security

  • Zero-knowledge proofs - Mathematical guarantees of correctness
  • ConsenSys engineering - Built by Ethereum infrastructure leaders
  • Full EVM equivalence - Type 2 zkEVM with complete compatibility

Developer Excellence

  • MetaMask integration - Native support from day one
  • Infura compatibility - Seamless ConsenSys ecosystem integration
  • Truffle & Hardhat ready - Use your existing development tools

Quick Start with Linea

Connect to Linea in seconds with Dwellir's optimized endpoints:

Linea RPC Endpoints
HTTPS
curl -sS -X POST https://api-linea-mainnet-archive.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots> \  -H 'Content-Type: application/json' \  -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
import { JsonRpcProvider } from 'ethers';const provider = new JsonRpcProvider(  'https://api-linea-mainnet-archive.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>');const latest = await provider.getBlockNumber();console.log('block', latest);
import requestsurl = 'https://api-linea-mainnet-archive.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>'payload = {  'jsonrpc': '2.0', 'id': 1,  'method': 'eth_blockNumber', 'params': []}resp = requests.post(url, json=payload)print(resp.json())
package mainimport (  "bytes"  "fmt"  "io"  "net/http")func main() {  url := "https://api-linea-mainnet-archive.n.dwellir.com/<API_Keys_Are_Not_Made_for_Bots>"  payload := []byte(`{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}`)  resp, err := http.Post(url, "application/json",    bytes.NewBuffer(payload))  if err != nil { panic(err) }  defer resp.Body.Close()  body, _ := io.ReadAll(resp.Body)  fmt.Println(string(body))}

Installation & Setup

JavaScript
import { JsonRpcProvider } from 'ethers';

// Connect to Linea mainnet
const provider = new JsonRpcProvider(
  'https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);

// Verify connection to Linea
const network = await provider.getNetwork();
console.log('Connected to Linea:', network.chainId === 59144n);

// Query account balance
const balance = await provider.getBalance('0x...');
console.log('Balance:', balance.toString());

Network Information

ParameterValueDetails
Chain ID591440xe708 (hex)
Block Time12 secondsAverage
Gas TokenETHNative token
Rollup TypezkEVMZero-Knowledge

API Reference

Linea supports the full Ethereum JSON-RPC API specification with zkEVM-specific optimizations. Access all standard methods plus L2-specific features.

zkEVM-Specific Features

Zero-Knowledge Proof Verification

Linea's zkEVM architecture provides unique capabilities:

JavaScript
// Monitor L2 state root updates
async function getStateRoot(provider) {
  const block = await provider.getBlock('latest');

  // Access zkEVM-specific fields
  const stateRoot = block.stateRoot;
  const zkProofHash = block.zkProofHash; // Linea-specific

  return {
    blockNumber: block.number,
    stateRoot,
    zkProofHash,
    timestamp: block.timestamp
  };
}

Gas Optimization for zkEVM

Optimize gas costs on Linea's zkEVM:

JavaScript
// Estimate gas with zkEVM optimizations
async function estimateLineaGas(provider, tx) {
  // Get L2 execution gas
  const gasEstimate = await provider.estimateGas(tx);

  // zkEVM has different gas dynamics than optimistic rollups
  // No separate L1 data fee, but proof generation costs amortized
  const gasPrice = await provider.getGasPrice();

  // Add 10% buffer for zkEVM proof overhead
  const bufferedGas = gasEstimate * 110n / 100n;

  return {
    gasLimit: bufferedGas,
    gasPrice: gasPrice,
    estimatedCost: bufferedGas * gasPrice
  };
}

Batch Transaction Processing

Leverage Linea's efficient batch processing:

JavaScript
// Batch multiple transactions for optimal zkProof generation
async function batchTransactions(provider, transactions) {
  const wallet = new ethers.Wallet(privateKey, provider);
  const nonce = await wallet.getTransactionCount();

  const promises = transactions.map((tx, index) => {
    return wallet.sendTransaction({
      ...tx,
      nonce: nonce + index,
      // Linea handles batching efficiently in zkProof generation
      gasLimit: 100000n,
    });
  });

  const receipts = await Promise.all(promises);
  return receipts;
}

Performance Optimizations

1. Connection Pooling

Maintain persistent connections for optimal performance:

JavaScript
class LineaProvider {
  static instance = null;

  static getInstance() {
    if (!this.instance) {
      this.instance = new JsonRpcProvider(
        'https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY',
        {
          chainId: 59144,
          name: 'linea'
        }
      );
    }
    return this.instance;
  }
}

2. Smart Contract Deployment

Deploy contracts optimized for zkEVM:

JavaScript
async function deployContract(provider, bytecode, abi) {
  const wallet = new ethers.Wallet(privateKey, provider);

  // zkEVM-optimized deployment
  const factory = new ethers.ContractFactory(abi, bytecode, wallet);

  // Linea-specific gas settings
  const contract = await factory.deploy({
    gasLimit: 3000000n, // Higher limit for complex contracts
    gasPrice: await provider.getGasPrice()
  });

  // Wait for zkProof generation and confirmation
  await contract.waitForDeployment();

  return contract.address;
}

3. Event Monitoring

Efficiently monitor events on Linea:

JavaScript
// Optimized event filtering for zkEVM
async function watchEvents(contract, eventName) {
  const filter = contract.filters[eventName]();

  // Linea processes events in zkProof batches
  // Use larger block ranges for efficiency
  const BATCH_SIZE = 5000;

  contract.on(filter, (event) => {
    console.log('Event detected:', event);
    // Process event data
  });

  // For historical events
  const events = await contract.queryFilter(
    filter,
    -BATCH_SIZE, // Last 5000 blocks
    'latest'
  );

  return events;
}

Common Integration Patterns

Cross-Layer Messaging

Interact between Ethereum L1 and Linea L2:

JavaScript
// Bridge assets from Ethereum to Linea
async function bridgeToLinea(l1Provider, l2Provider, amount) {
  // L1 bridge contract address
  const L1_BRIDGE = '0x...'; // Official Linea bridge

  const l1Wallet = new ethers.Wallet(privateKey, l1Provider);
  const bridgeContract = new ethers.Contract(
    L1_BRIDGE,
    bridgeABI,
    l1Wallet
  );

  // Initiate bridge transaction on L1
  const tx = await bridgeContract.bridgeETH({
    value: amount,
    gasLimit: 200000n
  });

  // Wait for L1 confirmation
  await tx.wait();

  // Monitor L2 for bridge completion (typically 10-20 minutes)
  // zkEVM finality is faster than optimistic rollups
  return tx.hash;
}

DeFi Integration

Build DeFi applications on Linea:

JavaScript
// Interact with DeFi protocols on Linea
async function swapTokens(provider, tokenA, tokenB, amount) {
  const wallet = new ethers.Wallet(privateKey, provider);

  // Connect to DEX on Linea
  const router = new ethers.Contract(
    ROUTER_ADDRESS,
    routerABI,
    wallet
  );

  // Approve token spending
  const tokenContract = new ethers.Contract(tokenA, erc20ABI, wallet);
  await tokenContract.approve(ROUTER_ADDRESS, amount);

  // Execute swap with Linea-optimized gas
  const tx = await router.swapExactTokensForTokens(
    amount,
    0, // Min amount out
    [tokenA, tokenB],
    wallet.address,
    Math.floor(Date.now() / 1000) + 3600, // 1 hour deadline
    {
      gasLimit: 250000n,
      gasPrice: await provider.getGasPrice()
    }
  );

  return tx;
}

Troubleshooting

Error: "Invalid chain ID"

Ensure you're using the correct chain ID for Linea:

JavaScript
// Correct chain ID for Linea mainnet
const LINEA_CHAIN_ID = 59144; // or 0xe708 in hex

// Verify connection
const chainId = await provider.getNetwork().then(n => n.chainId);
if (chainId !== 59144n) {
  throw new Error(`Wrong network: expected Linea (59144), got ${chainId}`);
}

Error: "Transaction underpriced"

Linea uses dynamic gas pricing. Always fetch current prices:

JavaScript
// Get optimal gas price for Linea
async function getOptimalGasPrice(provider) {
  const gasPrice = await provider.getGasPrice();

  // Add 10% buffer for zkEVM processing
  const bufferedPrice = gasPrice * 110n / 100n;

  return bufferedPrice;
}

Error: "Execution reverted"

Debug failed transactions with trace data:

JavaScript
// Debug transaction on Linea
async function debugTransaction(provider, txHash) {
  try {
    // Get transaction receipt
    const receipt = await provider.getTransactionReceipt(txHash);

    if (receipt.status === 0) {
      // Use debug_traceTransaction for detailed error
      const trace = await provider.send('debug_traceTransaction', [
        txHash,
        { tracer: 'callTracer' }
      ]);

      console.log('Revert reason:', trace);
    }

    return receipt;
  } catch (error) {
    console.error('Debug failed:', error);
  }
}

Migration Guide

From Ethereum Mainnet

Moving from L1 to Linea zkEVM:

JavaScript
// Before (Ethereum)
const provider = new JsonRpcProvider('https://eth-mainnet.example.com');

// After (Linea)
const provider = new JsonRpcProvider(
  'https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);

// Full EVM equivalence - contracts work identically
// Same development tools and libraries
// MetaMask and wallet support
// Note: Different chain ID (59144)
// Note: zkEVM gas dynamics differ from L1
// Note: Finality achieved through zkProofs

From Other L2s

Migrating from optimistic rollups to Linea zkEVM:

JavaScript
// Key differences from Optimistic L2s:
// 1. No challenge period - zkProofs provide instant finality
// 2. Different gas model - no separate L1 data fee
// 3. Faster withdrawals - hours instead of days

// Optimistic L2 (e.g., Optimism, Arbitrum)
const withdrawalPeriod = 7 * 24 * 60 * 60; // 7 days

// Linea zkEVM
const withdrawalPeriod = 8 * 60 * 60; // ~8 hours for zkProof generation

Developer Resources

Essential Tools

Development Frameworks

Need Help?


Build the future of Web3 on Linea zkEVM with Dwellir's enterprise-grade RPC infrastructure. Get your API key