Solana

Solana Beta is live. Try BoltRPC Solana endpoints free - start your trial now.

Arbitrum RPC Guide: How to Connect and Build on Arbitrum (2026)

A technical guide to Arbitrum RPC endpoints for developers in 2026. Covers HTTP vs WebSocket, Arbitrum-specific methods, ethers.js setup, common issues, how to choose a reliable provider.

BoltRPC
BoltRPC Team
13 min read
Arbitrum RPC Guide: How to Connect and Build on Arbitrum (2026)

Arbitrum RPC Guide: How to Connect and Build on Arbitrum (2026)

Arbitrum is an Ethereum Layer 2 network built on optimistic rollup technology. It executes transactions off-chain, batches them, posts compressed proofs to Ethereum mainnet. The result: significantly lower gas costs and faster finality than Ethereum mainnet, with security anchored to Ethereum’s validator set.

To interact with Arbitrum programmatically, reading contract state, submitting transactions, subscribing to events, your application connects through a JSON-RPC endpoint. This guide covers everything you need: how Arbitrum RPC works, which methods matter, how to connect with ethers.js or web3.py, Arbitrum-specific behavior to watch for, how to handle common issues in production.


Arbitrum Chain IDs at a Glance

NetworkChain IDRPC Type
Arbitrum One42161Mainnet
Arbitrum Nova42170Gaming/low-cost
Arbitrum Sepolia421614Testnet

What is an Arbitrum RPC Endpoint

An Arbitrum RPC endpoint is an HTTP or WebSocket URL that exposes the Arbitrum JSON-RPC API. Your application sends method calls to this endpoint and receives on-chain data in return.

HTTP endpoints are the standard choice for request-response interactions: reading balances, calling contracts, sending transactions, querying logs. Each call opens a connection, sends a request, receives a response, closes.

WebSocket endpoints maintain a persistent connection and support event subscriptions. Use WSS when your application needs to react to new blocks or contract events in real time, without polling.

Arbitrum One (chain ID: 42161) is the main production network. Arbitrum Nova (chain ID: 42170) is a separate chain optimized for low-cost, high-frequency applications like gaming. Both use the same JSON-RPC method set, but they are distinct networks with different state.

Arbitrum-specific RPC behavior to understand:

Arbitrum uses a sequencer. When you submit a transaction, it is sent to the Arbitrum sequencer, which orders and executes it immediately. The sequencer then posts batches of transactions to Ethereum L1. This means your transaction reaches “soft finality” in under a second (sequencer confirms it) and “hard finality” once the batch is posted to L1, which takes minutes. Your RPC provider connects you to a full node that tracks the sequencer’s output.

Some RPC methods that query L1 state (for example, checking whether an L1-to-L2 message has been processed) require understanding this two-layer model. Most standard dApp interactions only touch Arbitrum state and behave exactly like Ethereum.


Example Arbitrum RPC Methods

Arbitrum is fully EVM-compatible. Every standard Ethereum JSON-RPC method works on Arbitrum with the same syntax. Beyond those, Arbitrum adds its own arb_ prefixed methods for L2-specific operations.

Standard Ethereum Methods on Arbitrum

These methods work identically on Arbitrum and Ethereum:

import { ethers } from 'ethers';

const provider = new ethers.JsonRpcProvider(
  'https://eu.endpoints.matrixed.link/rpc/arbitrum?auth=YOUR_KEY'
);

// Read ETH balance
const balance = await provider.getBalance('0xYourAddress');

// Call a contract (read-only)
const contract = new ethers.Contract(contractAddress, abi, provider);
const result = await contract.someReadMethod();

// Get the current block number
const blockNumber = await provider.getBlockNumber();

// Get transaction receipt
const receipt = await provider.getTransactionReceipt(txHash);

// Estimate gas for a transaction
const gasEstimate = await provider.estimateGas({
  to: contractAddress,
  data: encodedCallData
});

Arbitrum-Specific Methods

arb_getL1BaseFeeEstimate

Returns the L1 base fee component used in Arbitrum’s gas pricing. Arbitrum transactions include two cost components: L2 execution gas and an L1 data posting fee (a small surcharge that covers the cost of posting batch data to Ethereum). This method returns the current L1 base fee estimate used in that calculation.

