Storage calls
It is sometimes impossible to extract the required data with only event and extrinsic data. StorageContext exposes direct queries of runtime storage items via RPC.

Generate Type-safe wrappers

Typegen generates wrappers for fully type-safe storage calls which cover all historical runtime upgrades.
To enable storage calls:
  • List fully qualified names of the storage items to the storage section of typegen config
  • Rerun typegen
Here's an example of the typegen config:
1
{
2
"outDir": "src/types",
3
"chainVersions": "chainVersions.json",
4
"typesBundle": "./typesBundle.json",
5
"events": [
6
"balances.Transfer"
7
],
8
"calls": [
9
"timestamp.set"
10
],
11
"storage": [
12
"System.Account"
13
]
14
}
Copied!
To generate all available storage calls, simply set "storage": true.
Note: One can also consult subscan by navigating to the Runtime section and inspecting Storage Functions of the pallet of interest.
Typegen will generate the file types/storage.ts with something similar to
1
export class SystemAccountStorage {
2
constructor(private ctx: StorageContext) {}
3
4
/**
5
* The full account information for a particular account ID.
6
*/
7
get isV1() {
8
return this.ctx._chain.getStorageItemTypeHash('System', 'Account') === 'eb40f1d91f26d72e29c60e034d53a72b9b529014c7e108f422d8ad5f03f0c902'
9
}
10
11
/**
12
* The full account information for a particular account ID.
13
*/
14
async getAsV1(key: Uint8Array): Promise<v1.AccountInfoWithRefCount> {
15
assert(this.isV1)
16
return this.ctx._chain.getStorage(this.ctx.block.hash, 'System', 'Account', key)
17
}
18
}
Copied!

Process Storage items information in a Handler

As previously mentioned, the storage items are always retrieved at the "current" block height of StorageContext. The usage in a handler function is straighforward:
1
processor.addPreHook({range: {from: 0, to: 0}}, async ctx => {
2
let accounts = new SystemAccountStorage(ctx)
3
let aliceAddress = ss58.decode('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY').bytes
4
let aliceAccount = await accounts.getAsV1(aliceAddress)
5
assert(aliceAccount.data.free > 0)
6
})
Copied!