polkadot-cli 1.1.1 → 1.2.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 +34 -0
  2. package/dist/cli.mjs +130 -37
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -79,6 +79,10 @@ dot accounts # shorthand, same as above
79
79
  # List all accounts (dev + stored)
80
80
  dot account list
81
81
 
82
+ # Add a watch-only address (no secret — for use as tx recipient or query target)
83
+ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
84
+ dot account add council 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
85
+
82
86
  # Create a new account (generates a mnemonic)
83
87
  dot account create my-validator
84
88
 
@@ -113,6 +117,36 @@ dot account inspect alice --prefix 0 # Polkadot mainnet prefix
113
117
  dot account inspect alice --output json # JSON output
114
118
  ```
115
119
 
120
+ #### Watch-only accounts
121
+
122
+ Add named addresses without secrets — useful for saving frequently-used recipients, multisig members, or query targets:
123
+
124
+ ```bash
125
+ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
126
+ dot account add council 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
127
+ ```
128
+
129
+ Watch-only accounts appear in `dot account list` with a `(watch-only)` badge and can be inspected and removed like any other account. They cannot be used with `--from` (signing) or as a source for `derive`.
130
+
131
+ The `add` subcommand is context-sensitive: bare `add <name> <address>` creates a watch-only entry, while `add --secret` or `add --env` imports a keyed account (same as `import`).
132
+
133
+ #### Named address resolution
134
+
135
+ Named accounts (both watch-only and keyed) resolve automatically everywhere an AccountId32 or MultiAddress is expected — in `dot tx` arguments and `dot query` keys:
136
+
137
+ ```bash
138
+ # Use a named account as transfer recipient
139
+ dot tx Balances.transferKeepAlive treasury 1000000000000 --from alice
140
+
141
+ # Query by account name
142
+ dot query System.Account treasury
143
+
144
+ # Dev accounts also resolve
145
+ dot tx Balances.transferKeepAlive bob 1000000000000 --from alice
146
+ ```
147
+
148
+ Resolution order: dev account name > stored account name > SS58 address > hex public key. If the input doesn't match any, the CLI shows an error listing available account names.
149
+
116
150
  #### Inspect accounts
117
151
 
118
152
  Convert between SS58 addresses, hex public keys, and account names. Accepts any of:
package/dist/cli.mjs CHANGED
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
5
  // src/cli.ts
6
6
  import cac from "cac";
7
7
  // package.json
8
- var version = "1.1.1";
8
+ var version = "1.2.0";
9
9
 
10
10
  // src/config/accounts-store.ts
11
11
  import { access as access2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
@@ -238,6 +238,9 @@ function findAccount(file, name) {
238
238
  function isEnvSecret(secret) {
239
239
  return typeof secret === "object" && secret !== null && "env" in secret;
240
240
  }
241
+ function isWatchOnly(account) {
242
+ return account.secret === undefined;
243
+ }
241
244
 
242
245
  // src/core/accounts.ts
243
246
  import { sr25519CreateDerive } from "@polkadot-labs/hdkd";
@@ -354,6 +357,9 @@ async function resolveAccountSigner(name) {
354
357
  const available = [...DEV_NAMES, ...accountsFile.accounts.map((a) => a.name)];
355
358
  throw new Error(`Unknown account "${name}". Available accounts: ${available.join(", ")}`);
356
359
  }
360
+ if (account.secret === undefined) {
361
+ throw new Error(`Account "${name}" is watch-only (no secret). Cannot sign. Import with --secret or --env.`);
362
+ }
357
363
  const secret = resolveSecret(account.secret);
358
364
  const isHexSeed = /^0x[0-9a-fA-F]{64}$/.test(secret);
359
365
  const keypair = isHexSeed ? deriveFromHexSeed(secret, account.derivationPath) : deriveFromMnemonic(secret, account.derivationPath);
@@ -463,15 +469,19 @@ function firstSentence(docs) {
463
469
  // src/commands/account.ts
464
470
  var ACCOUNT_HELP = `
465
471
  ${BOLD}Usage:${RESET}
472
+ $ dot account add <name> <ss58|hex> Add a watch-only address (no secret)
473
+ $ dot account add <name> --secret <s> [--path <derivation>] Import from BIP39 mnemonic
474
+ $ dot account add <name> --env <VAR> [--path <derivation>] Import account backed by env variable
466
475
  $ dot account create|new <name> [--path <derivation>] Create a new account
