Appearance
Ethereum
| Endpoint | https://rpc.lab.au.ro/eth |
| Protocol | JSON-RPC 2.0 over HTTPS (POST) |
| chainId | 1 (0x1) |
| Batch | ✓ (correlated by id) |
Supported methods
The full standard surface, live-verified: eth_blockNumber, eth_chainId, eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory, eth_getBalance, eth_getTransactionCount, eth_getCode, eth_getStorageAt, eth_getBlockByNumber, eth_getBlockByHash, eth_getTransactionByHash, eth_getTransactionReceipt, eth_call, eth_estimateGas, eth_getLogs, eth_sendRawTransaction, net_version, web3_clientVersion.
Restrictions:
eth_getLogs/eth_getFilterLogs— 1 request/min per key (heavy-method guard, HTTP 429 +Retry-Afterbeyond that).debug_*— not available (HTTP 403 at the gateway).trace_*— requires an archive node; not offered on the standard endpoint.
Quick test
bash
curl -X POST https://rpc.lab.au.ro/eth \
-H "apikey: $YOUR_API_KEY" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
# {"jsonrpc":"2.0","id":1,"result":"0x18213bb"}SDK integration
js
import { ethers } from 'ethers'
const req = new ethers.FetchRequest('https://rpc.lab.au.ro/eth')
req.setHeader('apikey', process.env.YOUR_API_KEY)
const provider = new ethers.JsonRpcProvider(req)
console.log(await provider.getBlockNumber()) // 25301941
console.log(await provider.getFeeData()) // gasPrice, maxFeePerGas…js
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createPublicClient({
chain: mainnet,
transport: http('https://rpc.lab.au.ro/eth', {
fetchOptions: { headers: { apikey: process.env.YOUR_API_KEY } }
})
})
console.log(await client.getBlockNumber()) // 25301917n
console.log(await client.getGasPrice()) // 424657331nbash
# The key may ride a query parameter instead of a header — handy for tools
# that only accept a URL. Prefer the header in production (URLs get logged).
curl -X POST "https://rpc.lab.au.ro/eth?apikey=$YOUR_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'Recipes
Wait for new blocks (no WebSocket needed)
eth_blockNumber is cached for 2 s server-side, so polling every 3–4 s is both fresh and cheap (1 CU):
js
let last = 0n
setInterval(async () => {
const n = await client.getBlockNumber()
if (n > last) { last = n; console.log('new block', n) }
}, 4000)Read an ERC-20 balance
js
import { erc20Abi } from 'viem'
const usdc = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
const balance = await client.readContract({
address: usdc, abi: erc20Abi,
functionName: 'balanceOf', args: ['0x...your address...']
})Send a transaction
Sign locally, broadcast the raw bytes — the platform never sees your key:
js
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
const account = privateKeyToAccount(process.env.PRIVATE_KEY)
const wallet = createWalletClient({ account, chain: mainnet, transport })
const hash = await wallet.sendTransaction({ to: '0x...', value: 10n ** 15n })
// then poll client.getTransactionReceipt({ hash })eth_sendRawTransaction costs 20 CU and is never cached.
Limitations
- No archive state: historical balance/storage queries older than the node's pruning horizon return errors;
trace_*/debug_*are unavailable. eth_getLogsis rate-limited to 1/min — for indexing workloads, sweep small ranges and respectRetry-After.