paritytech / paritytech/polkadot-cli
Add `storage` subcommand for raw `state_*` storage access
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 10
- Forks
- 2
- Avg merge
- 12h 35m
- Merged PRs (30d)
- 4
Description
Context
Today dot exposes two ways to read storage:
dot [chain.]<pallet>.<item>— typed, metadata-driven access. Limited to storage that lives undertwox128(palletName) ++ twox128(itemName); cannot reach well-known keys like:code,:heappages,:extrinsic_index, child-storage prefixes, or anything outside the metadata-described pallet surface.dot [chain.]rpc.state_getStorage 0x<key>— raw JSON-RPC passthrough (added in #197 / 0a4c5f3). Reaches anything, but is lumped in with ~50 other RPC methods and has no dedicated discovery / help / completion for the storage subset that matters most for debugging.
With the twox64/twox128/twox256 algorithms now in dot hash, users can construct any raw storage key locally — but reading it still requires reaching for the generic rpc passthrough. A dedicated, thin storage subcommand would close the loop and give AI coding agents an explicit verb for raw storage access.
Proposal
New top-level category storage, sibling to rpc / extensions, that wraps the state_* family. Raw hex in, raw hex out — no metadata coupling, no auto-decoding.
dot [chain.]storage # list operations
dot [chain.]storage.get <hex_key> [--at <hash>] # state_getStorage
dot [chain.]storage.hash <hex_key> [--at <hash>] # state_getStorageHash
dot [chain.]storage.size <hex_key> [--at <hash>] # state_getStorageSize
dot [chain.]storage.keys <hex_prefix> [--count N] [--start-key 0x…] [--at <hash>] # state_getKeysPaged
dot [chain.]storage.query <hex_key>… [--at <hash>] # state_queryStorageAt
Inherited from global flags: --chain, --rpc, --output, --json, --help.
Implementation sketch
src/utils/parse-dot-path.ts— add"storage"toDotCategoryandCATEGORY_ALIASES.src/commands/storage.ts(new) — modelled onsrc/commands/rpc.ts'shandleRpc(). Single handler dispatches onparsed.pallet(op name); validates hex args locally (/^0x([0-9a-fA-F]{2})*$/); callsrpcRequest()fromsrc/core/rpc.ts.src/cli.ts— add CAC options--countand--start-key; extendisFlatCategory(line 205) and the switch (next tocase "rpc"at line 293) to include"storage". Reuse the existing--atflag.src/completions/complete.ts— add"storage"toCATEGORIESand acompleteStorageCategory()returning the hardcoded op list.src/commands/storage.test.ts(new) — mirrorrpc.test.tsvalidation patterns. Norpc-methods.jsoncache fixture needed (we don't gate on remote method discovery —state_*is core).- Per-op
--helptext and the list view should surface well-known keys (:code=0x3a636f6465,:heappages=0x3a686561707061676573,:extrinsic_index) as examples — pure docs, no opinionated resolution.
Why thin / unopinionated
The killer feature here is predictability for coding agents: an agent that knows "read raw storage" can reach for storage.get without first learning the entire JSON-RPC surface. Keeping it thin (no --decode, no :code-as-keyword) means the contract is one short page and never lies.
Possible benefits
- Closes the loop with twox in
dot hash:dot hash twox128 System→ concat →dot polkadot.storage.get $PFXbecomes a copy-pasteable two-liner. - Reads well-known keys (
:code,:heappages, etc.) that are not in metadata. - Curated discoverability:
dot polkadot.storagelists 5 verbs vs hunting one of 50 RPC methods. - Tab completion for ops.
- Tighter pre-flight validation (hex regex, block-hash regex, count range) than the generic
rpcpassthrough.
Possible drawbacks / open questions
- Surface bloat. Everything here is reachable through
rpc.state_*already. The new subcommand is UX sugar, not new capability. Counter: explicit verbs help agents materially; the cost is ~200 lines + tests. - Block-hash keyword resolution. Should
--at best/--at finalizedresolve viachain_getBlockHash/chain_getFinalizedHead? Initial proposal says no (composable as--at $(dot <chain>.rpc.chain_getFinalizedHead)), but worth confirming. state_subscribeStorage. Existingrpchandler already rejects subscriptions; storage should do the same and not expose it.state_queryStorage(historical range across blocks): out of scope — heavy and usually disabled on public nodes.
Out of scope (intentional)
- Auto-decoding values via metadata (would re-couple to
getUnsafeApi/parseStorageKeys). state_subscribeStorage(streaming).state_queryStorage(historical range).- Built-in
:code-as-keyword translation (drifts toward opinionated; users can compose).
Verification
bun test src/commands/storage.test.ts— handler validation & dispatch.bun test src/utils/parse-dot-path.test.ts— category recognised.bun test— full suite green; no regressions inrpc/queryflat-category dispatch.- Manual against a live chain:
dot polkadot.storage→ lists 5 ops.dot polkadot.storage.get 0x3a636f6465→ returns the runtime WASM (huge hex).dot polkadot.storage.hash 0x3a636f6465→ cheap runtime-upgrade detector.dot polkadot.storage.keys 0x26aa394eea5630e07c48ae0c9558cef7 --count 5→ first 5 keys under the System pallet prefix.
- Confirm completion:
dot polkadot.storage.<TAB>yields the 5 ops.
Related
- #197 / 0a4c5f3 —
dot [chain.]rpc.<method>(existing escape hatch this would specialise). - Companion work landing alongside this issue: twox64/twox128/twox256 added to
dot hash(prerequisite for constructing storage keys locally).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with src/utils/parse-dot-path.ts, src/commands/rpc.ts, and src/cli.ts to trace category parsing and flat-command dispatch. Then mirror the validation and dispatch patterns in src/commands/rpc.test.ts while adding the named completion and CLI tests. Done means the five storage operations, flags, help/list output, validation, completion, and full test suite behave as specified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100