polkadot-cli 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +22 -1
  2. package/dist/cli.mjs +32 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![npm version](https://img.shields.io/npm/v/polkadot-cli)](https://www.npmjs.com/package/polkadot-cli)
1
2
  [![codecov](https://codecov.io/gh/peetzweg/polkadot-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/peetzweg/polkadot-cli)
2
3
 
3
4
  # polkadot-cli
@@ -309,12 +310,32 @@ dot query System.Number --output json | jq '.+1'
309
310
  dot query kusama.System.Account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
310
311
  ```
311
312
 
313
+ #### Partial key queries
314
+
315
+ For storage maps with multiple keys (NMaps), you can provide fewer keys than
316
+ expected to retrieve all entries matching that prefix. This uses the chain's
317
+ prefix-based iteration and does not require `--dump`.
318
+
319
+ ```bash
320
+ # Full key — returns a single value
321
+ dot query Staking.ErasStakers 100 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
322
+
323
+ # Partial key — returns all entries matching the first key
324
+ dot query Staking.ErasStakers 100
325
+
326
+ # No keys — requires --dump (safety net for large maps)
327
+ dot query Staking.ErasStakers --dump --limit 10
328
+ ```
329
+
330
+ The `--limit` option applies to partial key results just like it does for
331
+ `--dump` (default: 100, use `--limit 0` for unlimited).
332
+
312
333
  #### Output formatting
313
334
 
314
335
  Query results automatically convert on-chain types for readability:
315
336
 
316
337
  - **BigInt** values (e.g. balances) render as decimal strings
317
- - **Binary** fields (e.g. token `name`, `symbol`) render as text when valid UTF-8, or as `0x`-prefixed hex otherwise
338
+ - **Binary** fields (e.g. token `name`, `symbol`) render as text when the value contains only printable characters, or as `0x`-prefixed hex otherwise (values containing control characters, Private Use Area code points, or invalid UTF-8 sequences always fall back to hex)
318
339
  - **Uint8Array** values render as `0x`-prefixed hex
319
340
 
320
341
  ```bash
package/dist/cli.mjs CHANGED
@@ -387,14 +387,35 @@ var init_accounts = __esm(() => {
387
387
  DEV_NAMES = ["alice", "bob", "charlie", "dave", "eve", "ferdie"];
388
388
  });
389
389
 
390
+ // src/utils/binary-display.ts
391
+ function isReadableText(text) {
392
+ for (let i = 0;i < text.length; i++) {
393
+ const code = text.charCodeAt(i);
394
+ if (code <= 31 && code !== 9 && code !== 10 && code !== 13)
395
+ return false;
396
+ if (code === 127)
397
+ return false;
398
+ if (code >= 128 && code <= 159)
399
+ return false;
400
+ if (code === 65533)
401
+ return false;
402
+ if (code >= 57344 && code <= 63743)
403
+ return false;
404
+ }
405
+ return true;
406
+ }
407
+ function binaryToDisplay(value) {
408
+ const text = value.asText();
409
+ return isReadableText(text) ? text : value.asHex();
410
+ }
411
+
390
412
  // src/core/output.ts
391
413
  import { Binary } from "polkadot-api";
392
414
  function replacer(_key, value) {
393
415
  if (typeof value === "bigint")
394
416
  return value.toString();
395
417
  if (value instanceof Binary) {
396
- const text = value.asText();
397
- return text.includes("�") ? value.asHex() : text;
418
+ return binaryToDisplay(value);
398
419
  }
399
420
  if (value instanceof Uint8Array)
400
421
  return `0x${Buffer.from(value).toString("hex")}`;
@@ -2158,7 +2179,7 @@ var init_complete = __esm(() => {
2158
2179
  // src/cli.ts
2159
2180
  import cac from "cac";
2160
2181
  // package.json
2161
- var version = "1.8.1";
2182
+ var version = "1.9.0";
2162
2183
 
2163
2184
  // src/commands/account.ts
2164
2185
  init_accounts_store();
@@ -3927,14 +3948,15 @@ async function handleQuery(target, keys, opts) {
3927
3948
  ];
3928
3949
  const parsedKeys = await parseStorageKeys(meta, palletInfo.name, storageItem, effectiveKeys);
3929
3950
  const format = opts.output ?? "pretty";
3930
- if (storageItem.type === "map" && parsedKeys.length === 0) {
3931
- if (!opts.dump) {
3951
+ const expectedLen = storageItem.type === "map" && storageItem.keyTypeId != null ? meta.builder.buildStorage(palletInfo.name, storageItem.name).len : 0;
3952
+ if (storageItem.type === "map" && parsedKeys.length < expectedLen) {
3953
+ if (parsedKeys.length === 0 && !opts.dump) {
3932
3954
  clientHandle.destroy();
3933
3955
  await showItemHelp("query", target, { chain: opts.chain, rpc: opts.rpc });
3934
3956
  console.log(`${DIM}Hint: use --dump to fetch all entries${RESET}`);
3935
3957
  return;
3936
3958
  }
3937
- const entries = await storageApi.getEntries();
3959
+ const entries = await storageApi.getEntries(...parsedKeys);
3938
3960
  const limit = Number(opts.limit);
3939
3961
  const truncated = limit > 0 && entries.length > limit;
3940
3962
  const display = truncated ? entries.slice(0, limit) : entries;
@@ -3978,18 +4000,18 @@ async function parseStorageKeys(meta, palletName2, storageItem, args) {
3978
4000
  throw new Error(`${palletName2}.${storageItem.name} key expects ${typeDesc}
3979
4001
  ` + ` Pass 1 argument. Got ${args.length}.`);
3980
4002
  }
3981
- if (args.length !== len) {
4003
+ if (args.length > len) {
3982
4004
  let typeDesc;
3983
4005
  if (keyEntry.type === "tuple") {
3984
4006
  typeDesc = keyEntry.value.map((e) => describeType(meta.lookup, e.id)).join(", ");
3985
4007
  } else {
3986
4008
  typeDesc = describeType(meta.lookup, storageItem.keyTypeId);
3987
4009
  }
3988
- throw new Error(`${palletName2}.${storageItem.name} expects ${len} key arg(s): (${typeDesc}). Got ${args.length}.`);
4010
+ throw new Error(`${palletName2}.${storageItem.name} expects at most ${len} key arg(s): (${typeDesc}). Got ${args.length}.`);
3989
4011
  }
3990
4012
  if (keyEntry.type === "tuple") {
3991
4013
  const entries = keyEntry.value;
3992
- return Promise.all(entries.map((entry, i) => parseTypedArg(meta, entry, args[i])));
4014
+ return Promise.all(entries.slice(0, args.length).map((entry, i) => parseTypedArg(meta, entry, args[i])));
3993
4015
  }
3994
4016
  return Promise.all(args.map((arg) => parseTypedArg(meta, keyEntry, arg)));
3995
4017
  }
@@ -4452,8 +4474,7 @@ function formatEventValue(v) {
4452
4474
  if (v === null || v === undefined)
4453
4475
  return "null";
4454
4476
  if (v instanceof Binary3) {
4455
- const text = v.asText();
4456
- return text.includes("�") ? v.asHex() : text;
4477
+ return binaryToDisplay(v);
4457
4478
  }
4458
4479
  return JSON.stringify(v, (_k, val) => typeof val === "bigint" ? val.toString() : val);
4459
4480
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polkadot-cli",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "description": "CLI tool for querying Polkadot-ecosystem on-chain state",
5
5
  "type": "module",
6
6
  "bin": {