// Raw JSON-RPC call
const l1BaseFee = await provider.send('arb_getL1BaseFeeEstimate', []);
console.log('L1 base fee estimate:', l1BaseFee);

arb_estimateRetryableTicket

Used when programmatically sending L1-to-L2 messages (retryable tickets). Returns gas estimates for the full cross-chain message lifecycle. Most standard dApp developers do not call this directly; the Arbitrum SDK handles it. But if you are building a bridge or cross-chain messaging system, this method is essential.

const gasEstimate = await provider.send('arb_estimateRetryableTicket', [
  l1Sender,
  l2Destination,
  l2CallValue,
  maxSubmissionCost,
  excessFeeRefundAddress,
  callValueRefundAddress,
  gasLimit,
  maxFeePerGas,
  data
]);

eth_getLogs on Arbitrum: Important Considerations

Arbitrum produces blocks much faster than Ethereum mainnet. Block times on Arbitrum are approximately 250 milliseconds, compared to 12 seconds on Ethereum. This means a 24-hour period on Arbitrum generates orders of magnitude more blocks than the same period on Ethereum.

Practical consequence: when querying eth_getLogs with a block range, a range of 10,000 blocks on Ethereum spans about 33 hours. The same 10,000 blocks on Arbitrum spans only about 40 minutes.

Always use block numbers, not timestamps, when querying logs on Arbitrum. Providers may enforce tighter block-range limits on Arbitrum due to the higher block frequency. If your query spans a large time window, break it into smaller chunks:

async function getArbitrumLogsInChunks(provider, filter, chunkSize = 5000) {
  const logs = [];
  let fromBlock = filter.fromBlock;
  const toBlock = filter.toBlock === 'latest'
    ? await provider.getBlockNumber()
    : filter.toBlock;

  while (fromBlock <= toBlock) {
    const chunkEnd = Math.min(fromBlock + chunkSize - 1, toBlock);
    const chunk = await provider.getLogs({
      ...filter,
      fromBlock,
      toBlock: chunkEnd
    });
    logs.push(...chunk);
    fromBlock = chunkEnd + 1;
  }

  return logs;
}

Connecting to Arbitrum RPC: Step by Step

ethers.js

import { ethers } from 'ethers';

// HTTP provider: for standard read/write calls
const provider = new ethers.JsonRpcProvider(
  'https://eu.endpoints.matrixed.link/rpc/arbitrum?auth=YOUR_KEY'
);

// Verify the connection
const network = await provider.getNetwork();
console.log('Connected to chain ID:', network.chainId); // 42161n for Arbitrum One

// Read a balance
const balance = await provider.getBalance('0xYourAddress');
console.log('Balance:', ethers.formatEther(balance), 'ETH');

// WebSocket provider: for event subscriptions
const wsProvider = new ethers.WebSocketProvider(
  'wss://eu.endpoints.matrixed.link/ws/arbitrum?auth=YOUR_KEY'
);

// Subscribe to new blocks
wsProvider.on('block', (blockNumber) => {
  console.log('New Arbitrum block:', blockNumber);
});

web3.py

from web3 import Web3

# Connect via HTTP
w3 = Web3(Web3.HTTPProvider(
    'https://eu.endpoints.matrixed.link/rpc/arbitrum?auth=YOUR_KEY'
))

# Verify connection
print('Connected:', w3.is_connected())
print('Chain ID:', w3.eth.chain_id)  # 42161 for Arbitrum One

# Read a balance
balance = w3.eth.get_balance('0xYourAddress')
print('Balance:', w3.from_wei(balance, 'ether'), 'ETH')

# Call a contract
contract = w3.eth.contract(address=contract_address, abi=abi)
result = contract.functions.someReadMethod().call()

Direct curl (JSON-RPC)

curl -X POST https://eu.endpoints.matrixed.link/rpc/arbitrum?auth=YOUR_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'

For MetaMask setup with BoltRPC, see the Arbitrum RPC endpoint page.


Arbitrum-Specific RPC Considerations

Sequencer vs Full Node

When you send a transaction to Arbitrum via RPC, your request goes to a full node that forwards it to the sequencer. The sequencer is the component that orders and executes transactions on Arbitrum. It responds almost instantly, giving you a transaction hash and soft confirmation in under a second.

