polkadot-cli 1.9.0 → 1.10.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 +111 -25
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -617,6 +617,40 @@ For manual override, use `--ext` with a JSON object:
617
617
  dot tx System.remark 0xdeadbeef --from alice --ext '{"MyExtension":{"value":"..."}}'
618
618
  ```
619
619
 
620
+ #### Transaction options
621
+
622
+ Override low-level transaction parameters. Useful for rapid-fire submission (custom nonce), priority fees (tip), or controlling transaction lifetime (mortality).
623
+
624
+ | Flag | Value | Description |
625
+ |------|-------|-------------|
626
+ | `--nonce <n>` | non-negative integer | Override the auto-detected nonce |
627
+ | `--tip <amount>` | non-negative integer (planck) | Priority tip for the transaction pool |
628
+ | `--mortality <spec>` | `immortal` or period (min 4) | Transaction mortality window |
629
+ | `--at <block>` | `best`, `finalized`, or 0x-prefixed block hash | Block state to validate against |
630
+
631
+ ```bash
632
+ # Fire-and-forget: submit two txs in rapid succession with manual nonces
633
+ dot tx System.remark 0xdead --from alice --nonce 0 --wait broadcast
634
+ dot tx System.remark 0xbeef --from alice --nonce 1 --wait broadcast
635
+
636
+ # Add a priority tip (in planck)
637
+ dot tx Balances.transferKeepAlive 5FHneW46... 1000000000000 --from alice --tip 1000000
638
+
639
+ # Submit an immortal transaction (no expiry)
640
+ dot tx System.remark 0xdead --from alice --mortality immortal
641
+
642
+ # Set a custom mortality period (rounds up to nearest power of two)
643
+ dot tx System.remark 0xdead --from alice --mortality 128
644
+
645
+ # Validate against the best (not finalized) block
646
+ dot tx System.remark 0xdead --from alice --at best
647
+
648
+ # Combine: rapid-fire with tip and broadcast-only
649
+ dot tx System.remark 0xdead --from alice --nonce 5 --tip 500000 --wait broadcast
650
+ ```
651
+
652
+ When set, nonce / tip / mortality / at are shown in both `--dry-run` and submission output. These flags are silently ignored with `--encode`, `--yaml`, and `--json` (which return before signing).
653
+
620
654
  ### File-based commands
621
655
 
622
656
  Run any `dot` command from a YAML or JSON file. Especially useful for complex calls like XCM messages that are hard to construct inline.
package/dist/cli.mjs CHANGED
@@ -2172,14 +2172,24 @@ var init_complete = __esm(() => {
2172
2172
  "inspect"
2173
2173
  ];
2174
2174
  GLOBAL_OPTIONS = ["--chain", "--rpc", "--light-client", "--output", "--help", "--version"];
2175
- TX_OPTIONS = ["--from", "--dry-run", "--encode", "--ext", "--wait"];
2175
+ TX_OPTIONS = [
2176
+ "--from",
2177
+ "--dry-run",
2178
+ "--encode",
2179
+ "--ext",
2180
+ "--wait",
2181
+ "--nonce",
2182
+ "--tip",
2183
+ "--mortality",
2184
+ "--at"
2185
+ ];
2176
2186
  QUERY_OPTIONS = ["--limit"];
2177
2187
  });
2178
2188
 
2179
2189
  // src/cli.ts
2180
2190
  import cac from "cac";
2181
2191
  // package.json
2182
- var version = "1.9.0";
2192
+ var version = "1.10.0";
2183
2193
 
2184
2194
  // src/commands/account.ts
2185
2195
  init_accounts_store();
@@ -4043,6 +4053,50 @@ function parseWaitLevel(raw) {
4043
4053
  throw new CliError(`Invalid --wait value "${raw}". Valid: broadcast, best-block, best, finalized`);
4044
4054
  }
4045
4055
  }
4056
+ function parseNonceOption(raw) {
4057
+ if (raw === undefined)
4058
+ return;
4059
+ const n = Number(raw);
4060
+ if (!Number.isInteger(n) || n < 0) {
4061
+ throw new CliError(`Invalid --nonce value "${raw}". Must be a non-negative integer.`);
4062
+ }
4063
+ return n;
4064
+ }
4065
+ function parseTipOption(raw) {
4066
+ if (raw === undefined)
4067
+ return;
4068
+ try {
4069
+ const t = BigInt(raw);
4070
+ if (t < 0n) {
4071
+ throw new CliError(`Invalid --tip value "${raw}". Must be a non-negative integer.`);
4072
+ }
4073
+ return t;
4074
+ } catch (err) {
4075
+ if (err instanceof CliError)
4076
+ throw err;
4077
+ throw new CliError(`Invalid --tip value "${raw}". Must be a non-negative integer.`);
4078
+ }
4079
+ }
4080
+ function parseMortalityOption(raw) {
4081
+ if (raw === undefined)
4082
+ return;
4083
+ if (raw === "immortal")
4084
+ return { mortal: false };
4085
+ const n = Number(raw);
4086
+ if (!Number.isInteger(n) || n < 4) {
4087
+ throw new CliError(`Invalid --mortality value "${raw}". Use "immortal" or a period number (minimum 4).`);
4088
+ }
4089
+ return { mortal: true, period: n };
4090
+ }
4091
+ function parseAtOption(raw) {
4092
+ if (raw === undefined)
4093
+ return;
4094
+ if (raw === "best" || raw === "finalized")
4095
+ return raw;
4096
+ if (/^0x[0-9a-fA-F]{64}$/.test(raw))
4097
+ return raw;
4098
+ throw new CliError(`Invalid --at value "${raw}". Use "best", "finalized", or a 0x-prefixed 32-byte block hash.`);
4099
+ }
4046
4100
  async function handleTx(target, args, opts) {
4047
4101
  if (!target) {
4048
4102
  const config2 = await loadConfig();
@@ -4131,10 +4185,25 @@ async function handleTx(target, args, opts) {
4131
4185
  }
4132
4186
  let unsafeApi;
4133
4187
  let txOptions;
4188
+ const nonce = parseNonceOption(opts.nonce);
4189
+ const tip = parseTipOption(opts.tip);
4190
+ const mortality = parseMortalityOption(opts.mortality);
4191
+ const at = parseAtOption(opts.at);
4134
4192
  if (!decodeOnly) {
4135
4193
  const userExtOverrides = parseExtOption(opts.ext);
4136
4194
  const customSignedExtensions = buildCustomSignedExtensions(meta, userExtOverrides);
4137
- txOptions = Object.keys(customSignedExtensions).length > 0 ? { customSignedExtensions } : undefined;
4195
+ const built = {};
4196
+ if (Object.keys(customSignedExtensions).length > 0)
4197
+ built.customSignedExtensions = customSignedExtensions;
4198
+ if (nonce !== undefined)
4199
+ built.nonce = nonce;
4200
+ if (tip !== undefined)
4201
+ built.tip = tip;
4202
+ if (mortality !== undefined)
4203
+ built.mortality = mortality;
4204
+ if (at !== undefined)
4205
+ built.at = at;
4206
+ txOptions = Object.keys(built).length > 0 ? built : undefined;
4138
4207
  unsafeApi = clientHandle?.client.getUnsafeApi();
4139
4208
  }
4140
4209
  let tx;
@@ -4189,6 +4258,14 @@ async function handleTx(target, args, opts) {
4189
4258
  console.log(` ${BOLD}From:${RESET} ${opts.from} (${signerAddress})`);
4190
4259
  console.log(` ${BOLD}Call:${RESET} ${callHex}`);
4191
4260
  console.log(` ${BOLD}Decode:${RESET} ${decodedStr}`);
4261
+ if (nonce !== undefined)
4262
+ console.log(` ${BOLD}Nonce:${RESET} ${nonce}`);
4263
+ if (tip !== undefined)
4264
+ console.log(` ${BOLD}Tip:${RESET} ${tip}`);
4265
+ if (mortality !== undefined)
4266
+ console.log(` ${BOLD}Mortality:${RESET} ${mortality.mortal ? `mortal (period ${mortality.period})` : "immortal"}`);
4267
+ if (at !== undefined)
4268
+ console.log(` ${BOLD}At:${RESET} ${at}`);
4192
4269
  try {
4193
4270
  const fees = await tx.getEstimatedFees(signer?.publicKey, txOptions);
4194
4271
  console.log(` ${BOLD}Estimated fees:${RESET} ${fees}`);
@@ -4204,6 +4281,14 @@ async function handleTx(target, args, opts) {
4204
4281
  console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
4205
4282
  console.log(` ${BOLD}Call:${RESET} ${callHex}`);
4206
4283
  console.log(` ${BOLD}Decode:${RESET} ${decodedStr}`);
4284
+ if (nonce !== undefined)
4285
+ console.log(` ${BOLD}Nonce:${RESET} ${nonce}`);
4286
+ if (tip !== undefined)
4287
+ console.log(` ${BOLD}Tip:${RESET} ${tip}`);
4288
+ if (mortality !== undefined)
4289
+ console.log(` ${BOLD}Mortality:${RESET} ${mortality.mortal ? `mortal (period ${mortality.period})` : "immortal"}`);
4290
+ if (at !== undefined)
4291
+ console.log(` ${BOLD}At:${RESET} ${at}`);
4207
4292
  console.log(` ${BOLD}Tx:${RESET} ${result.txHash}`);
4208
4293
  if (result.type === "broadcasted") {
4209
4294
  console.log(` ${BOLD}Status:${RESET} ${GREEN}broadcasted${RESET}`);
@@ -5421,7 +5506,7 @@ if (process.argv[2] === "__complete") {
5421
5506
  default: "finalized"
5422
5507
  }).option("--limit <n>", "Max entries to return for map queries (0 = unlimited)", {
5423
5508
  default: 100
5424
- }).option("--dump", "Dump all entries of a storage map (without specifying a key)").option("--var <kv>", "Template variable for file input (KEY=VALUE, repeatable)").action(async (dotpath, args, opts) => {
5509
+ }).option("--dump", "Dump all entries of a storage map (without specifying a key)").option("--var <kv>", "Template variable for file input (KEY=VALUE, repeatable)").option("--nonce <n>", "Custom nonce for manual tx sequencing (for tx)").option("--tip <amount>", "Tip to prioritize transaction (for tx)").option("--mortality <spec>", '"immortal" or period number (for tx)').option("--at <block>", 'Block hash, "best", or "finalized" to validate against (for tx)').action(async (dotpath, args, opts) => {
5425
5510
  if (!dotpath) {
5426
5511
  printHelp();
5427
5512
  return;
@@ -5443,6 +5528,10 @@ if (process.argv[2] === "__complete") {
5443
5528
  json: opts.json,
5444
5529
  ext: opts.ext,
5445
5530
  wait: opts.wait,
5531
+ nonce: opts.nonce,
5532
+ tip: opts.tip,
5533
+ mortality: opts.mortality,
5534
+ at: opts.at,
5446
5535
  parsedArgs: cmd.args
5447
5536
  });
5448
5537
  break;
@@ -5494,31 +5583,28 @@ if (process.argv[2] === "__complete") {
5494
5583
  case "query":
5495
5584
  await handleQuery(target, args, { ...handlerOpts, limit: opts.limit, dump: opts.dump });
5496
5585
  break;
5497
- case "tx":
5586
+ case "tx": {
5587
+ const txOpts = {
5588
+ ...handlerOpts,
5589
+ from: opts.from,
5590
+ dryRun: opts.dryRun,
5591
+ encode: opts.encode,
5592
+ yaml: opts.yaml,
5593
+ json: opts.json,
5594
+ ext: opts.ext,
5595
+ wait: opts.wait,
5596
+ nonce: opts.nonce,
5597
+ tip: opts.tip,
5598
+ mortality: opts.mortality,
5599
+ at: opts.at
5600
+ };
5498
5601
  if (parsed.pallet && /^0x[0-9a-fA-F]+$/.test(parsed.pallet)) {
5499
- await handleTx(parsed.pallet, args, {
5500
- ...handlerOpts,
5501
- from: opts.from,
5502
- dryRun: opts.dryRun,
5503
- encode: opts.encode,
5504
- yaml: opts.yaml,
5505
- json: opts.json,
5506
- ext: opts.ext,
5507
- wait: opts.wait
5508
- });
5602
+ await handleTx(parsed.pallet, args, txOpts);
5509
5603
  } else {
5510
- await handleTx(target, args, {
5511
- ...handlerOpts,
5512
- from: opts.from,
5513
- dryRun: opts.dryRun,
5514
- encode: opts.encode,
5515
- yaml: opts.yaml,
5516
- json: opts.json,
5517
- ext: opts.ext,
5518
- wait: opts.wait
5519
- });
5604
+ await handleTx(target, args, txOpts);
5520
5605
  }
5521
5606
  break;
5607
+ }
5522
5608
  case "const":
5523
5609
  await handleConst(target, handlerOpts);
5524
5610
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polkadot-cli",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "CLI tool for querying Polkadot-ecosystem on-chain state",
5
5
  "type": "module",
6
6
  "bin": {