Immutable zkEVM RPC: A Developer's Guide (Chain ID 13371)
Immutable zkEVM is the EVM chain behind Immutable's games: in-game items, marketplaces and player wallets. If you are building a game backend, an inventory indexer or a marketplace bot against it, most of your code carries over from Ethereum unchanged. Two things do not: the chain rejects any transaction with a priority fee under 10 gwei, and it has no safe or finalized block, so libraries that wait for finality get an error instead of a block.
Everything below was measured against the live chain on October 16, 2026, through the same endpoint SwiftNodes customers use and through Immutable's own public RPC.
The endpoint
https://rpc.swiftnodes.io/rpc/immutable-zkevm?key=YOUR_API_KEY
import { createPublicClient, http, defineChain } from "viem";
const immutable = defineChain({
id: 13371,
name: "Immutable zkEVM",
nativeCurrency: { name: "IMX", symbol: "IMX", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc.swiftnodes.io/rpc/immutable-zkevm?key=YOUR_API_KEY"] } },
});
const client = createPublicClient({ chain: immutable, transport: http() });
viem also ships this chain as immutableZkEvm in viem/chains; pass our URL to http() to use it. Native balances are IMX, not ETH.
What we measured
| Property | Value |
|---|---|
| Chain ID | 13371 (0x343b) |
| Client (Immutable public RPC) | Geth/v1.0.0-beta.17-952166b1/linux-amd64/go1.21.13 |
| Block 1 | December 11, 2023 |
| Block interval | exactly 2 s (120 of 120 intervals) |
| Transactions per block | 0.93 on average; 49 of 121 blocks empty |
| Block gas limit | 30,000,000 |
| Gas used | 0.4% of the limit on average |
| Base fee | 49 wei |
eth_maxPriorityFeePerGas |
11 gwei |
eth_gasPrice |
11 gwei (11,000,000,049 wei) |
| Minimum tip accepted | 10 gwei |
| Plain IMX transfer | 21,000 gas, 0.000231 IMX |
safe / finalized tags |
not supported |
eth_getLogs range |
5,000 blocks maximum |
| Historical state | full, back to early blocks |
Despite the name, the chain answers like a go-ethereum node. Blocks are sealed Clique-style: the miner field is the zero address, difficulty is 2, and the signer's signature sits in extraData. The genesis block authorizes a single signer. None of the zk-specific RPC namespaces exist: zkevm_batchNumber and zks_L1BatchNumber both return "method does not exist". Treat it as a fast, low-traffic geth chain with two rules of its own.
Rule one: the tip must be at least 10 gwei
On Ethereum a 1 or 2 gwei priority fee is normal, and plenty of code hardcodes it. Immutable zkEVM rejects that at the door. We signed three transactions from an empty wallet with different tips and sent them to the public RPC:
| Tip | Response |
|---|---|
| 1 gwei | transaction underpriced: gas tip cap 1000000000, minimum needed 10000000000 |
| 9 gwei | transaction underpriced: gas tip cap 9000000000, minimum needed 10000000000 |
| 10 gwei | insufficient funds for intrinsic transaction cost |
The third error is the one you want: the node checked the tip, accepted it, and only then noticed the wallet had no IMX. Anything under 10 gwei never reaches the balance check.
The base fee, meanwhile, has drifted from 1 gwei at genesis down to 49 wei, because blocks run at well under half full and EIP-1559 lowers the base fee after every such block. So the price you pay is almost entirely tip. In the 287 transactions we sampled from the last 300 blocks, the tips were:
| Tip | Transactions |
|---|---|
| 10 gwei | 35 |
| 11 gwei | 234 |
| 12 gwei | 12 |
| 15 to 100 gwei | 6 |
256 were EIP-1559 (type 2) and 31 legacy (type 0). For legacy transactions the same floor applies to gasPrice, since the tip is gasPrice minus the base fee.
The safe pattern is to ask the node:
const tip = await client.estimateMaxPriorityFeePerGas(); // 11 gwei today
const { maxFeePerGas } = await client.estimateFeesPerGas();
viem's estimateMaxPriorityFeePerGas calls eth_maxPriorityFeePerGas, which returns 11 gwei here. If you build transactions yourself, clamp the tip: max(eth_maxPriorityFeePerGas, 10 gwei). Bumping a stuck transaction works as usual, with the replacement needing a higher tip than the original.
Costs stay small. A plain IMX transfer used exactly 21,000 gas at an effective price of 11 gwei, which is 0.000231 IMX. Estimate contract calls with eth_estimateGas as usual; see estimating gas with EIP-1559 for padding advice.
Rule two: no safe or finalized block
eth_getBlockByNumber("safe") -> safe block not found
eth_getBlockByNumber("finalized") -> finalized block not found
Immutable zkEVM is one of the chains in our survey of the finalized block tag across 62 chains that return an error rather than a block. That matters in three places:
client.getBlock({ blockTag: "finalized" })throws instead of returning a block.- Indexers that read up to
finalizedand stop never make progress. - Wallet and bridge code that waits for
safebefore showing "confirmed" waits forever, or crashes.
Use a confirmation count on latest instead. At 2 seconds per block, 30 confirmations is one minute and 150 is five. Keep reorg handling in your indexer anyway, as described in handling chain reorgs in an indexer: store block hashes and check each new block's parent hash, so a replaced block is caught whatever depth you choose.
Logs: 5,000 blocks per request
eth_getLogs is limited by block range, not by result count:
| Range | Result |
|---|---|
| 100 blocks | 380 logs |
| 1,000 blocks | 3,769 logs |
| 5,000 blocks | 24,112 logs |
| 5,001 blocks | exceeded maximum block range: 5000 |
At 2 seconds per block, 5,000 blocks is under three hours of chain. Backfilling a contract deployed a year ago means about 3,200 requests, so filter by address and topics and run several ranges in parallel. Unfiltered, the chain emits about 4.8 logs per block, so a full 5,000-block page is a few megabytes of JSON. More on range caps in eth_getLogs range caps.
For live data, poll eth_getLogs or eth_getBlockByNumber every 2 seconds over HTTP, which matches the block interval. WebSocket subscriptions are not available for Immutable zkEVM on SwiftNodes today.
History, receipts and tracing
Historical state reads worked at every depth we tried, including block 16,777,216 from early in the chain's life, so balance-at-block and eth_call at old blocks work for analytics and airdrop snapshots. eth_getBlockReceipts works and returns [] for the many empty blocks.
Tracing does not: debug_traceBlockByNumber and trace_block both return "method does not exist", and so do txpool_status and the clique_* methods. If you need internal transactions, decode them from logs or replay calls with eth_call at the parent block.
| Method | Result |
|---|---|
eth_getLogs |
works, 5,000-block cap |
eth_getBlockReceipts |
works |
eth_getBalance / eth_call at old blocks |
work |
eth_maxPriorityFeePerGas, eth_feeHistory |
work |
safe / finalized tags |
not available |
debug_*, trace_* |
not available |
txpool_*, clique_* |
not available |
Summary
- Geth-based gaming chain, chain ID 13371, gas in IMX, 2-second blocks.
- The minimum tip is 10 gwei; lower tips fail with
transaction underpriced. Readeth_maxPriorityFeePerGas(11 gwei) and never hardcode an Ethereum tip. - The base fee is 49 wei, so the tip is the price: a transfer costs 0.000231 IMX.
- No
safeorfinalizedblock: count confirmations onlatest. eth_getLogsis capped at 5,000 blocks; no tracing.
Immutable zkEVM endpoints and method support are on our Immutable zkEVM RPC page, with 127 other chains on the same key. SwiftNodes has a free tier to try it.
John Sullivan covers RPC infrastructure, node operations, and multi-chain development at SwiftNodes — what it actually takes to keep endpoints fast, fresh, and reliable across EVM and non-EVM networks.
Related posts
- Ronin RPC After the Move to Ethereum L2: A Developer's Guide (Chain ID 2020)
Ronin became an OP Stack layer 2 in May 2026. Measured: 2 s blocks, a fixed 20 gwei base fee, a 200-block getLogs cap, ~23 min to finalized, and no pre-migration history.
- Lens Chain RPC: A Developer's Guide (Chain ID 232)
Lens Chain is a ZK Stack chain for social apps that pays gas in GHO and keeps its data on Avail. Measured: blocks only when there are transactions, two thirds of transactions sponsored by a paymaster, 8-hour batches, ~11 h to finalized, and a 10,000-log cap.
- Filecoin RPC: A Developer's Guide to the FEVM (Chain ID 314)
Filecoin speaks Ethereum JSON-RPC, but it is not an EVM chain underneath. Measured: 30-second epochs with null rounds that return an error, tipsets of about five blocks, two address formats, transfers that cost millions of gas, F3 finality 10 minutes behind the head, and a 360-epoch eth_getLogs cap.