polkadot-cli 1.7.0 → 1.8.1

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 +58 -1
  2. package/dist/cli.mjs +215 -33
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -21,6 +21,7 @@ Ships with Polkadot and all system parachains preconfigured with multiple fallba
21
21
  - ✅ Runtime API calls — `dot apis.Core.version`
22
22
  - ✅ Batteries included — all system parachains and testnets already setup to be used
23
23
  - ✅ File-based commands — run any command from a YAML/JSON file with variable substitution
24
+ - ✅ Parachain sovereign accounts — derive child and sibling addresses from a parachain ID
24
25
 
25
26
  ### Preconfigured chains
26
27
 
@@ -496,6 +497,28 @@ dot tx Balances.transfer_keep_alive 5FHneW46... 1000000000000 --encode
496
497
  dot tx Sudo.sudo $(dot tx System.remark 0xcafe --encode) --from alice
497
498
  ```
498
499
 
500
+ #### Decode call data to YAML / JSON
501
+
502
+ Decode a hex-encoded call into a YAML or JSON file that is compatible with [file-based commands](#file-based-commands). This is useful for inspecting opaque call data, sharing human-readable transaction definitions, or editing parameters before re-submitting. Works offline from cached metadata and does not require `--from`.
503
+
504
+ ```bash
505
+ # Decode a raw hex call to YAML
506
+ dot tx.0x0001076465616462656566 --yaml
507
+
508
+ # Decode a raw hex call to JSON
509
+ dot tx.0x0001076465616462656566 --json
510
+
511
+ # Encode a named call and output as YAML
512
+ dot tx.System.remark 0xdeadbeef --yaml
513
+
514
+ # Round-trip: encode to hex, decode to YAML, re-encode from file
515
+ dot tx.System.remark 0xdeadbeef --encode # 0x0001076465616462656566
516
+ dot tx.0x0001076465616462656566 --yaml > remark.yaml
517
+ dot ./remark.yaml --encode # same hex
518
+ ```
519
+
520
+ `--yaml` / `--json` are mutually exclusive with each other and with `--encode` and `--dry-run`.
521
+
499
522
  Both dry-run and submission display the encoded call hex and a decoded human-readable form:
500
523
 
501
524
  ```
@@ -750,7 +773,15 @@ tx:
750
773
  value: ${AMOUNT}