Your RPC endpoint connects to a full node tracking the sequencer’s output. You do not need to do anything special for this to work. But be aware that until the sequencer’s batch is posted to L1 and verified, the transaction has not reached Ethereum-backed finality. For most applications, sequencer confirmation is sufficient. For cross-chain bridges or high-value operations, wait for L1 confirmation.

L1 to L2 Message Passing

Sending a message from Ethereum L1 to Arbitrum L2 (for example, depositing ETH or ERC-20 tokens) creates a “retryable ticket” on Arbitrum. These are special L2 transactions that get auto-executed when the L1 message is processed.

If you need to monitor the status of an L1-to-L2 message via RPC, use the Arbitrum SDK alongside your RPC provider. The SDK wraps the complexity of retryable ticket status checks.

Block Time and Timestamps

Arbitrum’s block time of roughly 250ms means block numbers increment very quickly. Do not use block numbers as a proxy for wall-clock time in the same way you might on Ethereum. Instead, use eth_getBlockByNumber to retrieve the actual timestamp for a block:

const block = await provider.getBlock('latest');
console.log('Block timestamp:', new Date(block.timestamp * 1000));

For time-sensitive logic, always rely on block timestamps, not block number arithmetic.

Nitro: What Changed for RPC Users

Arbitrum Nitro (launched 2022) is the current Arbitrum stack. Nitro improved performance and reduced gas costs substantially. For RPC users, the key change is that Nitro uses a WASM-based fraud proof system and compiles EVM code through a Go implementation. This is transparent to your RPC calls. You do not need to change any code. But if you encounter documentation referencing the older “Classic” Arbitrum, note that some behaviors and method responses differ. All modern Arbitrum (One and Nova) runs on Nitro.

Arbitrum Nova

Arbitrum Nova is a separate chain (chain ID 42170) optimized for high-volume, low-cost transactions. It uses AnyTrust technology instead of the full rollup model used by Arbitrum One. With AnyTrust, transaction data is posted to a committee of validators rather than directly to Ethereum L1. This reduces costs substantially, making Nova the preferred choice for gaming apps, social platforms, high-frequency NFT activity.

AnyTrust comes with a different trust assumption: you rely on the committee behaving honestly, not just on Ethereum’s security. For high-value DeFi, Arbitrum One is the appropriate choice. For throughput-sensitive, lower-value applications, Nova is purpose-built.

BoltRPC currently supports Arbitrum One. For Nova RPC access, contact us at trial.boltrpc.io to discuss your requirements.


Common Arbitrum RPC Issues

eth_getLogs Range Limits

Because Arbitrum produces blocks at high frequency, providers often enforce stricter block-range limits for eth_getLogs compared to Ethereum mainnet. A query spanning 100,000 blocks covers only about 7 hours on Arbitrum but would cover more than two weeks on Ethereum.

If your eth_getLogs call returns an error like “block range too large” or times out, reduce your chunk size. Start with 5,000-block chunks and adjust based on what your provider supports.

Sequencer Downtime Handling

The Arbitrum sequencer has occasionally experienced brief outages in the past. During a sequencer outage, transaction submissions are delayed, but the L2 state remains valid and readable. Your RPC reads (balance checks, contract calls, log queries) continue to work during sequencer downtime. Only transaction submission is affected.

Build retry logic into transaction submission rather than failing hard:

async function sendWithRetry(signer, txParams, maxAttempts = 3) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      const tx = await signer.sendTransaction(txParams);
      return await tx.wait();
    } catch (err) {
      if (attempt === maxAttempts) throw err;
      // Wait before retry: exponential backoff
      await new Promise(resolve => setTimeout(resolve, 1000 * attempt));
    }
  }
}

Gas Estimation Differences from Ethereum Mainnet

Arbitrum’s gas model includes the L1 data fee component. eth_estimateGas on Arbitrum returns the total gas estimate including this L1 component, so the raw number looks different from an equivalent Ethereum transaction.

Do not hard-code Ethereum-derived gas estimates for Arbitrum transactions. Always call eth_estimateGas against the Arbitrum RPC endpoint directly. Add a buffer (typically 10-20%) for safety:

const estimate = await provider.estimateGas({
  to: contractAddress,
  data: encodedCall
});

