state_queryStorageAt - Hydration RPC Method
Batch query multiple storage keys at a specific block on Hydration. Efficiently retrieve consistent multi-key state snapshots for indexers, dashboards, and analytics.
Queries multiple storage keys at a specific block on Hydration, returning all values in a single call. This is the preferred method for fetching consistent multi-key state snapshots, as all values are read from the same block.
Why Hydration? Build on Polkadot's leading DEX with $200M+ TVL, Omnipool AMM, and native HOLLAR stablecoin with Omnipool with reduced slippage, permissioned listings, 3M DOT DAO allocation, and 200%+ APR farm yields.
When to Use This Method
state_queryStorageAt is essential for DeFi developers, liquidity providers, and DAOs requiring capital-efficient trading:
- Consistent State Snapshots -- Fetch multiple storage values from the same block to ensure data consistency on Hydration
- Batch Raw Storage Reads -- Retrieve several known storage keys in one RPC call
- Indexer and Analytics -- Build efficient data pipelines by querying all required storage keys at once
- Historical State Analysis -- Compare storage state across different blocks for auditing and data analysis
Code Examples
Common Use Cases
1. Multi-Key Snapshot
Read multiple storage keys from the same block:
import { ApiPromise, WsProvider } from '@polkadot/api';
async function getStorageSnapshot(api, addresses) {
const keys = await Promise.all(addresses.map((address) => api.query.system.account.key(address)));
const results = await api.rpc.state.queryStorageAt(keys);
return results[0].changes.map(([key, value], idx) => ({
address: addresses[idx],
key: key.toHex(),
raw: value?.toHex() ?? null
}));
}
const snapshot = await getStorageSnapshot(api, [
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
'5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
]);
snapshot.forEach((entry) => {
console.log(`${entry.address}: ${entry.raw}`);
});2. Historical State Comparison
Compare storage state between two blocks for auditing:
async function compareStorageAtBlocks(api, keys, blockHash1, blockHash2) {
const [result1, result2] = await Promise.all([
api.rpc.state.queryStorageAt(keys, blockHash1),
api.rpc.state.queryStorageAt(keys, blockHash2)
]);
const changes1 = new Map(result1[0].changes.map(([k, v]) => [k.toHex(), v?.toHex()]));
const changes2 = new Map(result2[0].changes.map(([k, v]) => [k.toHex(), v?.toHex()]));
const diffs = [];
for (const [key, val1] of changes1) {
const val2 = changes2.get(key);
if (val1 !== val2) {
diffs.push({ key, before: val1, after: val2 });
}
}
console.log(`Found ${diffs.length} storage changes between blocks`);
return diffs;
}3. Efficient Indexer State Fetching
Fetch all required storage in a single batch for indexer pipelines:
async function fetchBlockState(api, blockHash) {
// Build storage keys for multiple storage items
const keys = [
api.query.system.number.key(), // block number
api.query.timestamp.now.key(), // timestamp
api.query.system.eventCount.key(), // event count
api.query.system.extrinsicCount.key() // extrinsic count
];
const result = await api.rpc.state.queryStorageAt(keys, blockHash);
const changes = new Map(
result[0].changes.map(([k, v]) => [k.toHex(), v?.toHex()])
);
return {
block: blockHash,
keyCount: changes.size,
entries: Object.fromEntries(changes)
};
}Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32603 | Internal error | Verify storage keys are correctly encoded hex strings with 0x prefix |
| -32602 | Invalid params | Ensure keys is an array of hex strings and blockHash is a valid block hash |
| -32005 | Rate limit exceeded | Reduce the number of keys per batch or implement rate limiting |
| State pruned | Historical state unavailable | The requested block may be pruned on this node -- use an archive node for deep historical queries |
Related Methods
state_getStorage-- Query a single storage keystate_getKeysPaged-- Enumerate storage keys with paginationstate_call-- Call a runtime API functionstate_getMetadata-- Get runtime metadata to construct storage keyschain_getBlockHash-- Get a block hash by block number for historical queries
state_getKeysPaged
Enumerate storage keys with pagination on Hydration. Iterate over storage maps like accounts, validators, and assets efficiently with cursor-based pagination.
system_health
Check node health status on Hydration. Returns peer count, sync status, and connectivity — essential for monitoring, load balancing, and infrastructure management on Polkadot's leading DEX with $200M+ TVL, Omnipool AMM, and native HOLLAR stablecoin.