751
774
  ```
752
775
 
753
- All existing flags work with file input `--chain` overrides the file's `chain:` field, `--from`, `--dry-run`, `--encode`, `--output`, etc. behave identically to inline commands.
776
+ Hex values passed via `--var` are preserved as-is, including leading zeros. This is important for encoded call data in XCM `Transact` instructions or similar byte-array fields:
777
+
778
+ ```bash
779
+ # Encode a remark, then embed it in an XCM Transact via --var
780
+ CALL=$(dot tx.System.remark 0xdead --encode)
781
+ dot ./xcm-transact.yaml --var CALL=$CALL --encode
782
+ ```
783
+
784
+ All existing flags work with file input — `--chain` overrides the file's `chain:` field, `--from`, `--dry-run`, `--encode`, `--yaml`, `--json`, `--output`, etc. behave identically to inline commands.
754
785
 
755
786
  ### Compute hashes
756
787
 
@@ -775,6 +806,32 @@ dot hash blake2b256 0xdeadbeef --output json
775
806
 
776
807
  Run `dot hash` with no arguments to see all available algorithms.
777
808
 
809
+ ### Parachain sovereign accounts
810
+
811
+ Derive the sovereign account addresses for a parachain. These are deterministic accounts derived from a parachain ID — no chain connection required.
812
+
813
+ - **Child** accounts represent a parachain on the relay chain (prefix `"para"`)
814
+ - **Sibling** accounts represent a parachain on another parachain (prefix `"sibl"`)
815
+
816
+ ```bash
817
+ # Show both child and sibling accounts
818
+ dot parachain 1000
819
+
820
+ # Show only the child (relay chain) account
821
+ dot parachain 2004 --type child
822
+
823
+ # Show only the sibling (parachain-to-parachain) account
824
+ dot parachain 2004 --type sibling
825
+
826
+ # Use Polkadot SS58 prefix (default: 42)
827
+ dot parachain 1000 --prefix 0
828
+
829
+ # JSON output
830
+ dot parachain 1000 --output json
831
+ ```
832
+
833
+ Run `dot parachain` with no arguments to see usage and examples.
834
+
778
835
  ### Getting help
779
836
 
780
837
  Every command supports `--help` to show its detailed usage, available actions, and examples:
package/dist/cli.mjs CHANGED
@@ -966,6 +966,7 @@ function parseValue(arg) {
966
966
  // src/commands/tx.ts
967
967
  import { getViewBuilder } from "@polkadot-api/view-builder";
968
968
  import { Binary as Binary2 } from "polkadot-api";
969
+ import { stringify as stringifyYaml } from "yaml";
969
970
  async function parseStructArgs(meta, fields, args, callLabel) {
970
971
  const fieldNames = Object.keys(fields);
971
972
  if (args.length !== fieldNames.length) {
@@ -1967,6 +1968,12 @@ async function generateCompletions(currentWord, precedingWords) {
1967
1968
  if (firstArg === "hash") {
1968
1969
  return filterPrefix(getAlgorithmNames(), currentWord);
1969
1970
  }
1971
+ if (firstArg === "parachain") {
1972
+ if (prevWord === "--type") {
1973
+ return filterPrefix(["child", "sibling"], currentWord);
1974
+ }
1975
+ return [];
1976
+ }
1970
1977
  return completeDotpath(currentWord, config, knownChains, precedingWords);
1971
1978
  }
1972
1979
  function detectCategory(words, _knownChains) {
@@ -2130,7 +2137,7 @@ var init_complete = __esm(() => {
2130
2137
  apis: "apis",
2131
2138
  api: "apis"
2132
2139
  };
2133
- NAMED_COMMANDS = ["chain", "account", "inspect", "hash", "completions"];
2140
+ NAMED_COMMANDS = ["chain", "account", "inspect", "hash", "parachain", "completions"];
2134
2141
  CHAIN_SUBCOMMANDS = ["add", "remove", "update", "list", "default"];
2135
2142
  ACCOUNT_SUBCOMMANDS = [
2136
2143
  "add",
@@ -2151,7 +2158,7 @@ var init_complete = __esm(() => {
2151
2158
  // src/cli.ts
2152
2159
  import cac from "cac";
2153
2160
  // package.json
2154
- var version = "1.7.0";
2161
+ var version = "1.8.1";
2155
2162
 
2156
2163
  // src/commands/account.ts
2157
2164
  init_accounts_store();
@@ -3433,6 +3440,7 @@ async function showItemHelp2(category, target, opts) {
3433
3440
  init_hash();
3434
3441
  init_output();
3435
3442
  init_errors();
3443
+ import { readFile as readFile3 } from "node:fs/promises";
3436
3444
  async function resolveInput(data, opts) {
3437
3445
  const sources = [data !== undefined, !!opts.file, !!opts.stdin].filter(Boolean).length;
3438
3446
  if (sources > 1) {
@@ -3442,26 +3450,15 @@ async function resolveInput(data, opts) {
3442
3450
  throw new CliError("No input provided. Pass data as argument, or use --file or --stdin");
3443
3451
  }
3444
3452
  if (opts.file) {
3445
- const buf = await Bun.file(opts.file).arrayBuffer();
3453
+ const buf = await readFile3(opts.file);
3446
3454
  return new Uint8Array(buf);
3447
3455
  }
3448
3456
  if (opts.stdin) {
3449
- const reader = Bun.stdin.stream().getReader();
3450
3457
  const chunks = [];
3451
- while (true) {
3452
- const { done, value } = await reader.read();
3453
- if (done)
3454
- break;
3455
- chunks.push(value);
3456
- }
3457
- const totalLen = chunks.reduce((sum, c) => sum + c.length, 0);
3458
- const result = new Uint8Array(totalLen);
3459
- let offset = 0;
3460
- for (const chunk of chunks) {
3461
- result.set(chunk, offset);
3462
- offset += chunk.length;
3458
+ for await (const chunk of process.stdin) {
3459
+ chunks.push(chunk);
3463
3460
  }
3464
- return result;
3461
+ return new Uint8Array(Buffer.concat(chunks));
3465
3462
  }
3466
3463
  return parseInputData(data);
3467
3464
  }
@@ -3765,6 +3762,97 @@ function registerInspectCommand(cli) {
3765
3762
  });
3766
3763
  }
3767
3764
 
3765
+ // src/commands/parachain.ts
3766
+ init_accounts();
3767
+ init_output();
3768
+
3769
+ // src/core/parachain.ts
3770
+ var SOVEREIGN_ACCOUNT_TYPES = ["child", "sibling"];
3771
+ var PREFIXES = {
3772
+ child: new Uint8Array([112, 97, 114, 97]),
3773
+ sibling: new Uint8Array([115, 105, 98, 108])
3774
+ };
3775
+ function deriveSovereignAccount(paraId, type) {
3776
+ const result = new Uint8Array(32);
3777
+ result.set(PREFIXES[type], 0);
3778
+ new DataView(result.buffer).setUint32(4, paraId, true);
3779
+ return result;
3780
+ }
3781
+ function isValidParaId(value) {
3782
+ return Number.isInteger(value) && value >= 0 && value <= 4294967295;
3783
+ }
3784
+
3785
+ // src/commands/parachain.ts
3786
+ init_errors();
3787
+ function printParachainHelp() {
3788
+ console.log(`${BOLD}Usage:${RESET} dot parachain <paraId> [options]
3789
+ `);
3790
+ console.log(`${BOLD}Description:${RESET}`);
3791
+ console.log(` Derive sovereign account addresses for a parachain.
3792
+ `);
3793
+ console.log(` ${DIM}Child accounts represent a parachain on the relay chain.${RESET}`);
3794
+ console.log(` ${DIM}Sibling accounts represent a parachain on another parachain.${RESET}
3795
+ `);
3796
+ console.log(`${BOLD}Options:${RESET}`);
3797
+ console.log(` ${CYAN}--type <child|sibling>${RESET} ${DIM}Account type (default: both)${RESET}`);
3798
+ console.log(` ${CYAN}--prefix <N>${RESET} ${DIM}SS58 prefix (default: 42)${RESET}`);
3799
+ console.log(` ${CYAN}--output json${RESET} ${DIM}Output as JSON${RESET}`);
3800
+ console.log(`
3801
+ ${BOLD}Examples:${RESET}`);
3802
+ console.log(` ${DIM}$ dot parachain 1000${RESET}`);
3803
+ console.log(` ${DIM}$ dot parachain 2004 --prefix 0${RESET}`);
3804
+ console.log(` ${DIM}$ dot parachain 1000 --type sibling${RESET}`);
3805
+ console.log(` ${DIM}$ dot parachain 2000 --output json${RESET}`);
3806
+ }
3807
+ function validateType(type) {
3808
+ const lower = type.toLowerCase();
3809
+ if (lower === "child" || lower === "sibling")
3810
+ return lower;
3811
+ throw new CliError(`Unknown account type "${type}". Valid types: child, sibling.`);
3812
+ }
3813
+ function registerParachainCommand(cli) {
3814
+ cli.command("parachain [paraId]", "Derive parachain sovereign accounts").option("--type <type>", "Account type: child, sibling (default: both)").option("--prefix <number>", "SS58 prefix for address encoding (default: 42)").action(async (paraIdStr, opts) => {
3815
+ if (!paraIdStr) {
3816
+ printParachainHelp();
3817
+ return;
3818
+ }
3819
+ const paraId = Number(paraIdStr);
3820
+ if (!isValidParaId(paraId)) {
3821
+ throw new CliError(`Invalid parachain ID "${paraIdStr}". Must be a non-negative integer (0 to 4294967295).`);
3822
+ }
3823
+ const prefix = opts.prefix != null ? Number(opts.prefix) : 42;
3824
+ if (Number.isNaN(prefix) || prefix < 0) {
3825
+ throw new CliError(`Invalid prefix "${opts.prefix}". Must be a non-negative integer.`);
3826
+ }
3827
+ const types = opts.type ? [validateType(opts.type)] : SOVEREIGN_ACCOUNT_TYPES;
3828
+ const format = opts.output ?? "pretty";
3829
+ if (format === "json") {
3830
+ const result = { paraId, prefix };
3831
+ for (const type of types) {
3832
+ const accountId = deriveSovereignAccount(paraId, type);
3833
+ result[type] = {
3834
+ publicKey: publicKeyToHex(accountId),
3835
+ ss58: toSs58(accountId, prefix)
3836
+ };
3837
+ }
3838
+ console.log(formatJson(result));
3839
+ } else {
3840
+ printHeading(`Parachain ${paraId} — Sovereign Accounts`);
3841
+ for (const type of types) {
3842
+ const accountId = deriveSovereignAccount(paraId, type);
3843
+ const hex = publicKeyToHex(accountId);
3844
+ const ss58 = toSs58(accountId, prefix);
3845
+ const label = type.charAt(0).toUpperCase() + type.slice(1);
3846
+ console.log(` ${BOLD}${label}:${RESET}`);
3847
+ console.log(` ${BOLD}Public Key:${RESET} ${hex}`);
3848
+ console.log(` ${BOLD}SS58:${RESET} ${ss58}`);
3849
+ console.log(` ${BOLD}Prefix:${RESET} ${prefix}`);
3850
+ console.log();
3851
+ }
3852
+ }
3853
+ });
3854
+ }
3855
+
3768
3856
  // src/commands/query.ts
3769
3857
  init_store();
3770
3858
  init_client();
@@ -3918,6 +4006,7 @@ init_errors();
3918
4006
  init_focused_inspect();
3919
4007
  import { getViewBuilder as getViewBuilder2 } from "@polkadot-api/view-builder";
3920
4008
  import { Binary as Binary3 } from "polkadot-api";
4009
+ import { stringify as stringifyYaml2 } from "yaml";
3921
4010
  function parseWaitLevel(raw) {
3922
4011
  switch (raw) {
3923
4012
  case "broadcast":
@@ -3968,7 +4057,7 @@ async function handleTx(target, args, opts) {
3968
4057
  console.log();
3969
4058
  return;
3970
4059
  }
3971
- if (!opts.from && !opts.encode) {
4060
+ if (!opts.from && !opts.encode && !opts.yaml && !opts.json) {
3972
4061
  if (isRawCall) {
3973
4062
  throw new Error("--from is required (or use --encode to output hex without signing)");
3974
4063
  }
@@ -3981,6 +4070,15 @@ async function handleTx(target, args, opts) {
3981
4070
  if (opts.encode && isRawCall) {
3982
4071
  throw new Error("--encode cannot be used with raw call hex (already encoded)");
3983
4072
  }
4073
+ if ((opts.yaml || opts.json) && opts.encode) {
4074
+ throw new Error("--yaml/--json and --encode are mutually exclusive");
4075
+ }
4076
+ if ((opts.yaml || opts.json) && opts.dryRun) {
4077
+ throw new Error("--yaml/--json and --dry-run are mutually exclusive");
4078
+ }
4079
+ if (opts.yaml && opts.json) {
4080
+ throw new Error("--yaml and --json are mutually exclusive");
4081
+ }
3984
4082
  const config = await loadConfig();
3985
4083
  const effectiveChain = opts.chain;
3986
4084
  let pallet;
@@ -3991,9 +4089,10 @@ async function handleTx(target, args, opts) {
3991
4089
  callName = target.slice(dotIdx + 1);
3992
4090
  }
3993
4091
  const { name: chainName, chain: chainConfig } = resolveChain(config, effectiveChain);
3994
- const signer = opts.encode ? undefined : await resolveAccountSigner(opts.from);
4092
+ const decodeOnly = opts.encode || opts.yaml || opts.json;
4093
+ const signer = decodeOnly ? undefined : await resolveAccountSigner(opts.from);
3995
4094
  let clientHandle;
3996
- if (!opts.encode) {
4095
+ if (!decodeOnly) {
3997
4096
  clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
3998
4097
  }
3999
4098
  try {
@@ -4010,7 +4109,7 @@ async function handleTx(target, args, opts) {
4010
4109
  }
4011
4110
  let unsafeApi;
4012
4111
  let txOptions;
4013
- if (!opts.encode) {
4112
+ if (!decodeOnly) {
4014
4113
  const userExtOverrides = parseExtOption(opts.ext);
4015
4114
  const customSignedExtensions = buildCustomSignedExtensions(meta, userExtOverrides);
4016
4115
  txOptions = Object.keys(customSignedExtensions).length > 0 ? { customSignedExtensions } : undefined;
@@ -4023,9 +4122,14 @@ async function handleTx(target, args, opts) {
4023
4122
  throw new Error(`Extra arguments are not allowed when submitting a raw call hex.