const gasLimit = estimate * 120n / 100n; // 20% buffer

Also note that Arbitrum’s eth_gasPrice returns the Arbitrum gas price, not Ethereum’s. These are independent values.


Choosing an Arbitrum RPC Provider

When evaluating a provider for Arbitrum workloads, look for:

Reliability and infrastructure quality. Arbitrum’s fast block times mean your application generates more RPC calls per second than an equivalent Ethereum application. Your provider needs infrastructure built for high-throughput workloads.

WebSocket support. Real-time applications on Arbitrum, bots, dashboards, event-driven logic, need stable WebSocket connections. Not all providers treat WSS as a first-class offering.

Security certifications. Providers handling production traffic for financial applications should operate on certified infrastructure. ISO/IEC 27001:2022 certification is the standard to look for.

Transparent pricing. Some providers assign different costs to different methods. Understand the pricing model before committing, particularly if your workload is heavy on eth_getLogs.

BoltRPC provides Arbitrum RPC on infrastructure operated by Matrixed.Link, which is ISO/IEC 27001:2022 certified. The platform handles 2 billion daily requests across 20+ networks with automatic failover. Pricing is straightforward: fixed monthly plans with transparent method weighting, so you know your costs before you build.

Trusted by Chainlink, Tiingo, Gains Network, Enjin.

Start your free 2-week trial: trial.boltrpc.io


FAQ

What is the Arbitrum One RPC URL?

To connect to Arbitrum One via BoltRPC, use:

  • HTTP: https://eu.endpoints.matrixed.link/rpc/arbitrum?auth=YOUR_KEY
  • WebSocket: wss://eu.endpoints.matrixed.link/ws/arbitrum?auth=YOUR_KEY

Replace YOUR_KEY with your API key from trial.boltrpc.io. Arbitrum One’s chain ID is 42161.

Is Arbitrum RPC compatible with Ethereum tools like ethers.js?

Yes. Arbitrum is fully EVM-compatible. ethers.js, viem, web3.py, web3.js or any other standard Ethereum library work with Arbitrum RPC endpoints without modification. Use the Arbitrum endpoint URL in place of an Ethereum endpoint URL. Your existing code will work. The chain ID returned will be 42161 (Arbitrum One) rather than 1 (Ethereum mainnet).

What is the difference between Arbitrum One and Arbitrum Nova RPC?

Arbitrum One (chain ID: 42161) is the main Arbitrum network, designed for general-purpose DeFi and dApp use. It uses a full rollup data availability model where all transaction data is posted to Ethereum L1.

Arbitrum Nova (chain ID: 42170) uses a different data availability model (AnyTrust) that posts data to a committee of validators rather than directly to Ethereum. This makes Nova cheaper per transaction, but with a different security model. Nova is designed for high-frequency, lower-value use cases like gaming and social applications.

Both use the same JSON-RPC methods. You connect to each with a different endpoint URL and chain ID.

How do I subscribe to Arbitrum events via WebSocket?

Use a WebSocket provider with ethers.js and subscribe to contract event filters:

import { ethers } from 'ethers';

const wsProvider = new ethers.WebSocketProvider(
  'wss://eu.endpoints.matrixed.link/ws/arbitrum?auth=YOUR_KEY'
);

// Subscribe to a specific contract event
const contract = new ethers.Contract(contractAddress, abi, wsProvider);

contract.on('Transfer', (from, to, amount, event) => {
  console.log(`Transfer: ${from} → ${to}, amount: ${ethers.formatEther(amount)}`);
});

// Subscribe to all new blocks
wsProvider.on('block', (blockNumber) => {
  console.log('New block:', blockNumber);
});

// Clean up when done
process.on('SIGINT', async () => {
  await wsProvider.destroy();
});

Because Arbitrum produces blocks roughly every 250ms, block subscription events fire very frequently. Make sure your event handler is efficient and non-blocking to avoid a backlog.


Frequently asked questions

Ready to build with high-performance RPC?

Start your free trial today. No credit card required. Access 20+ networks instantly.

Disclaimer: The content in this article is for informational purposes only and does not constitute financial, legal, or technical advice. Code examples and configurations are provided as-is. Always verify information with official documentation and test thoroughly in your own environment before deploying to production.

Continue reading