Kusama RPC: A Developer's Guide After the Asset Hub Move
Most Kusama RPC tutorials were written for a chain that no longer exists in the same shape. Until October 2025, the Kusama relay chain was where balances lived, where you bonded and nominated, and where governance ran. On October 7, 2025, Kusama completed its Asset Hub migration: balances, staking and governance moved off the relay chain to Kusama Asset Hub, through runtime upgrades, with no action required from holders.
The code that broke is the code that still queries the relay chain for things that moved. It doesn't throw. It returns an empty account and a zero balance. This guide covers what the Kusama relay RPC still does, what moved, and the numbers we measured through our own endpoint on 2026-09-26.
The essentials
Everything in this table was read live from https://rpc.swiftnodes.io/rpc/kusama:
| Kusama relay chain | |
|---|---|
system_chain |
Kusama |
Runtime (specName) |
kusama, specVersion 2003002, transactionVersion 26 |
| Node | Parity Polkadot 1.24.0 |
| Token | KSM, 12 decimals (system_properties) |
| SS58 address prefix | 2 |
| Block time | 6.38 s average over a 90-second sample |
| Finality (GRANDPA) | finalized head trailed the best head by 2-3 blocks (about 13-19 s) |
| RPC surface | 120 methods: system_*, chain_*, state_*, author_*, chainHead_v1_*, grandpa_*, beefy_*, mmr_*, and others |
eth_* methods |
none |
If you're coming from Ethereum, the same rules as Polkadot apply. There is no eth_blockNumber, viem and ethers won't connect, and storage is SCALE-encoded rather than ABI-encoded. Our Polkadot RPC guide covers that translation; everything there carries over to Kusama except the numbers. DOT has 10 decimals, KSM has 12. Kusama addresses use SS58 prefix 2, Polkadot's use 0, so the same public key encodes to a different address string on each network.
Big change: balances moved to Asset Hub
This is the gotcha worth the whole post. We read the Balances.TotalIssuance storage item and counted System.Account entries on both chains:
| Relay chain | Kusama Asset Hub | |
|---|---|---|
Balances.TotalIssuance |
24,939 KSM | 18,889,082 KSM |
System.Account entries |
2,343 | more than 30,000 (we stopped counting) |
The relay chain now accounts for roughly 0.1% of the KSM supply. If your wallet backend, tax tool or exchange integration still reads system.account on the relay chain, almost every user shows a zero balance, and nothing errors to tell you so.
The fix is to point balance, transfer, staking and governance queries at Asset Hub:
import { ApiPromise, WsProvider } from "@polkadot/api";
// Kusama Asset Hub: balances, transfers, staking, governance
const assetHub = await ApiPromise.create({
provider: new WsProvider("wss://kusama-asset-hub-rpc.polkadot.io"),
});
const { data } = await assetHub.query.system.account("YOUR_KUSAMA_ADDRESS");
console.log("free KSM:", Number(data.free.toBigInt()) / 1e12);
Two details trip people up here:
- Asset Hub's runtime is still called
statemine.state_getRuntimeVersionon Kusama Asset Hub returnsspecName: "statemine", the parachain's original name. If your code identifies networks byspecName, add it. - Addresses don't change. Asset Hub uses the same SS58 prefix (2) and 12 decimals, so a user's address and balance units are identical; only the chain you ask is different.
Staking follows the same rule. Bonding, nominating and unbonding are Asset Hub extrinsics now. The relay chain still has consensus work to do, so some staking-related storage remains there, but it is not where a nominator's position is managed.
What the relay chain RPC is still for
The relay chain didn't become useless; it became specialised. Query it directly for:
- Block production and finality. BABE produces relay blocks and GRANDPA finalizes them. If you need to know that something is final across the Kusama network, the relay chain's finalized head is the source.
- Parachain validation. Which parachain blocks were backed and included is relay-chain state.
- Bridge and light-client proofs. The
beefy_*andmmr_*methods exist for bridges and light clients that need compact proofs of relay-chain history. - Validator operations. Session keys are still set on the relay chain.
- Indexing relay events. Explorers and indexers that follow the relay chain itself.
For a dApp that only shows balances and sends transfers, the relay chain is now the wrong endpoint.
Follow finalized heads, not new heads
Kusama's new heads can be re-organised before GRANDPA finalizes them. In our sample, finality ran 2-3 blocks behind the best head. For anything that credits a user, subscribe to finalized heads:
import { ApiPromise, WsProvider } from "@polkadot/api";
const api = await ApiPromise.create({
provider: new WsProvider("wss://rpc.swiftnodes.io/ws/kusama?key=YOUR_API_KEY"),
});
await api.rpc.chain.subscribeFinalizedHeads((header) => {
console.log("finalized", header.number.toNumber());
});
The same logic applies as on any chain: a WebSocket that stops delivering is not the same as a chain with no new blocks. At 6.4 seconds per block, 30 seconds without a finalized head is worth a reconnect. The pattern is in reconnecting without losing events.
Runtime upgrades change your types
Kusama is Polkadot's canary network, so runtime upgrades usually reach it first and more often. Every upgrade can change storage layouts, call indices and the transactionVersion that signed transactions commit to. Polkadot-JS reloads metadata by itself when the runtime changes. What breaks is everything that doesn't: hand-written SCALE decoders, cached type definitions, and offline signers carrying old metadata.
Watch for upgrades instead of discovering them from failed transactions:
await api.rpc.state.subscribeRuntimeVersion((v) => {
console.log("runtime", v.specName.toString(), v.specVersion.toNumber(), "tx version", v.transactionVersion.toNumber());
});
When specVersion changes, reload metadata before decoding anything new. When transactionVersion changes, an offline signer with old metadata will produce transactions the chain rejects.
History: 256 blocks of state
Our Kusama relay endpoint is a pruned node. We asked for the Timestamp.Now storage item at increasing depths:
| Blocks back | State available |
|---|---|
| 64, 128, 200, 250, 256 | yes |
| 300, 500, 1,000 and deeper | no: State already discarded (error 4003) |
So state queries work for the last 256 blocks, about 27 minutes at 6.4 s per block. Blocks and headers are still available further back through chain_getBlockHash and chain_getBlock; it's the storage at old blocks that is pruned. For balance history, staking history or anything else that needs state_getStorage at an old block hash, you need an archive node, and the migration splits it in two: account history from before October 7, 2025 is relay-chain state, and everything after is on Asset Hub. The general trade-off is in full node vs archive node.
New JSON-RPC API: chainHead_v1
Our Kusama node exposes the newer JSON-RPC interface alongside the legacy one: nine chainHead_v1_* methods plus transaction_* and transactionWatch_*. Polkadot-JS uses the legacy chain_* and state_* methods. The newer polkadot-api (PAPI) client is built on chainHead_v1. Both work against the same endpoint. The archive_v1_* methods are not available, which matches the node being pruned.
The short version
- Balances, transfers, staking and governance: use Kusama Asset Hub. The relay chain holds about 0.1% of KSM.
- Finality, parachain inclusion, bridge proofs, validator operations: use the relay chain.
- KSM has 12 decimals and SS58 prefix 2, on both chains.
- Credit users on finalized heads, 2-3 blocks behind the best head.
- Subscribe to runtime versions; Kusama upgrades often.
- Relay state is kept for 256 blocks on our endpoint; older state needs an archive node.
Kusama relay-chain RPC over HTTP and WebSocket is on our Kusama RPC page, with the live block height and WebSocket status. The same key covers Polkadot and 81 other chains. SwiftNodes has a free tier if you want 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
- Polkadot RPC: JSON-RPC Over a Different Namespace
Polkadot's RPC is JSON-RPC over HTTP — but it's the Substrate namespace (system_*, chain_*, state_*), not eth_*, so viem/ethers don't connect. The relay chain runs no smart contracts, DOT has 10 decimals (not 18), and storage is SCALE-encoded, not ABI. Here's the developer map for querying Polkadot (and Kusama / Asset Hub) over Substrate RPC.
- 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.
- Babylon RPC: A Developer's Guide
How to query Babylon Genesis over RPC and LCD — CometBFT 0.38.22 on chain bbn-1, ~9.6 second blocks, 68 validators, blocks filled with finality signatures, why tx_search refuses ranges, and the pruning floor that gave three different answers in six calls.