4024
4123
  ` + "Usage: dot tx 0x<call_hex> --from <account>");
4025
4124
  }
4125
+ callHex = target;
4126
+ if (opts.yaml || opts.json) {
4127
+ const fileObj = decodeCallToFileFormat(meta, callHex, chainName);
4128
+ outputFileFormat(fileObj, !!opts.yaml);
4129
+ return;
4130
+ }
4026
4131
  const callBinary = Binary3.fromHex(target);
4027
4132
  tx = await unsafeApi.txFromCallData(callBinary);
4028
- callHex = target;
4029
4133
  } else {
4030
4134
  const palletNames = getPalletNames(meta);
4031
4135
  const palletInfo = findPallet(meta, pallet);
@@ -4039,11 +4143,17 @@ async function handleTx(target, args, opts) {
4039
4143
  }
4040
4144
  const effectiveArgs = opts.parsedArgs !== undefined ? fileArgsToStrings(opts.parsedArgs) : args;
4041
4145
  const callData = await parseCallArgs(meta, palletInfo.name, callInfo.name, effectiveArgs);
4042
- if (opts.encode) {
4146
+ if (opts.encode || opts.yaml || opts.json) {
4043
4147
  const { codec, location } = meta.builder.buildCall(palletInfo.name, callInfo.name);
4044
4148
  const encodedArgs = codec.enc(callData);
4045
4149
  const fullCall = new Uint8Array([location[0], location[1], ...encodedArgs]);
4046
- console.log(Binary3.fromBytes(fullCall).asHex());
4150
+ const hex = Binary3.fromBytes(fullCall).asHex();
4151
+ if (opts.encode) {
4152
+ console.log(hex);
4153
+ return;
4154
+ }
4155
+ const fileObj = decodeCallToFileFormat(meta, hex, chainName);
4156
+ outputFileFormat(fileObj, !!opts.yaml);
4047
4157
  return;
4048
4158
  }
4049
4159
  tx = unsafeApi.tx[palletInfo.name][callInfo.name](callData);
@@ -4164,6 +4274,58 @@ function decodeCallFallback(meta, callHex) {
4164
4274
  const argsStr = formatRawDecoded(args);
4165
4275
  return `${palletName2}.${callName} ${argsStr}`;
4166
4276
  }
4277
+ function decodeCallToFileFormat(meta, callHex, chainName) {
4278
+ const callTypeId = meta.lookup.call;
4279
+ if (callTypeId == null)
4280
+ throw new Error("No RuntimeCall type ID in metadata");
4281
+ const codec = meta.builder.buildDefinition(callTypeId);
4282
+ const decoded = codec.dec(Binary3.fromHex(callHex).asBytes());
4283
+ const palletName2 = decoded.type;
4284
+ const call = decoded.value;
4285
+ const callName = call.type;
4286
+ const args = call.value;
4287
+ return {
4288
+ chain: chainName,
4289
+ tx: {
4290
+ [palletName2]: {
4291
+ [callName]: sanitizeForSerialization(args) ?? null
4292
+ }
4293
+ }
4294
+ };
4295
+ }
4296
+ function sanitizeForSerialization(value) {
4297
+ if (value === undefined || value === null)
4298
+ return null;
4299
+ if (value instanceof Binary3)
4300
+ return value.asHex();
4301
+ if (typeof value === "bigint") {
4302
+ if (value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER) {
4303
+ return Number(value);
4304
+ }
4305
+ return value.toString();
4306
+ }
4307
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
4308
+ return value;
4309
+ }
4310
+ if (Array.isArray(value)) {
4311
+ return value.map(sanitizeForSerialization);
4312
+ }
4313
+ if (typeof value === "object") {
4314
+ const result = {};
4315
+ for (const [k, v] of Object.entries(value)) {
4316
+ result[k] = sanitizeForSerialization(v);
4317
+ }
4318
+ return result;
4319
+ }
4320
+ return String(value);
4321
+ }
4322
+ function outputFileFormat(obj, asYaml) {
4323
+ if (asYaml) {
4324
+ process.stdout.write(stringifyYaml2(obj));
4325
+ } else {
4326
+ console.log(JSON.stringify(obj, null, 2));
4327
+ }
4328
+ }
4167
4329
  function formatRawDecoded(value) {
4168
4330
  if (value === undefined || value === null)
4169
4331
  return "null";
@@ -4786,7 +4948,7 @@ function watchTransaction(observable, level) {
4786
4948
 
4787
4949
  // src/config/store.ts
4788
4950
  init_types();
4789
- import { access as access3, mkdir as mkdir3, readFile as readFile3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
4951
+ import { access as access3, mkdir as mkdir3, readFile as readFile4, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
4790
4952
  import { homedir as homedir2 } from "node:os";
4791
4953
  import { join as join3 } from "node:path";
4792
4954
  var DOT_DIR2 = join3(homedir2(), ".polkadot");
@@ -4806,7 +4968,7 @@ async function fileExists3(path) {
4806
4968
  async function loadConfig2() {
4807
4969
  await ensureDir3(DOT_DIR2);
4808
4970
  if (await fileExists3(CONFIG_PATH2)) {
4809
- const saved = JSON.parse(await readFile3(CONFIG_PATH2, "utf-8"));
4971
+ const saved = JSON.parse(await readFile4(CONFIG_PATH2, "utf-8"));
4810
4972
  return {
4811
4973
  ...saved,
4812
4974
  chains: { ...DEFAULT_CONFIG.chains, ...saved.chains }
@@ -4823,6 +4985,7 @@ async function saveConfig2(config) {
4823
4985
 
4824
4986
  // src/core/file-loader.ts
4825
4987
  init_errors();
4988
+ import { access as access4, readFile as readFile5 } from "node:fs/promises";
4826
4989
  import { parse as parseYaml } from "yaml";
4827
4990
  var CATEGORIES = ["tx", "query", "const", "apis"];
4828
4991
  var FILE_EXTENSIONS = [".json", ".yaml", ".yml"];
@@ -4870,16 +5033,24 @@ function substituteVars(text, vars) {
4870
5033
  return envVal;
4871
5034
  if (defaultValue !== undefined)
4872
5035
  return defaultValue;
4873
- throw new CliError(`Undefined variable "\${${varName}}" in file. ` + `Provide it via --var ${varName}=VALUE, as an environment variable, ` + `or add a default with \${${varName}:-default}.`);
5036
+ throw new CliError(`Undefined variable "\${${varName}}" in file.
5037
+
5038
+ ` + ` Provide it using one of:
5039
+ ` + ` --var ${varName}=VALUE
5040
+ ` + ` ${varName}=VALUE dot ... (environment variable)
5041
+ ` + ` \${${varName}:-default} (inline default in file)`);
4874
5042
  });
4875
5043
  }
5044
+ function quoteYamlHexValues(text) {
5045
+ return text.replace(/^(\s*(?:[^:]+:\s+|-\s+))(0x[0-9a-fA-F]+)\s*$/gm, '$1"$2"');
5046
+ }
4876
5047
  async function loadCommandFile(filePath, cliVars) {
4877
- const file = Bun.file(filePath);
4878
- const exists = await file.exists();
4879
- if (!exists) {
5048
+ try {
5049
+ await access4(filePath);
5050
+ } catch {
4880
5051
  throw new CliError(`File not found: ${filePath}`);
4881
5052
  }
4882
- const rawText = await file.text();
5053
+ const rawText = await readFile5(filePath, "utf-8");
4883
5054
  if (!rawText.trim()) {
4884
5055
  throw new CliError(`File is empty: ${filePath}`);
4885
5056
  }
@@ -4898,9 +5069,10 @@ async function loadCommandFile(filePath, cliVars) {
4898
5069
  } catch {}
4899
5070
  const mergedVars = { ...fileVars, ...cliVars };
4900
5071
  const substituted = substituteVars(rawText, mergedVars);
5072
+ const textToParse = isJson ? substituted : quoteYamlHexValues(substituted);
4901
5073
  let parsed;
4902
5074
  try {
4903
- parsed = isJson ? JSON.parse(substituted) : parseYaml(substituted);
5075
+ parsed = isJson ? JSON.parse(textToParse) : parseYaml(textToParse);
4904
5076
  } catch (err) {
4905
5077
  const format = isJson ? "JSON" : "YAML";
4906
5078
  const msg = err instanceof Error ? err.message : String(err);
@@ -5191,12 +5363,15 @@ if (process.argv[2] === "__complete") {
5191
5363
  console.log(" dot apis.Core.version Call a runtime API");
5192
5364
  console.log(" dot polkadot.query.System.Number With chain prefix");
5193
5365
  console.log(" dot ./transfer.yaml --from alice Run from file");
5366
+ console.log(" dot tx.0x1f0003... --yaml Decode hex call to YAML");
5367
+ console.log(" dot tx.System.remark 0xdead --json Encode & output as JSON file format");
5194
5368
  console.log();
5195
5369
  console.log("Commands:");
5196
5370
  console.log(" inspect [target] Inspect chain metadata (alias: explore)");
5197
5371
  console.log(" chain Manage chain configurations");
5198
5372
  console.log(" account Manage accounts");
5199
5373
  console.log(" hash Hash utilities");
5374
+ console.log(" parachain Derive parachain sovereign accounts");
5200
5375
  console.log(" completions <sh> Generate shell completions (zsh, bash, fish)");
5201
5376
  console.log();
5202
5377
  console.log("Global options:");
@@ -5219,8 +5394,9 @@ if (process.argv[2] === "__complete") {
5219
5394
  registerInspectCommand(cli);
5220
5395
  registerAccountCommands(cli);
5221
5396
  registerHashCommand(cli);
5397
+ registerParachainCommand(cli);
5222
5398
  registerCompletionsCommand(cli);
5223
- cli.command("[dotpath] [...args]").option("--from <name>", "Account to sign with (for tx)").option("--dry-run", "Estimate fees without submitting (for tx)").option("--encode", "Encode call to hex without signing (for tx)").option("--ext <json>", "Custom signed extension values as JSON (for tx)").option("-w, --wait <level>", "Resolve at: broadcast, best-block (or best), finalized (for tx)", {
5399
+ cli.command("[dotpath] [...args]").option("--from <name>", "Account to sign with (for tx)").option("--dry-run", "Estimate fees without submitting (for tx)").option("--encode", "Encode call to hex without signing (for tx)").option("--yaml", "Decode call to YAML file format (for tx)").option("--json", "Decode call to JSON file format (for tx)").option("--ext <json>", "Custom signed extension values as JSON (for tx)").option("-w, --wait <level>", "Resolve at: broadcast, best-block (or best), finalized (for tx)", {
5224
5400
  default: "finalized"
5225
5401
  }).option("--limit <n>", "Max entries to return for map queries (0 = unlimited)", {
5226
5402
  default: 100
@@ -5242,6 +5418,8 @@ if (process.argv[2] === "__complete") {
5242
5418
  from: opts.from,
5243
5419
  dryRun: opts.dryRun,
5244
5420
  encode: opts.encode,
5421
+ yaml: opts.yaml,
5422
+ json: opts.json,
5245
5423
  ext: opts.ext,
5246
5424
  wait: opts.wait,
5247
5425
  parsedArgs: cmd.args
@@ -5302,6 +5480,8 @@ if (process.argv[2] === "__complete") {
5302
5480
  from: opts.from,
5303
5481
  dryRun: opts.dryRun,
5304
5482
  encode: opts.encode,
5483
+ yaml: opts.yaml,
5484
+ json: opts.json,
5305
5485
  ext: opts.ext,
5306
5486
  wait: opts.wait
5307
5487
  });
@@ -5311,6 +5491,8 @@ if (process.argv[2] === "__complete") {
5311
5491
  from: opts.from,
5312
5492
  dryRun: opts.dryRun,
5313
5493
  encode: opts.encode,
5494
+ yaml: opts.yaml,
5495
+ json: opts.json,
5314
5496
  ext: opts.ext,
5315
5497
  wait: opts.wait
5316
5498
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polkadot-cli",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "CLI tool for querying Polkadot-ecosystem on-chain state",
5
5
  "type": "module",
6
6
  "bin": {