DEV Community

SwiftNodes
SwiftNodes

Posted on • Originally published at swiftnodes.io

Starknet RPC: It's JSON-RPC, but Almost Nothing Else From Ethereum Transfers

Almost every chain we've covered is EVM, and the pitch is the same: point viem or ethers at the endpoint and your Ethereum knowledge carries over. Starknet is the one where that's not true. It's a validity (ZK) rollup on Ethereum, but the execution layer is Cairo, not the EVM — different VM, different contract language, different account model. The RPC is still JSON-RPC over HTTP, so at a glance it looks familiar, but it's the starknet_* namespace, not eth_* — which means your EVM toolchain won't connect and your mental model needs adjusting. If you're coming from Ethereum, this is the spotlight to read slowly. Here's the map.

The essentials

Starknet mainnet is chain SN_MAIN (starknet_chainId returns the felt-encoded string 0x534e5f4d41494e), a STARK validity rollup with:

  • Cairo VM, not EVM — contracts are written in Cairo and run on the Starknet OS; Solidity and EVM bytecode don't apply.
  • STRK as the fee/staking token (18 decimals), launched February 2024.
  • Validity-proof finality — every state update ships with a STARK proof verified on Ethereum L1, so once proven it's cryptographically final (no fraud-proof challenge window).
  • A versioned JSON-RPC spec — the endpoint above reports starknet_specVersion 0.10.2; the method set is a formal, versioned standard.
  • Its own toolchainstarknet.js / starknet.py, starkli, and scarb (Cairo build). Not foundry/hardhat/viem.

Connecting uses a Starknet library, not an EVM one:

import { RpcProvider } from "starknet";

const provider = new RpcProvider({
  nodeUrl: "https://rpc.swiftnodes.io/rpc/starknet?key=YOUR_API_KEY",
});

await provider.getBlockNumber();          // starknet_blockNumber under the hood
await provider.getSpecVersion();          // "0.10.2"
Enter fullscreen mode Exit fullscreen mode

Point viem/ethers at the same URL and it fails — those speak eth_*, and Starknet doesn't answer to that namespace.

The method map: eth_* → starknet_*

The concepts you use daily mostly have an analogue — just under a different name and with different shapes:

You want to… Ethereum (eth_*) Starknet (starknet_*)
Latest block height eth_blockNumber starknet_blockNumber
Read a block eth_getBlockByNumber starknet_getBlockWithTxs
Call a view function eth_call starknet_call
Read storage eth_getStorageAt starknet_getStorageAt
Estimate cost eth_estimateGas starknet_estimateFee
Fetch a receipt eth_getTransactionReceipt starknet_getTransactionReceipt
Query events/logs eth_getLogs starknet_getEvents (continuation tokens)
Submit a transaction eth_sendRawTransaction starknet_addInvokeTransaction

Two things to notice immediately: there's no single "send raw transaction" — you submit INVOKE, DECLARE, or DEPLOY_ACCOUNT transactions depending on intent — and event querying uses continuation tokens for pagination rather than a fromBlock/toBlock range you scan yourself (a different rhythm from the eth_getLogs range-cap dance).

Big difference #1: every account is a contract (native AA, no EOAs)

This is the one that trips up Ethereum developers hardest. Starknet has no externally-owned accounts. There is no "private key = address." Every account is a deployed smart contract that holds its own signature-verification logic — account abstraction isn't a bolt-on standard like ERC-4337, it's the only account model.

Practical consequences from the RPC's perspective:

  • To send a transaction, you invoke through your account contract (an INVOKE), which the account validates with whatever scheme it implements.
  • A brand-new account must be deployed (DEPLOY_ACCOUNT) before it can transact — the "just receive funds and go" flow from Ethereum doesn't exist.
  • Multicall is native — an account can carry multiple calls in one transaction without a Multicall contract.
  • Signature formats are account-defined, so don't assume secp256k1/ECDSA (Starknet commonly uses the STARK-friendly curve).

If you liked the account-abstraction direction on zkSync Era, Starknet takes it all the way: there, AA is native but the chain is still EVM-compatible; here, AA is native and the VM is Cairo.

Big difference #2: Cairo and felts, not Solidity and uint256

Starknet's fundamental data type is the field element (felt252), not the EVM's 32-byte word. Addresses, storage keys, calldata, and return values are felts. When you call a contract, arguments and results are arrays of felts, and it's on you (or the library's ABI layer) to encode/decode Cairo types into and out of them. There are no Solidity ABIs — Cairo has its own ABI format, and starknet.js handles the marshalling if you feed it the contract's ABI.

The upshot: address handling and calldata encoding are different enough that you can't reuse EVM helpers. A Starknet address isn't a 20-byte hex string; contract calls aren't 4-byte selectors plus ABI-packed args. Lean on the Starknet library rather than hand-rolling.

Finality: STARK-proven, so no challenge window

Unlike the optimistic rollups we've covered (Blast, Unichain, Fraxtal) — where hard finality waits out a 7-to-14-day fraud-proof window — Starknet is a validity rollup. State transitions are accompanied by a STARK proof verified on Ethereum, so once that proof settles, the state is cryptographically final; there's nothing to challenge. The two tiers are:

  • Soft confirmation on Starknet within seconds to minutes (the sequencer has accepted and sequenced your transaction).
  • Hard finality once the STARK proof is verified on L1 — final by math, not by an elapsed dispute period.

That's a genuinely different finality story from optimistic L2s; the general model is in soft vs. hard finality, and like every rollup there's a sequencer ordering transactions before proofs settle.

What does NOT carry over

Be explicit with yourself before you start:

  • eth_* methods — not available; use starknet_*.
  • viem / ethers / web3.py / foundry / hardhat — they speak EVM JSON-RPC and Solidity; use starknet.js / starknet.py / starkli / scarb.
  • Solidity, EVM bytecode, 4-byte selectors, 20-byte addresses, uint256 words — replaced by Cairo, felts, and the Cairo ABI.
  • EOAs and raw eth_sendRawTransaction — replaced by account contracts and INVOKE/DECLARE/DEPLOY_ACCOUNT.

What does carry over is the shape of the work: it's still JSON-RPC over HTTP(S), you still read blocks/receipts/events and submit transactions, and reading a receipt to confirm success is conceptually the same check — just via starknet_getTransactionReceipt and Starknet's status fields.

The short version

Starknet (chain SN_MAIN) is a non-EVM STARK validity rollup: JSON-RPC over HTTP like Ethereum, but the starknet_* namespace, not eth_* — so viem/ethers/foundry don't connect and you use starknet.js/starkli instead. Contracts are Cairo, values are felts, and every account is a contract (native account abstraction, no EOAs — you send INVOKE transactions through your account, and new accounts must be deployed first). Most eth_* calls have a starknet_* analogue (with starknet_getEvents using continuation tokens), and finality is STARK-proven with no challenge window — cryptographic once the proof lands on L1. Treat it as its own platform that happens to share Ethereum's RPC transport, not as another EVM chain.

Building Cairo dApps, account-abstraction wallets, or indexers over Starknet? A flat-rate Starknet RPC endpoint gives you the full starknet_* JSON-RPC over HTTP alongside 75+ other chains under one key. Grab a free key and point your stack at:

https://rpc.swiftnodes.io/rpc/starknet?key=YOUR_API_KEY
Enter fullscreen mode Exit fullscreen mode

Originally published on the SwiftNodes blog. SwiftNodes provides flat-rate multi-chain RPC endpoints — HTTP + WebSocket, 75+ chains, no per-request metering. Grab a free key.

Top comments (0)