How can I get all items in a storage map? In polkadot-js, can we choose a storage map and give no id and its return all items? How can I do it like that?
3 Answers
Actually, the polkadot js did not fetch all the items.
It uses get_keys_paged to get the first <default paged size>(maybe 100) items.
This RPC accepts a key and a start key as params. So, that is how it works. Starting searching the first x
items under the given key.
Tips:
After getting all the keys that you want, call get_storage to get the key's value (generally this is a batch call).
You could make a loop like this to fetch all the pairs.
-
Not quite correct - as explained in my comment
.entries()
(with optional params if map is more that 2 keys) would return all entries. What is correct in this comment is the underlying implementation that.keys()
and.entries()
use, aka via the paged interfaces.– JacoCommented Aug 4, 2022 at 9:07
The JavaScript API provides the .keys()
and .entries()
interfaces on storage. This means -
// returns all the entries, key + value pairs
const entries = await api.query.someWhere.someMap.entries()
// returns the keys only (decoded)
const entries = await api.query.someWhere.someMap.keys()
For a description of the above, you can follow along in the documentation. It is listed here -
The UI calls .entries()
for maps when the option is selected. Underlying in the API it indeed uses the pages keys RPCs to retrieve all keys/entries.
For anyone wondering how to do it in rust for use in the Runtime: You can use the method .iter()
of StorageMap combined with the itertools method .collect_vec()
.
So for example if you wish to get all accounts that hold balance in frame_system::Account, you would do as following:
use itertools::Itertools // imports .collect_vec()
let balances_tuples = frame_system::Account::<ParaRuntime>::iter().collect_vec();