467
- $ dot account import|add <name> --secret <s> [--path <derivation>] Import from BIP39 mnemonic
468
- $ dot account import|add <name> --env <VAR> [--path <derivation>] Import account backed by env variable
476
+ $ dot account import <name> --secret <s> [--path <derivation>] Import from BIP39 mnemonic
477
+ $ dot account import <name> --env <VAR> [--path <derivation>] Import account backed by env variable
469
478
  $ dot account derive <source> <new-name> --path <derivation> Derive a child account
470
479
  $ dot account inspect <input> [--prefix <N>] Inspect an account/address/key
471
480
  $ dot account list List all accounts
472
481
  $ dot account remove|delete <name> [name2] ... Remove stored account(s)
473
482
 
474
483
  ${BOLD}Examples:${RESET}
484
+ $ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
475
485
  $ dot account create my-validator
476
486
  $ dot account create my-staking --path //staking
477
487
  $ dot account create multi --path //polkadot//0/wallet
@@ -500,8 +510,11 @@ function registerAccountCommands(cli) {
500
510
  case "new":
501
511
  case "create":
502
512
  return accountCreate(names[0], opts);
503
- case "import":
504
513
  case "add":
514
+ if (opts.secret || opts.env)
515
+ return accountImport(names[0], opts);
516
+ return accountAddWatchOnly(names[0], names[1]);
517
+ case "import":
505
518
  return accountImport(names[0], opts);
506
519
  case "derive":
507
520
  return accountDerive(names[0], names[1], opts);
@@ -618,6 +631,48 @@ async function accountImport(name, opts) {
618
631
  console.log();
619
632
  }
620
633
  }
