Aurora RPC: A Developer's Guide (EVM on NEAR)
Aurora looks like an Ethereum chain from the outside: chain ID 1313161554, ETH for gas, eth_* methods, MetaMask and Foundry work. Underneath, it isn't a chain with its own validators at all. Aurora is an EVM implemented as a smart contract on NEAR Protocol. Your Ethereum transaction is wrapped in a NEAR transaction by a relayer and executed by that contract, and NEAR's validators produce and finalize the blocks.
Most of the time you won't notice. When you do, it's because a field that means something on Ethereum means something else, or nothing, on Aurora. This guide covers those fields, measured through our endpoint on 2026-10-01.
The essentials
| Aurora mainnet | |
|---|---|
| Chain ID | 1313161554 (0x4e454152, "NEAR" in ASCII) |
| Gas token | ETH (NEAR gas is paid by the relayer) |
| Block time | 0.59 s average over 1,000 blocks |
safe / finalized |
equal to latest (NEAR finality) |
| Block gas limit | 9,007,199,254,740,991 |
| Base fee | none (baseFeePerGas absent) |
eth_gasPrice |
0.07 gwei |
eth_getLogs range |
100,000-block ranges accepted |
| Historical state | full archive, back to block 1 |
| Tracing | debug_*, trace_* and eth_getBlockReceipts not available |
| WebSocket | newHeads streams |
Block fields that don't mean what you think
Aurora blocks follow NEAR's, roughly one every 0.6 seconds, and most are empty: we scanned back 216 blocks before finding one with a transaction. A few header fields are placeholders:
gasLimitis 9,007,199,254,740,991, which is 2^53 − 1, JavaScript'sNumber.MAX_SAFE_INTEGER. It is not a real capacity. Code that computes "how full is this block" fromgasUsed / gasLimitgets zero, and tools that budget batch sizes from the block gas limit will think anything fits.minerandnonceare zero. There is no block producer on Aurora's side to report.- There is no
baseFeePerGas. Aurora doesn't run EIP-1559's fee market, so code that readsblock.baseFeePerGasto price a transaction needs a fallback toeth_gasPrice.
Fees: one price, and a few oddities
eth_gasPrice returned 0.07 gwei, and eth_maxPriorityFeePerGas returned the same 0.07 gwei: there is no base fee for a priority fee to sit on top of. Type-2 (EIP-1559) transactions are accepted, but in practice the whole fee is the gas price. Viem and ethers handle this if you let them estimate, but hand-built maxFeePerGas = 2 × baseFee + tip logic breaks on a missing base fee.
Three more things we saw:
eth_estimateGasfor a plain ETH transfer returned 28,080, not Ethereum's 21,000. The transfers we inspected used exactly 21,000 (0x5208) once mined, so the estimate is padded; leave the padding in.eth_feeHistoryis not trustworthy. It returnedbaseFeePerGasof zero (correct) but anoldestBlockof 113,128,533 when the chain head was about 218,000,000, and non-zerogasUsedRatiovalues for blocks that were empty. Don't drive fee logic from it.- Receipts can report an
effectiveGasPriceof zero: two of the three we sampled did, while still showing normalgasUsed. Fee accounting that divides by, or multiplies with, that field needs to handle zero.
The general mechanics are in estimating gas right; on Aurora, prefer eth_gasPrice and legacy-style pricing.
Receipts: zero cumulative gas, plus NEAR hashes
Every Aurora receipt we read had cumulativeGasUsed of 0x0, whatever its own gasUsed. On Ethereum, cumulativeGasUsed is the running total within the block, and some indexers derive per-transaction gas or block utilisation from it. On Aurora, use gasUsed.
Receipts also carry two fields Ethereum doesn't have:
{
"gasUsed": "0x184af",
"cumulativeGasUsed": "0x0",
"effectiveGasPrice": "0x501bd00",
"nearTransactionHash": "0x9dc2abb1…",
"nearReceiptHash": "0x8c4c3bb8…",
"status": "0x1",
"type": "0x2"
}
nearTransactionHash and nearReceiptHash identify the NEAR transaction and receipt that carried your Ethereum transaction. They are how you follow a transaction onto NEAR's own explorers when you need to see what the relayer actually did. viem keeps them on the receipt object, but its types don't declare them, so read them as (receipt as any).nearTransactionHash or from the raw JSON-RPC response.
Finality: there is no wait
safe and finalized both returned the newest block. Aurora inherits NEAR's finality, so a transaction in a block is final in about a second. That makes Aurora one of the fastest chains in our finalized-tag measurements across 62 chains, and it means confirmation loops written for Ethereum (wait 12 blocks, wait for finalized) are pure delay here.
Logs, history and tracing
eth_getLogsaccepted address-filtered ranges of 100,000 blocks, about 16 hours of Aurora. Because most blocks are empty, wide ranges are cheap; see eth_getLogs range caps for chunking when they aren't.- Historical state worked at every depth we tried, back to block 1.
- No tracing.
debug_traceBlockByNumber,trace_blockandeth_getBlockReceiptsall returned "not supported". Internal calls and value transfers inside a transaction can't be reconstructed from Aurora's RPC; tools built on trace_filter or debug_traceTransaction need another source, and receipt indexing is oneeth_getTransactionReceiptper transaction.
Aurora's own documentation also notes that mining methods (eth_getWork and friends) and pending-transaction filters are not supported, and that eth_getFilterChanges only returns logs since the filter was created (Aurora JSON-RPC reference).
Sending transactions
eth_sendRawTransaction works as usual: you sign an Ethereum transaction, and the relayer behind the endpoint wraps it in a NEAR transaction to the Aurora Engine contract and pays the NEAR gas (Aurora relayer docs). From your code's point of view nothing changes, except that the receipt you get back has the NEAR hashes above.
import { createPublicClient, http } from "viem";
import { aurora } from "viem/chains";
const client = createPublicClient({
chain: aurora,
transport: http("https://rpc.swiftnodes.io/rpc/aurora?key=YOUR_API_KEY"),
});
// Price from eth_gasPrice: there is no base fee to build EIP-1559 fees from.
const gasPrice = await client.getGasPrice();
// Receipt utilisation: use gasUsed, never cumulativeGasUsed (always 0 here).
const receipt = await client.getTransactionReceipt({ hash: "0x..." });
console.log(receipt.gasUsed);
The short version
- Chain ID 1313161554, ETH for gas, EVM running as a contract on NEAR; relayers pay NEAR gas.
- 0.6 s blocks, mostly empty;
finalizedequalslatest. - Placeholder fields:
gasLimitis 2^53 − 1,minerandnonceare zero, nobaseFeePerGas,cumulativeGasUsedalways 0. - Fees: price with
eth_gasPrice(0.07 gwei); don't trusteth_feeHistory; expecteffectiveGasPriceof zero. - Receipts add
nearTransactionHashandnearReceiptHash. - Full archive and wide
eth_getLogs; no tracing at all.
Aurora HTTP and WebSocket endpoints are on our Aurora RPC page, with the live block height and WebSocket status. The same key covers 83 chains, and 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
- Kava RPC: A Developer's Guide (Chain ID 2222)
Kava runs an EVM beside a Cosmos SDK chain. Measured: 5.7 s blocks, instant finality, a 10,000-block getLogs cap, ~100 blocks of state, archive routing.
- Cronos RPC: A Developer's Guide
How to use Cronos EVM over JSON-RPC — chain ID 25, ~0.42 second blocks with instant finality, a 10,000-block eth_getLogs cap, historical state pruned after ~100 blocks, and no debug or trace namespace.
- Hyperliquid RPC: A Developer's Guide
How to query HyperEVM over JSON-RPC — chain 999, ~1s blocks, a near-fixed 0.1 gwei base fee, a 1000-block and 1 MiB eth_getLogs cap, no WebSocket, and the one that will cost you money: state methods accept a block number and then ignore it, so historical reads silently return the latest state.