634
+ async function accountAddWatchOnly(name, address) {
635
+ if (!name) {
636
+ console.error(`Account name is required.
637
+ `);
638
+ console.error("Usage: dot account add <name> <ss58-address|0x-public-key>");
639
+ process.exit(1);
640
+ }
641
+ if (!address) {
642
+ console.error(`Address is required.
643
+ `);
644
+ console.error("Usage: dot account add <name> <ss58-address|0x-public-key>");
645
+ process.exit(1);
646
+ }
647
+ if (isDevAccount(name)) {
648
+ throw new Error(`"${name}" is a built-in dev account and cannot be used as a custom account name.`);
649
+ }
650
+ const accountsFile = await loadAccounts();
651
+ if (findAccount(accountsFile, name)) {
652
+ throw new Error(`Account "${name}" already exists.`);
653
+ }
654
+ let hexPub;
655
+ if (isHexPublicKey(address)) {
656
+ hexPub = address;
657
+ } else {
658
+ try {
659
+ const decoded = fromSs58(address);
660
+ hexPub = publicKeyToHex(decoded);
661
+ } catch {
662
+ throw new Error(`Invalid address "${address}". Expected an SS58 address or 0x-prefixed 32-byte hex public key.`);
663
+ }
664
+ }
665
+ accountsFile.accounts.push({
666
+ name,
667
+ publicKey: hexPub,
668
+ derivationPath: ""
669
+ });
670
+ await saveAccounts(accountsFile);
671
+ printHeading("Account Added (watch-only)");
672
+ console.log(` ${BOLD}Name:${RESET} ${name}`);
673
+ console.log(` ${BOLD}Address:${RESET} ${toSs58(hexPub)}`);
674
+ console.log();
675
+ }
621
676
  async function accountDerive(sourceName, newName, opts) {
622
677
  if (!sourceName) {
623
678
  console.error(`Source account name is required.
@@ -645,15 +700,19 @@ async function accountDerive(sourceName, newName, opts) {
645
700
  if (!source) {
646
701
  throw new Error(`Source account "${sourceName}" not found.`);
647
702
  }
703
+ if (isWatchOnly(source)) {
704
+ throw new Error(`Cannot derive from "${sourceName}": watch-only, no secret.`);
705
+ }
648
706
  if (findAccount(accountsFile, newName)) {
649
707
  throw new Error(`Account "${newName}" already exists.`);
650
708
  }
651
709
  const path = opts.path;
652
- if (isEnvSecret(source.secret)) {
653
- const publicKey = tryDerivePublicKey(source.secret.env, path) ?? "";
710
+ const sourceSecret = source.secret;
711
+ if (isEnvSecret(sourceSecret)) {
712
+ const publicKey = tryDerivePublicKey(sourceSecret.env, path) ?? "";
654
713
  accountsFile.accounts.push({
655
714
  name: newName,
656
- secret: source.secret,
715
+ secret: sourceSecret,
657
716
  publicKey,
658
717
  derivationPath: path
659
718
  });
@@ -662,20 +721,20 @@ async function accountDerive(sourceName, newName, opts) {
662
721
  console.log(` ${BOLD}Name:${RESET} ${newName}`);
663
722
  console.log(` ${BOLD}Source:${RESET} ${sourceName}`);
664
723
  console.log(` ${BOLD}Path:${RESET} ${path}`);
665
- console.log(` ${BOLD}Env:${RESET} ${source.secret.env}`);
724
+ console.log(` ${BOLD}Env:${RESET} ${sourceSecret.env}`);
666
725
  if (publicKey) {
667
726
  console.log(` ${BOLD}Address:${RESET} ${toSs58(publicKey)}`);
668
727
  } else {
669
- console.log(` ${YELLOW}Address will resolve when $${source.secret.env} is set.${RESET}`);
728
+ console.log(` ${YELLOW}Address will resolve when $${sourceSecret.env} is set.${RESET}`);
670
729
  }
671
730
  console.log();
672
731
  } else {
673
- const { publicKey } = importAccount(source.secret, path);
732
+ const { publicKey } = importAccount(sourceSecret, path);
674
733
  const hexPub = publicKeyToHex(publicKey);
675
734
  const address = toSs58(publicKey);
676
735
  accountsFile.accounts.push({
677
736
  name: newName,
678
- secret: source.secret,
737
+ secret: sourceSecret,
679
738
  publicKey: hexPub,
680
739
  derivationPath: path
681
740
  });
@@ -704,7 +763,10 @@ async function accountList() {
704
763
  displayName += ` (${account.derivationPath})`;
705
764
  }
706
765
  let address;
707
- if (isEnvSecret(account.secret)) {
766
+ if (isWatchOnly(account)) {
767
+ displayName += " (watch-only)";
768
+ address = account.publicKey ? toSs58(account.publicKey) : "n/a";
769
+ } else if (account.secret !== undefined && isEnvSecret(account.secret)) {
708
770
  displayName += ` (env: ${account.secret.env})`;
709
771
  let pubKey = account.publicKey;
710
772
  if (!pubKey) {
@@ -786,7 +848,7 @@ async function accountInspect(input, opts) {
786
848
  name = account.name;
787
849
  if (account.publicKey) {
788
850
  publicKeyHex = account.publicKey;
789
- } else if (isEnvSecret(account.secret)) {
851
+ } else if (account.secret !== undefined && isEnvSecret(account.secret)) {
790
852
  const derived = tryDerivePublicKey(account.secret.env, account.derivationPath);
791
853
  if (!derived) {
792
854
  console.error(`Cannot derive public key for "${account.name}": $${account.secret.env} is not set.`);
@@ -2564,8 +2626,35 @@ import { Binary as Binary2 } from "polkadot-api";
2564
2626
  var pjsAppsLink = (rpc, hash) => `https://polkadot.js.org/apps/?rpc=${encodeURIComponent(rpc)}#/explorer/query/${hash}`;
2565
2627
  var papiLink = (rpc, hash) => `https://dev.papi.how/explorer/${hash}#networkId=custom&endpoint=${encodeURIComponent(rpc)}`;
2566
2628
 
2629
+ // src/core/resolve-address.ts
2630
+ async function resolveAccountAddress(input) {
2631
+ if (isDevAccount(input)) {
2632
+ return getDevAddress(input);
2633
+ }
2634
+ const accountsFile = await loadAccounts();
2635
+ const account = findAccount(accountsFile, input);
2636
+ if (account) {
2637
+ if (account.publicKey) {
2638
+ return toSs58(account.publicKey);
2639
+ }
2640
+ throw new Error(`Account "${account.name}" has no public key resolved yet.`);
2641
+ }
2642
+ try {
2643
+ const decoded = fromSs58(input);
2644
+ publicKeyToHex(decoded);
2645
+ return input;
2646
+ } catch {}
2647
+ if (isHexPublicKey(input)) {
2648
+ return input;
2649
+ }
2650
+ const stored = accountsFile.accounts.map((a) => a.name);
2651
+ const available = [...DEV_NAMES, ...stored];
2652
+ throw new Error(`Unknown account or address "${input}".
2653
+ Available accounts: ${available.join(", ")}`);
2654
+ }
2655
+
2567
2656
  // src/commands/tx.ts
2568
- function parseStructArgs(meta, fields, args, callLabel) {
2657
+ async function parseStructArgs(meta, fields, args, callLabel) {
2569
2658
  const fieldNames = Object.keys(fields);
2570
2659
  if (args.length !== fieldNames.length) {
2571
2660
  const expected = fieldNames.map((name) => `${name}: ${describeType(meta.lookup, fields[name].id)}`).join(", ");
@@ -2577,7 +2666,7 @@ function parseStructArgs(meta, fields, args, callLabel) {
2577
2666
  const name = fieldNames[i];
2578
2667
  const entry = fields[name];
2579
2668
  try {
2580
- result[name] = parseTypedArg(meta, entry, args[i]);
2669
+ result[name] = await parseTypedArg(meta, entry, args[i]);
2581
2670
  } catch (err) {
2582
2671
  const typeDesc = describeType(meta.lookup, entry.id);
2583
2672
  throw new Error(`Invalid value for argument '${name}' (expected ${typeDesc}): ${JSON.stringify(args[i])}
@@ -2723,7 +2812,7 @@ function parseEnumShorthand(arg) {
2723
2812
  return null;
2724
2813
  return { variant, inner: arg.slice(firstParen + 1, -1) };
2725
2814
  }
2726
- function parseTypedArg(meta, entry, arg) {
2815
+ async function parseTypedArg(meta, entry, arg) {
2727
2816
  if (entry.type === "lookupEntry")
2728
2817
  return parseTypedArg(meta, entry.value, arg);
2729
2818
  switch (entry.type) {
@@ -2732,6 +2821,7 @@ function parseTypedArg(meta, entry, arg) {
2732
2821
  case "compact":
2733
2822
  return entry.isBig ? BigInt(arg) : parseInt(arg, 10);
2734
2823
  case "AccountId32":
2824
+ return resolveAccountAddress(arg);
2735
2825
  case "AccountId20":
2736
2826
  return arg;
2737
2827
  case "option": {
@@ -2760,7 +2850,7 @@ function parseTypedArg(meta, entry, arg) {
2760
2850
  if (resolvedDef.type === "void" || shorthand.inner === "") {
2761
2851
  return { type: matched2 };
2762
2852
  }
2763
- const innerValue = parseTypedArg(meta, variantDef, shorthand.inner);
2853
+ const innerValue = await parseTypedArg(meta, variantDef, shorthand.inner);
2764
2854
  return normalizeValue(meta.lookup, entry, { type: matched2, value: innerValue });
2765
2855
  }
2766
2856
  }
@@ -2768,7 +2858,8 @@ function parseTypedArg(meta, entry, arg) {
2768
2858
  const idVariant = entry.value.Id;
2769
2859
  const innerType = idVariant.type === "lookupEntry" ? idVariant.value : idVariant;
2770
2860
  if (innerType.type === "AccountId32" && !arg.startsWith("{")) {
2771
- return { type: "Id", value: arg };
2861
+ const resolved = await resolveAccountAddress(arg);
2862
+ return { type: "Id", value: resolved };
2772
2863
  }
2773
2864
  }
2774
2865
  const matched = variants.find((v) => v.toLowerCase() === arg.toLowerCase());
@@ -2919,7 +3010,7 @@ async function handleQuery(target, keys, opts) {
2919
3010
  }
2920
3011
  const unsafeApi = clientHandle.client.getUnsafeApi();
2921
3012
  const storageApi = unsafeApi.query[palletInfo.name][storageItem.name];
2922
- const parsedKeys = parseStorageKeys(meta, palletInfo.name, storageItem, keys);
3013
+ const parsedKeys = await parseStorageKeys(meta, palletInfo.name, storageItem, keys);
2923
3014
  const format = opts.output ?? "pretty";
2924
3015
  if (storageItem.type === "map" && parsedKeys.length === 0) {
2925
3016
  const entries = await storageApi.getEntries();
@@ -2945,7 +3036,7 @@ ${DIM}Showing ${limit} of ${entries.length} entries. Use --limit 0 for all.${RES
2945
3036
  function palletName(name) {
2946
3037
  return name;
2947
3038
  }
2948
- function parseStorageKeys(meta, palletName2, storageItem, args) {
3039
+ async function parseStorageKeys(meta, palletName2, storageItem, args) {
2949
3040
  if (storageItem.type === "plain" || storageItem.keyTypeId == null) {
2950
3041
  return args.map(parseValue);
2951
3042
  }
@@ -2956,11 +3047,11 @@ function parseStorageKeys(meta, palletName2, storageItem, args) {
2956
3047
  const keyEntry = meta.lookup(storageItem.keyTypeId);
2957
3048
  if (len === 1) {
2958
3049
  if (args.length === 1) {
2959
- return [parseTypedArg(meta, keyEntry, args[0])];
3050
+ return [await parseTypedArg(meta, keyEntry, args[0])];
2960
3051
  }
2961
3052
  if (keyEntry.type === "struct") {
2962
3053
  const label = `${palletName2}.${storageItem.name} key`;
2963
- return [parseStructArgs(meta, keyEntry.value, args, label)];
3054
+ return [await parseStructArgs(meta, keyEntry.value, args, label)];
2964
3055
  }
2965
3056
  const typeDesc = describeType(meta.lookup, storageItem.keyTypeId);
2966
3057
  throw new Error(`${palletName2}.${storageItem.name} key expects ${typeDesc}
@@ -2977,9 +3068,9 @@ function parseStorageKeys(meta, palletName2, storageItem, args) {
2977
3068
  }
2978
3069
  if (keyEntry.type === "tuple") {
2979
3070
  const entries = keyEntry.value;
2980
- return entries.map((entry, i) => parseTypedArg(meta, entry, args[i]));
3071
+ return Promise.all(entries.map((entry, i) => parseTypedArg(meta, entry, args[i])));
2981
3072
  }
2982
- return args.map((arg) => parseTypedArg(meta, keyEntry, arg));
3073
+ return Promise.all(args.map((arg) => parseTypedArg(meta, keyEntry, arg)));
2983
3074
  }
2984
3075
 
2985
3076
  // src/commands/tx.ts
@@ -3090,7 +3181,7 @@ async function handleTx(target, args, opts) {
3090
3181
  const callNames = palletInfo.calls.map((c) => c.name);
3091
3182
  throw new Error(suggestMessage(`call in ${palletInfo.name}`, callName, callNames));
3092
3183
  }
3093
- const callData = parseCallArgs(meta, palletInfo.name, callInfo.name, args);
3184
+ const callData = await parseCallArgs(meta, palletInfo.name, callInfo.name, args);
3094
3185
  if (opts.encode) {
3095
3186
  const { codec, location } = meta.builder.buildCall(palletInfo.name, callInfo.name);
3096
3187
  const encodedArgs = codec.enc(callData);
@@ -3339,7 +3430,7 @@ function formatEventValue(v) {
3339
3430
  }
3340
3431
  return JSON.stringify(v, (_k, val) => typeof val === "bigint" ? val.toString() : val);
3341
3432
  }
3342
- function parseCallArgs(meta, palletName2, callName, args) {
3433
+ async function parseCallArgs(meta, palletName2, callName, args) {
3343
3434
  const palletMeta = meta.unified.pallets.find((p) => p.name === palletName2);
3344
3435
  if (!palletMeta?.calls)
3345
3436
  return;
@@ -3356,12 +3447,12 @@ function parseCallArgs(meta, palletName2, callName, args) {
3356
3447
  return;
3357
3448
  }
3358
3449
  if (variant.type === "struct") {
3359
- return parseStructArgs2(meta, variant.value, args, `${palletName2}.${callName}`);
3450
+ return await parseStructArgs2(meta, variant.value, args, `${palletName2}.${callName}`);
3360
3451
  }
3361
3452
  if (variant.type === "lookupEntry") {
3362
3453
  const inner = variant.value;
3363
3454
  if (inner.type === "struct") {
3364
- return parseStructArgs2(meta, inner.value, args, `${palletName2}.${callName}`);
3455
+ return await parseStructArgs2(meta, inner.value, args, `${palletName2}.${callName}`);
3365
3456
  }
3366
3457
  if (inner.type === "void")
3367
3458
  return;
@@ -3369,7 +3460,7 @@ function parseCallArgs(meta, palletName2, callName, args) {
3369
3460
  throw new Error(`${palletName2}.${callName} takes 1 argument (${describeType(meta.lookup, inner.id)}), but ${args.length} provided.`);
3370
3461
  }
3371
3462
  try {
3372
- return parseTypedArg2(meta, inner, args[0]);
3463
+ return await parseTypedArg2(meta, inner, args[0]);
3373
3464
  } catch (err) {
3374
3465
  const typeDesc = describeType(meta.lookup, inner.id);
3375
3466
  throw new Error(`Invalid value for argument 0 (expected ${typeDesc}): ${JSON.stringify(args[0])}`, { cause: err });
@@ -3380,18 +3471,18 @@ function parseCallArgs(meta, palletName2, callName, args) {
3380
3471
  if (args.length !== entries.length) {
3381
3472
  throw new Error(`${palletName2}.${callName} takes ${entries.length} arguments, but ${args.length} provided.`);
3382
3473
  }
3383
- return entries.map((entry, i) => {
3474
+ return Promise.all(entries.map(async (entry, i) => {
3384
3475
  try {
3385
- return parseTypedArg2(meta, entry, args[i]);
3476
+ return await parseTypedArg2(meta, entry, args[i]);
3386
3477
  } catch (err) {
3387
3478
  const typeDesc = describeType(meta.lookup, entry.id);
3388
3479
  throw new Error(`Invalid value for argument ${i} (expected ${typeDesc}): ${JSON.stringify(args[i])}`, { cause: err });
3389
3480
  }
3390
- });
3481
+ }));
3391
3482
  }
3392
3483
  return args.length === 0 ? undefined : args.map(parseValue);
3393
3484
  }
3394
- function parseStructArgs2(meta, fields, args, callLabel) {
3485
+ async function parseStructArgs2(meta, fields, args, callLabel) {
3395
3486
  const fieldNames = Object.keys(fields);
3396
3487
  if (args.length !== fieldNames.length) {
3397
3488
  const expected = fieldNames.map((name) => `${name}: ${describeType(meta.lookup, fields[name].id)}`).join(", ");
@@ -3403,7 +3494,7 @@ function parseStructArgs2(meta, fields, args, callLabel) {
3403
3494
  const name = fieldNames[i];
3404
3495
  const entry = fields[name];
3405
3496
  try {
3406
- result[name] = parseTypedArg2(meta, entry, args[i]);
3497
+ result[name] = await parseTypedArg2(meta, entry, args[i]);
3407
3498
  } catch (err) {
3408
3499
  const typeDesc = describeType(meta.lookup, entry.id);
3409
3500
  throw new Error(`Invalid value for argument '${name}' (expected ${typeDesc}): ${JSON.stringify(args[i])}
@@ -3549,7 +3640,7 @@ function parseEnumShorthand2(arg) {
3549
3640
  return null;
3550
3641
  return { variant, inner: arg.slice(firstParen + 1, -1) };
3551
3642
  }
3552
- function parseTypedArg2(meta, entry, arg) {
3643
+ async function parseTypedArg2(meta, entry, arg) {
3553
3644
  if (entry.type === "lookupEntry")
3554
3645
  return parseTypedArg2(meta, entry.value, arg);
3555
3646
  switch (entry.type) {
@@ -3558,6 +3649,7 @@ function parseTypedArg2(meta, entry, arg) {
3558
3649
  case "compact":
3559
3650
  return entry.isBig ? BigInt(arg) : parseInt(arg, 10);
3560
3651
  case "AccountId32":
3652
+ return resolveAccountAddress(arg);
3561
3653
  case "AccountId20":
3562
3654
  return arg;
3563
3655
  case "option": {
@@ -3586,7 +3678,7 @@ function parseTypedArg2(meta, entry, arg) {
3586
3678
  if (resolvedDef.type === "void" || shorthand.inner === "") {
3587
3679
  return { type: matched2 };
3588
3680
  }
3589
- const innerValue = parseTypedArg2(meta, variantDef, shorthand.inner);
3681
+ const innerValue = await parseTypedArg2(meta, variantDef, shorthand.inner);
3590
3682
  return normalizeValue2(meta.lookup, entry, { type: matched2, value: innerValue });
3591
3683
  }
3592
3684
  }
@@ -3594,7 +3686,8 @@ function parseTypedArg2(meta, entry, arg) {
3594
3686
  const idVariant = entry.value.Id;
3595
3687
  const innerType = idVariant.type === "lookupEntry" ? idVariant.value : idVariant;
3596
3688
  if (innerType.type === "AccountId32" && !arg.startsWith("{")) {
3597
- return { type: "Id", value: arg };
3689
+ const resolved = await resolveAccountAddress(arg);
3690
+ return { type: "Id", value: resolved };
3598
3691
  }
3599
3692
  }
3600
3693
  const matched = variants.find((v) => v.toLowerCase() === arg.toLowerCase());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polkadot-cli",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "CLI tool for querying Polkadot-ecosystem on-chain state",
5
5
  "type": "module",
6
6
  "bin": {