polkadot-cli 1.15.1 → 1.17.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 +544 -147
  2. package/dist/cli.mjs +944 -242
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,6 +20,8 @@ Ships with Polkadot and all system parachains preconfigured with multiple fallba
20
20
  - ✅ Account management — BIP39 mnemonics, derivation paths, env-backed secrets, watch-only, dev accounts
21
21
  - ✅ Named address resolution across all commands
22
22
  - ✅ Runtime API calls — `dot polkadot.apis.Core.version`
23
+ - ✅ Full-metadata dump — `dot metadata <chain>` emits one JSON blob with pallets, runtime APIs, and transaction extensions (or raw SCALE bytes via `--raw`)
24
+ - ✅ Stale-metadata detection — when a tx or query fails because the runtime upgraded, the CLI tells you exactly which `dot chain update` to run
23
25
  - ✅ Chain topology — relay/parachain hierarchy with tree display and auto-detection
24
26
  - ✅ Batteries included — all system parachains and testnets already setup to be used
25
27
  - ✅ File-based commands — run any command from a YAML/JSON file with variable substitution
@@ -100,6 +102,12 @@ dot chain add my-para --rpc wss://rpc.example.com --relay polkadot --parachain-i
100
102
 
101
103
  # List configured chains (shows relay/parachain hierarchy)
102
104
  dot chain list
105
+ dot chains # shorthand
106
+ dot chains -v # include RPC endpoints in the list
107
+
108
+ # Inspect a single chain (rpc, parachains, metadata cache status)
109
+ dot chain info polkadot
110
+ dot chain polkadot # bare-noun shortcut, same as `chain info polkadot`
103
111
 
104
112
  # Re-fetch metadata after a runtime upgrade
105
113
  dot chain update polkadot # updates a specific chain
@@ -113,22 +121,55 @@ dot chain remove kusama
113
121
 
114
122
  `dot chain list` displays chains as a tree, grouping parachains under their parent relay:
115
123
 
124
+ ```
125
+ Configured Chains
126
+
127
+ polkadot
128
+ ├─ polkadot-asset-hub [1000]
129
+ ├─ polkadot-bridge-hub [1002]
130
+ ├─ polkadot-collectives [1001]
131
+ ├─ polkadot-coretime [1005]
132
+ └─ polkadot-people [1004]
133
+
134
+ paseo
135
+ ├─ paseo-asset-hub [1000]
136
+ └─ paseo-people [1004]
137
+
138
+ my-solo-chain
139
+ ```
140
+
141
+ The default list is intentionally compact — names + relay tree + parachain IDs. Pass `-v` / `--verbose` to also print every RPC endpoint inline (à la `git remote -v`):
142
+
116
143
  ```
117
144
  Configured Chains
118
145
 
119
146
  polkadot wss://polkadot.ibp.network
120
- ├─ polkadot-asset-hub [1000] wss://...
121
- ├─ polkadot-bridge-hub [1002] wss://...
122
- ├─ polkadot-collectives [1001] wss://...
123
- ├─ polkadot-coretime [1005] wss://...
124
- └─ polkadot-people [1004] wss://...
147
+ wss://polkadot-rpc.n.dwellir.com
148
+ wss://rpc.polkadot.io
149
+ ├─ polkadot-asset-hub [1000] wss://polkadot-asset-hub-rpc.polkadot.io
150
+ ...
151
+ ```
125
152
 
126
- paseo wss://paseo.ibp.network
127
- ├─ paseo-asset-hub [1000] wss://...
128
- └─ paseo-people [1004] wss://...
153
+ For the full set of fields for one chain (RPCs, parent relay, child parachains, metadata cache status), use `dot chain info <name>`:
129
154
 
130
- my-solo-chain wss://...
131
155
  ```
156
+ dot chain info polkadot
157
+
158
+ # polkadot
159
+ #
160
+ # rpc:
161
+ # wss://polkadot.ibp.network
162
+ # wss://rpc.polkadot.io
163
+ # ...
164
+ # parachains:
165
+ # polkadot-asset-hub [1000]
166
+ # polkadot-bridge-hub [1002]
167
+ # ...
168
+ # metadata:
169
+ # not cached — run `dot chain update polkadot`
170
+ ```
171
+
172
+ After a successful `dot chain update <name>`, the `metadata:` row shows the cached `specName`, `specVersion`, and `fetchedAt` timestamp instead of the `not cached` hint. `dot chain info <name> --json` emits the same data as a structured object (with `metadata: null` when no fingerprint is cached). Names resolve case-insensitively. The bare-noun form `dot chain <name>` is a shortcut for `dot chain info <name>` — known action verbs (`add`, `remove`, `update`, `list`, `export`, `import`, `info`) take precedence over chain names if there's ever a clash.
132
173
 
133
174
  All built-in system parachains are preconfigured with their relay chain and parachain ID. When adding a custom parachain with `--relay`, the CLI auto-detects the parachain ID from on-chain `ParachainInfo` storage. Use `--parachain-id` to set it explicitly if auto-detection is not available.
134
175
 
@@ -136,14 +177,18 @@ Removing a relay chain that has parachains prints a warning listing the orphaned
136
177
 
137
178
  #### Selecting a chain
138
179
 
139
- Every chain-consuming command must specify a chain explicitly either with the global `--chain <name>` flag or with a dotpath chain prefix. There is no hidden default; running a command without a chain errors out with a message listing the configured chains.
180
+ Every chain-consuming command must specify a chain explicitly. Prefer the dotpath chain prefix; the `--chain <name>` flag is equivalent. There is no hidden default; running a command without a chain errors out with a message listing the configured chains.
140
181
 
141
182
  ```bash
142
- # Via --chain flag
143
- dot query.System.Number --chain polkadot
144
-
145
- # Via dotpath chain prefix
183
+ # Recommended — dotpath chain prefix
146
184
  dot polkadot.query.System.Number
185
+ # Output:
186
+ # 31014744
187
+
188
+ # Equivalent — --chain flag
189
+ dot query.System.Number --chain polkadot
190
+ # Output:
191
+ # 31014744
147
192
 
148
193
  # Both at once errors
149
194
  dot polkadot.query.System.Number --chain polkadot # ✗ errors
@@ -244,7 +289,7 @@ dot account add ci-signer --env MY_SECRET
244
289
  dot account derive treasury treasury-staking --path //staking
245
290
 
246
291
  # Use it — the env var is read at signing time
247
- MY_SECRET="word1 word2 ..." dot tx.System.remark 0xdead --from ci-signer --chain polkadot
292
+ MY_SECRET="word1 word2 ..." dot polkadot.tx.System.remark 0xdead --from ci-signer
248
293
 
249
294
  # Remove one or more accounts
250
295
  dot account remove my-validator
@@ -288,13 +333,13 @@ Named accounts (both watch-only and keyed) resolve automatically everywhere an A
288
333
 
289
334
  ```bash
290
335
  # Use a named account as transfer recipient
291
- dot tx.Balances.transferKeepAlive treasury 1000000000000 --from alice --chain polkadot
336
+ dot polkadot.tx.Balances.transfer_keep_alive treasury 1000000000000 --from alice
292
337
 
293
338
  # Query by account name
294
339
  dot polkadot.query.System.Account treasury
295
340
 
296
341
  # Dev accounts also resolve
297
- dot tx.Balances.transferKeepAlive bob 1000000000000 --from alice --chain polkadot
342
+ dot polkadot.tx.Balances.transfer_keep_alive bob 1000000000000 --from alice
298
343
  ```
299
344
 
300
345
  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 all available account names alphabetically, one per line. When the input is close to an existing name, a "Did you mean?" suggestion is included:
@@ -338,7 +383,26 @@ JSON output:
338
383
 
339
384
  ```bash
340
385
  dot account inspect alice --json
341
- # {"publicKey":"0xd435...a27d","ss58":"5Grw...utQY","prefix":42,"name":"Alice"}
386
+ # Output:
387
+ # {
388
+ # "publicKey": "0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d",
389
+ # "ss58": "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
390
+ # "prefix": 42,
391
+ # "name": "Alice"
392
+ # }
393
+ ```
394
+
395
+ Plain text output:
396
+
397
+ ```bash
398
+ dot account inspect alice
399
+ # Output:
400
+ # Account Info
401
+ #
402
+ # Name: Alice
403
+ # Public Key: 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
404
+ # SS58: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
405
+ # Prefix: 42
342
406
  ```
343
407
 
344
408
  #### Reveal the sr25519 private key
@@ -443,7 +507,7 @@ Instead of the `--chain` flag, you can prefix the dot-path with the chain name.
443
507
  ```bash
444
508
  dot polkadot.query.System.Account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
445
509
  dot polkadot.const.Balances.ExistentialDeposit
446
- dot polkadot.tx.Balances.transferKeepAlive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --from alice
510
+ dot polkadot.tx.Balances.transfer_keep_alive bob 1000000000 --from alice --dry-run
447
511
  dot inspect polkadot.System # for `inspect`, the prefix is the first arg
448
512
  dot inspect polkadot.System.Account
449
513
  ```
@@ -475,9 +539,24 @@ This works for all categories (`query`, `tx`, `const`, `events`, `errors`, `apis
475
539
  ```bash
476
540
  # Plain storage value
477
541
  dot polkadot.query.System.Number
542
+ # Output:
543
+ # 31014744
478
544
 
479
- # Map entry by key
545
+ # Map entry by key — Alice's account on Polkadot (free balance is u128 as a quoted string)
480
546
  dot polkadot.query.System.Account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
547
+ # Output:
548
+ # {
549
+ # "nonce": 0,
550
+ # "consumers": 0,
551
+ # "providers": 0,
552
+ # "sufficients": 0,
553
+ # "data": {
554
+ # "free": "0",
555
+ # "reserved": "0",
556
+ # "frozen": "0",
557
+ # "flags": "170141183460469231731687303715884105728"
558
+ # }
559
+ # }
481
560
 
482
561
  # Map without key — shows help/usage (use --dump to fetch all entries)
483
562
  dot polkadot.query.System.Account
@@ -520,15 +599,27 @@ Query results automatically convert on-chain types for readability:
520
599
 
521
600
  ```bash
522
601
  # Token metadata — symbol and name display as text, not {}
523
- dot paseo-asset-hub.query.Assets.Metadata 50000413
524
- # { "deposit": "6693666000", "name": "Paseo Token", "symbol": "PAS", ... }
602
+ dot polkadot-asset-hub.query.Assets.Metadata 1984
603
+ # Output:
604
+ # {
605
+ # "deposit": "2008200000",
606
+ # "name": "Tether USD",
607
+ # "symbol": "USDt",
608
+ # "decimals": 6,
609
+ # "is_frozen": false
610
+ # }
525
611
  ```
526
612
 
527
613
  ### Look up constants
528
614
 
529
615
  ```bash
530
616
  dot polkadot.const.Balances.ExistentialDeposit
617
+ # Output:
618
+ # "10000000000"
619
+
531
620
  dot polkadot.const.System.SS58Prefix
621
+ # Output:
622
+ # 0
532
623
 
533
624
  # --chain flag is equivalent
534
625
  dot const.Balances.ExistentialDeposit --chain polkadot
@@ -539,44 +630,144 @@ dot polkadot.const.Balances.ExistentialDeposit --json | jq
539
630
 
540
631
  ### Inspect metadata
541
632
 
542
- Works offline from cached metadata after the first fetch. The chain is required: pass it with `--chain` or as a prefix on the inspect target (e.g. `dot inspect polkadot.System`).
543
-
544
- ```bash
545
- # List all pallets (shows storage, constants, calls, events, and errors counts)
546
- dot inspect --chain polkadot
547
-
548
- # List a pallet's storage items, constants, calls, events, and errors
549
- dot inspect System --chain polkadot
633
+ Works offline from cached metadata after the first fetch. The chain is required. Prefer the chain-prefix-on-target form (`dot inspect polkadot.System`); `--chain` is equivalent. Note that `dot polkadot.inspect.X` does **not** parse — `inspect` is a top-level command, not a dotpath category.
550
634
 
551
- # Detailed type info for a specific storage item or constant
552
- dot inspect System.Account --chain polkadot
635
+ Output is **width-aware**: short type signatures stay on a single line, longer ones expand across multiple lines with field names aligned. Composite struct fields, enum variants, and call arguments are color-coded (cyan field names, yellow primitives, magenta container keywords like `Vec`/`Option`, green enum variants) when stdout is a TTY; piped output stays plain.
553
636
 
554
- # Call detail — shows argument signature and docs
555
- dot inspect Balances.transfer_allow_death --chain polkadot
637
+ ```bash
638
+ # Pallet detail list storage, constants, calls, events, and errors
639
+ dot inspect polkadot.System
640
+ # Output:
641
+ # System Pallet
642
+ #
643
+ # Storage Items:
644
+ # Account [map]
645
+ # Key: AccountId32
646
+ # Value: {
647
+ # nonce : u32,
648
+ # consumers : u32,
649
+ # providers : u32,
650
+ # sufficients: u32,
651
+ # data : { free: u128, reserved: u128, frozen: u128, flags: u128 },
652
+ # }
653
+ # The full account information for a particular account ID.
654
+ # ...
655
+
656
+ # Storage item detail — full type and docs (each part on its own line)
657
+ dot inspect polkadot.System.Account
658
+ # Output:
659
+ # System.Account (Storage)
660
+ #
661
+ # Type: map
662
+ # Key: AccountId32
663
+ # Value: {
664
+ # nonce : u32,
665
+ # consumers : u32,
666
+ # providers : u32,
667
+ # sufficients: u32,
668
+ # data : { free: u128, reserved: u128, frozen: u128, flags: u128 },
669
+ # }
670
+ #
671
+ # The full account information for a particular account ID.
556
672
 
557
673
  # Event detail — shows field signature and docs
558
- dot inspect Balances.Transfer --chain polkadot
674
+ dot inspect polkadot.Balances.Transfer
675
+ # Output:
676
+ # Balances.Transfer (Event)
677
+ #
678
+ # Fields: (from: AccountId32, to: AccountId32, amount: u128)
679
+ #
680
+ # Transfer succeeded.
559
681
 
560
682
  # Error detail — shows docs
561
- dot inspect Balances.InsufficientBalance --chain polkadot
683
+ dot inspect polkadot.Balances.InsufficientBalance
684
+ # Output:
685
+ # Balances.InsufficientBalance (Error)
686
+ #
687
+ # Balance too low to send value.
562
688
 
563
- # Chain prefix on the inspect target works too (note: `dot polkadot.inspect.X` does NOT use either form below)
564
- dot inspect polkadot.System
565
- dot inspect polkadot.System.Account
689
+ # List all pallets single positional is read as a pallet name, so use --chain here
690
+ dot inspect --chain polkadot
566
691
  ```
567
692
 
568
693
  All listings — pallets, storage items, constants, calls, events, and errors — are sorted alphabetically, making it easy to find a specific item at a glance.
569
694
 
570
695
  The pallet listing view shows type information inline so you can understand item shapes at a glance:
571
696
 
572
- - **Storage**: key/value types with `[map]` tag for map items (e.g. `Account: AccountId32 { nonce: u32, ... } [map]`)
697
+ - **Storage**: name with optional `[map]` tag, followed by indented `Key:` / `Value:` lines (composite values expand to one field per line when wide)
573
698
  - **Constants**: the constant's type (e.g. `ExistentialDeposit: u128`)
574
- - **Calls**: full argument signature (e.g. `transfer_allow_death(dest: enum(5 variants), value: Compact<u128>)`)
575
- - **Events**: field signature (e.g. `Transfer(from: AccountId32, to: AccountId32, amount: u128)`)
699
+ - **Calls**: argument signature inline if it fits, otherwise one argument per line with names aligned by colon
700
+ - **Events**: field signature inline if it fits, otherwise one field per line
576
701
  - **Errors**: name and documentation (e.g. `InsufficientBalance`)
577
702
 
703
+ Long call signatures expand automatically:
704
+
705
+ ```bash
706
+ dot inspect polkadot.Referenda
707
+ # Output (excerpt):
708
+ # cancel(index: u32)
709
+ # Cancel an ongoing referendum.
710
+ # ...
711
+ # submit(
712
+ # proposal_origin : system | Origins | ParachainsOrigin | XcmPallet,
713
+ # proposal : Legacy | Inline | Lookup,
714
+ # enactment_moment: At | After,
715
+ # )
716
+ # Propose a referendum on a privileged action.
717
+ ```
718
+
719
+ Enums up to 24 variants now render as `A | B | C | …` (previously variants were collapsed to `enum(N variants)` for >4); only enums with more than 24 variants are still summarized for readability. So a transaction extension's value type like `Option<AsPersonalAliasWithAccount | AsPersonalAliasWithProof | …>` now spells out the variants you actually need to construct.
720
+
578
721
  Documentation from the runtime metadata is shown on an indented line below each item. The detail view (`dot inspect Balances.transfer_allow_death`) shows the full argument signature and complete documentation text. Use call inspection to discover argument names, types, and docs before constructing `dot tx` commands.
579
722
 
723
+ ### Dump full metadata
724
+
725
+ `dot metadata <chain>` fetches the chain's runtime metadata and prints **everything** as one JSON blob — pallets (with calls, events, errors, storage, constants), runtime APIs, and transaction extensions, headed by a runtime fingerprint (`specVersion`, `transactionVersion`, `codeHash`, etc.). Useful for feeding LLM agents or pipelines that want a single source of truth instead of walking `dot inspect` piecemeal.
726
+
727
+ ```bash
728
+ # Decoded JSON — fetches fresh from the chain (top-level command; no chain prefix)
729
+ dot metadata polkadot
730
+
731
+ # SCALE-encoded metadata bytes as a single 0x… hex line (for tools that re-parse)
732
+ dot metadata polkadot --raw
733
+
734
+ # Skip the network round-trip and use cached metadata
735
+ dot metadata polkadot --cached
736
+
737
+ # Override the RPC endpoint
738
+ dot metadata polkadot --rpc wss://rpc.example.com
739
+
740
+ # Slice with jq — list call names in Balances
741
+ dot metadata polkadot | jq -r '.pallets[] | select(.name=="Balances") | .calls[].name'
742
+ # Output:
743
+ # burn
744
+ # force_adjust_total_issuance
745
+ # force_set_balance
746
+ # force_transfer
747
+ # force_unreserve
748
+ # transfer_all
749
+ # transfer_allow_death
750
+ # transfer_keep_alive
751
+ # upgrade_accounts
752
+
753
+ # All transaction extension identifiers
754
+ dot metadata polkadot | jq -r '.transactionExtensions[].identifier'
755
+ # Output:
756
+ # AuthorizeCall
757
+ # CheckNonZeroSender
758
+ # CheckSpecVersion
759
+ # CheckTxVersion
760
+ # CheckGenesis
761
+ # CheckMortality
762
+ # CheckNonce
763
+ # CheckWeight
764
+ # ChargeTransactionPayment
765
+ # PrevalidateAttests
766
+ # CheckMetadataHash
767
+ ```
768
+
769
+ The decoded JSON is structured-only (no colorization), so it's safe to redirect to a file or pipe into other tools. The default fetches fresh from the RPC and atomically updates the local metadata cache and runtime-fingerprint sidecar — so subsequent commands benefit from the freshest possible metadata.
770
+
580
771
  ### Runtime APIs
581
772
 
582
773
  Browse and call Substrate runtime APIs. These are top-level APIs exposed by the runtime (e.g. `Core`, `AccountNonceApi`, `TransactionPaymentApi`), accessed as `dot <chain>.apis.ApiName.method`.
@@ -584,18 +775,43 @@ Browse and call Substrate runtime APIs. These are top-level APIs exposed by the
584
775
  ```bash
585
776
  # List all runtime APIs with method counts
586
777
  dot polkadot.apis
778
+ # Output:
779
+ # Runtime APIs on polkadot (24)
780
+ #
781
+ # AccountNonceApi 1 methods
782
+ # AssetHubMigrationApi 2 methods
783
+ # AuthorityDiscoveryApi 1 methods
784
+ # BabeApi 6 methods
785
+ # ...
587
786
 
588
787
  # List methods in a specific API (with signatures)
589
788
  dot polkadot.apis.Core
789
+ # Output:
790
+ # Core Methods
791
+ #
792
+ # execute_block(block: { header: { ... }, extrinsics: Vec<Vec<u8>> }) → unknown
793
+ # Execute the given block.
794
+ # initialize_block(header: { ... }) → AllExtrinsics | OnlyInherents
795
+ # Initialize a block with the given header and return the runtime executive mode.
796
+ # version() → { spec_name: str, impl_name: str, ... }
797
+ # Returns the version of the runtime.
590
798
 
591
799
  # Call a runtime API method
592
- dot polkadot.apis.Core.version
800
+ dot polkadot.apis.Core.version --json
801
+ # Output:
802
+ # {
803
+ # "spec_name": "polkadot",
804
+ # "impl_name": "parity-polkadot",
805
+ # "spec_version": 2002001,
806
+ # "transaction_version": 26,
807
+ # ...
808
+ # }
593
809
 
594
810
  # --chain flag is equivalent
595
811
  dot apis.Core.version --chain polkadot
596
812
 
597
813
  # Show method signature and docs (chain still required to load metadata)
598
- dot apis.Core.version --chain polkadot --help
814
+ dot polkadot.apis.Core.version --help
599
815
  ```
600
816
 
601
817
  `api` is an alias for `apis`.
@@ -623,16 +839,16 @@ Runtime API arguments accept the same shorthand as `dot tx` arguments:
623
839
  | `Vec<T>` (non-byte) | JSON array or comma-separated | `[1,2,3]`, `1,2,3` |
624
840
  | Structs / nested enums | JSON | `{"type":"X1","value":{…}}` |
625
841
 
626
- For sized byte arrays (`[u8; N]`) — common for Ethereum-style addresses (`H160`, `[u8; 20]`), 32-byte hashes (`H256`), and raw `AccountId32` bytes — pass a `0x`-prefixed hex string. Example: a contract call against the `pallet-revive` runtime API:
842
+ For sized byte arrays (`[u8; N]`) — common for Ethereum-style addresses (`H160`, `[u8; 20]`), 32-byte hashes (`H256`), and raw `AccountId32` bytes — pass a `0x`-prefixed hex string. Example: a contract call against the `pallet-revive` runtime API. Use `dot <chain>.apis.<ApiName>.<method> --help` to see the exact argument signature for any method.
627
843
 
628
844
  ```bash
629
- ALICE=5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
845
+ ORIGIN=alice
630
846
  CONTRACT=0x970951a12f975e6762482aca81e57d5a2a4e73f4 # H160, [u8; 20]
631
847
  CALLDATA=$(cast calldata "set(uint256)" 42)
632
848
 
849
+ # Args: origin, dest, value, gas_limit (Option), storage_deposit (Option), input_data
633
850
  dot paseo-asset-hub.apis.ReviveApi.call \
634
- "$ALICE" "$CONTRACT" 0 null null "$CALLDATA"
635
- # ^ origin ^ dest ^ value ^ gas_limit (Option, none) ^ deposit (Option, none) ^ input_data (Vec<u8>)
851
+ "$ORIGIN" "$CONTRACT" 0 null null "$CALLDATA"
636
852
  ```
637
853
 
638
854
  ##### Passing `Option<T>`
@@ -640,9 +856,10 @@ dot paseo-asset-hub.apis.ReviveApi.call \
640
856
  Absent options (`None`) can be written three ways, all equivalent:
641
857
 
642
858
  ```bash
643
- dot paseo-asset-hub.apis.ReviveApi.call "$ALICE" "$CONTRACT" 0 null null "$CALLDATA"
644
- dot paseo-asset-hub.apis.ReviveApi.call "$ALICE" "$CONTRACT" 0 none none "$CALLDATA"
645
- dot paseo-asset-hub.apis.ReviveApi.call "$ALICE" "$CONTRACT" 0 undefined undefined "$CALLDATA"
859
+ # null (recommended), none, and undefined all mean None
860
+ dot paseo-asset-hub.apis.ReviveApi.call "$ORIGIN" "$CONTRACT" 0 null null "$CALLDATA"
861
+ dot paseo-asset-hub.apis.ReviveApi.call "$ORIGIN" "$CONTRACT" 0 none none "$CALLDATA"
862
+ dot paseo-asset-hub.apis.ReviveApi.call "$ORIGIN" "$CONTRACT" 0 undefined undefined "$CALLDATA"
646
863
  ```
647
864
 
648
865
  `null` is the **recommended** form — it matches JSON / YAML semantics, so args read identically on the CLI and inside [file-based command](#file-based-commands) YAML/JSON inputs.
@@ -651,7 +868,7 @@ A present option (`Some(value)`) is just the value itself — no wrapping:
651
868
 
652
869
  ```bash
653
870
  # gas_limit = Some({ ref_time: 1_000_000, proof_size: 100_000 })
654
- dot paseo-asset-hub.apis.ReviveApi.call "$ALICE" "$CONTRACT" 0 \
871
+ dot paseo-asset-hub.apis.ReviveApi.call "$ORIGIN" "$CONTRACT" 0 \
655
872
  '{"ref_time":1000000,"proof_size":100000}' \
656
873
  null \
657
874
  "$CALLDATA"
@@ -661,8 +878,6 @@ Notes:
661
878
  - The `null` / `none` / `undefined` literals are case-sensitive (lowercase only).
662
879
  - There is no `Some(value)` prefix — bare values are already treated as `Some`.
663
880
 
664
- Use `dot <chain>.apis.<ApiName>.<method> --help` to see the exact argument signature for any method.
665
-
666
881
  ### Focused metadata listings
667
882
 
668
883
  Each category supports partial dot-paths for browsing metadata. Category-only invocations list pallets (or APIs); pallet-level invocations list items; item-level invocations show detail. Singular and plural aliases work: `event` = `events`, `error` = `errors`, `api` = `apis`, `consts` = `constants` = `const`.
@@ -711,15 +926,29 @@ List the transaction extensions (also known as signed extensions) a chain declar
711
926
  ```bash
712
927
  # List all transaction extensions on a chain
713
928
  dot polkadot.extensions
929
+ # Output:
930
+ # Transaction extensions on polkadot (11)
931
+ #
932
+ # AuthorizeCall unknown [custom]
933
+ # ChargeTransactionPayment Compact<u128> [builtin]
934
+ # CheckGenesis unknown [builtin]
935
+ # CheckMetadataHash Disabled | Enabled [builtin]
936
+ # CheckMortality enum(256 variants) [builtin]
937
+ # CheckNonce Compact<u64> [builtin]
938
+ # CheckNonZeroSender unknown [builtin]
939
+ # CheckSpecVersion unknown [builtin]
940
+ # CheckTxVersion unknown [builtin]
941
+ # CheckWeight unknown [builtin]
942
+ # PrevalidateAttests unknown [builtin]
714
943
 
715
944
  # Detail view for a single extension
716
945
  dot polkadot.extensions.CheckMortality
717
-
718
- # --chain flag form is equivalent
719
- dot extensions.ChargeTransactionPayment --chain polkadot
720
-
721
- # Space-separated syntax also works
722
- dot extensions CheckMortality --chain polkadot
946
+ # Output:
947
+ # CheckMortality (Transaction Extension)
948
+ #
949
+ # Value type: enum(256 variants)
950
+ # AdditionalSigned: [u8; 32]
951
+ # Handled by: polkadot-api (builtin)
723
952
 
724
953
  # Structured output for scripts
725
954
  dot polkadot.extensions --json
@@ -739,29 +968,58 @@ The detail view shows the extension's value type, its `additionalSigned` type, a
739
968
  Build, sign, and submit transactions. Pass a `Pallet.Call` with arguments, or a raw SCALE-encoded call hex (e.g. from a multisig proposal or governance). Both forms display a decoded human-readable representation of the call.
740
969
 
741
970
  ```bash
742
- # Simple remark
743
- dot tx.System.remark 0xdeadbeef --from alice --chain polkadot
744
-
745
- # Transfer (amount in plancks)
746
- dot tx.Balances.transferKeepAlive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --from alice --chain polkadot
747
-
748
- # Estimate fees without submitting
749
- dot tx.Balances.transferKeepAlive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --from alice --chain polkadot --dry-run
971
+ # Estimate fees without submitting (no broadcast). The Decode block shows
972
+ # the call name on the header line and indented JSON below it.
973
+ dot polkadot.tx.System.remark 0xdeadbeef --from alice --dry-run
974
+ # Output:
975
+ # Chain: polkadot
976
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
977
+ # Call: 0x000010deadbeef
978
+ # Decode: System.remark
979
+ # {
980
+ # "remark": "0xdeadbeef"
981
+ # }
982
+ # Estimated fees: 125598975
983
+
984
+ # Transfer (amount in plancks). Method names are snake_case.
985
+ dot polkadot.tx.Balances.transfer_keep_alive bob 1000000000000 --from alice --dry-run
986
+
987
+ # Submit (omit --dry-run)
988
+ dot polkadot.tx.System.remark 0xdeadbeef --from alice
750
989
 
751
990
  # Submit a raw SCALE-encoded call (e.g. from a multisig proposal or another tool)
752
- dot tx 0x0503008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48 --from alice --chain polkadot
753
-
754
- # Batch multiple transfers with Utility.batchAll (comma-separated encoded calls)
755
- A=$(dot tx.Balances.transfer_keep_alive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --encode --chain polkadot)
756
- B=$(dot tx.Balances.transfer_keep_alive 5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y 2000000000000 --encode --chain polkadot)
757
- dot tx.Utility.batchAll $A,$B --from alice --chain polkadot
758
- ```
759
-
760
- The dot-prefix form works for `tx` too — these are equivalent:
991
+ dot polkadot.tx 0x000010deadbeef --from alice --dry-run
992
+
993
+ # Batch multiple remarks with Utility.batch_all (comma-separated encoded calls).
994
+ # Complex decoded calls remain readable because each level is indented.
995
+ A=$(dot polkadot.tx.System.remark 0xdeadbeef --encode)
996
+ B=$(dot polkadot.tx.System.remark 0xcafe --encode)
997
+ dot polkadot.tx.Utility.batch_all "$A,$B" --from alice --dry-run
998
+ # Output (excerpt — nested calls each get their own enum {type, value} envelope):
999
+ # Chain: polkadot
1000
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
1001
+ # Call: 0x1a0208000010deadbeef000008cafe
1002
+ # Decode: Utility.batch_all
1003
+ # {
1004
+ # "calls": [
1005
+ # {
1006
+ # "type": "System",
1007
+ # "value": {
1008
+ # "type": "remark",
1009
+ # "value": { "remark": "0xdeadbeef" }
1010
+ # }
1011
+ # },
1012
+ # ...
1013
+ # ]
1014
+ # }
1015
+ # Estimated fees: 133994995
1016
+ ```
1017
+
1018
+ The `--chain` flag is equivalent to the chain prefix:
761
1019
 
762
1020
  ```bash
763
- dot tx.System.remark 0xdeadbeef --from alice --chain polkadot
764
1021
  dot polkadot.tx.System.remark 0xdeadbeef --from alice
1022
+ dot tx.System.remark 0xdeadbeef --from alice --chain polkadot
765
1023
  ```
766
1024
 
767
1025
  #### Enum shorthand
@@ -770,17 +1028,27 @@ Enum arguments accept a concise `Variant(value)` syntax instead of verbose JSON:
770
1028
 
771
1029
  ```bash
772
1030
  # Instead of: '{"type":"system","value":{"type":"Authorized"}}'
773
- dot tx.Utility.dispatch_as 'system(Authorized)' $(dot tx.System.remark 0xcafe --encode --chain polkadot) --from alice --chain polkadot
774
-
775
- # Nested enums work too
776
- dot tx.Utility.dispatch_as 'system(Signed(5FHneW46...))' <call> --from alice --chain polkadot
1031
+ dot polkadot.tx.Utility.dispatch_as 'system(Authorized)' $(dot polkadot.tx.System.remark 0xcafe --encode) --from alice --dry-run
1032
+ # Output:
1033
+ # Chain: polkadot
1034
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
1035
+ # Call: 0x1a030003000008cafe
1036
+ # Decode: Utility.dispatch_as
1037
+ # {
1038
+ # "as_origin": { "type": "system", "value": { "type": "Authorized" } },
1039
+ # "call": { "type": "System", "value": { "type": "remark", "value": { "remark": "0xcafe" } } }
1040
+ # }
1041
+ # Estimated fees: 127644270
1042
+
1043
+ # Nested enums work too — Signed origin with an account
1044
+ dot polkadot.tx.Utility.dispatch_as 'system(Signed(bob))' "$INNER_CALL" --from alice --dry-run
777
1045
 
778
1046
  # Void variants — empty parens or just the name
779
- dot tx.Pallet.call 'Root()' ... --from alice --chain polkadot
780
- dot tx.Pallet.call 'Root' ... --from alice --chain polkadot
1047
+ dot polkadot.tx.Pallet.call 'Root()' ... --from alice
1048
+ dot polkadot.tx.Pallet.call 'Root' ... --from alice
781
1049
 
782
1050
  # JSON inside parens for struct values
783
- dot tx.Pallet.call 'AccountId32({"id":"0xd435..."})' ... --from alice --chain polkadot
1051
+ dot polkadot.tx.Pallet.call 'AccountId32({"id":"0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d"})' ... --from alice
784
1052
  ```
785
1053
 
786
1054
  Variant matching is case-insensitive (`system` resolves to `system`, `authorized` to `Authorized`). All existing formats (JSON objects, hex, SS58 addresses) continue to work unchanged.
@@ -791,13 +1059,26 @@ Encode a call to hex without signing or submitting. Useful for preparing calls t
791
1059
 
792
1060
  ```bash
793
1061
  # Encode a remark call
794
- dot tx.System.remark 0xdeadbeef --encode --chain polkadot
1062
+ dot polkadot.tx.System.remark 0xdeadbeef --encode
1063
+ # Output:
1064
+ # 0x000010deadbeef
795
1065
 
796
1066
  # Encode a transfer (use the hex output in a batch or sudo call)
797
- dot tx.Balances.transfer_keep_alive 5FHneW46... 1000000000000 --encode --chain polkadot
798
-
799
- # Use encoded output with Sudo.sudo
800
- dot tx.Sudo.sudo $(dot tx.System.remark 0xcafe --encode --chain polkadot) --from alice --chain polkadot
1067
+ dot polkadot.tx.Balances.transfer_keep_alive bob 1000000000 --encode
1068
+ # Output:
1069
+ # 0x050300...02286bee
1070
+
1071
+ # Use encoded output with Sudo.sudo (Sudo only exists on testnets like Paseo)
1072
+ dot paseo-asset-hub.tx.Sudo.sudo $(dot paseo-asset-hub.tx.System.remark 0xcafe --encode) --from alice --dry-run
1073
+ # Output:
1074
+ # Chain: paseo-asset-hub
1075
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
1076
+ # Call: 0xfb00000008cafe
1077
+ # Decode: Sudo.sudo
1078
+ # {
1079
+ # "call": { "type": "System", "value": { "type": "remark", "value": { "remark": "0xcafe" } } }
1080
+ # }
1081
+ # Estimated fees: ...
801
1082
  ```
802
1083
 
803
1084
  #### Decode call data to YAML / JSON
@@ -806,54 +1087,86 @@ Decode a hex-encoded call into a YAML or JSON file that is compatible with [file
806
1087
 
807
1088
  ```bash
808
1089
  # Decode a raw hex call to YAML
809
- dot tx.0x0001076465616462656566 --to-yaml --chain polkadot
1090
+ dot polkadot.tx.0x000010deadbeef --to-yaml
1091
+ # Output:
1092
+ # chain: polkadot
1093
+ # tx:
1094
+ # System:
1095
+ # remark:
1096
+ # remark: "0xdeadbeef"
810
1097
 
811
1098
  # Decode a raw hex call to JSON
812
- dot tx.0x0001076465616462656566 --to-json --chain polkadot
1099
+ dot polkadot.tx.0x000010deadbeef --to-json
1100
+ # Output:
1101
+ # {
1102
+ # "chain": "polkadot",
1103
+ # "tx": {
1104
+ # "System": {
1105
+ # "remark": {
1106
+ # "remark": "0xdeadbeef"
1107
+ # }
1108
+ # }
1109
+ # }
1110
+ # }
813
1111
 
814
1112
  # Encode a named call and output as YAML
815
- dot tx.System.remark 0xdeadbeef --to-yaml --chain polkadot
1113
+ dot polkadot.tx.System.remark 0xdeadbeef --to-yaml
816
1114
 
817
1115
  # Round-trip: encode to hex, decode to YAML, re-encode from file
818
- dot tx.System.remark 0xdeadbeef --encode --chain polkadot # 0x0001076465616462656566
819
- dot tx.0x0001076465616462656566 --to-yaml --chain polkadot > remark.yaml
820
- dot ./remark.yaml --encode # chain comes from the file
1116
+ dot polkadot.tx.System.remark 0xdeadbeef --encode # 0x000010deadbeef
1117
+ dot polkadot.tx.0x000010deadbeef --to-yaml > remark.yaml
1118
+ dot ./remark.yaml --encode # chain comes from the file
821
1119
  ```
822
1120
 
823
1121
  `--to-yaml` / `--to-json` are mutually exclusive with each other and with `--encode` and `--dry-run`.
824
1122
 
825
- Both dry-run and submission display the encoded call hex and a decoded human-readable form:
1123
+ Both dry-run and submission display the encoded call hex and a decoded human-readable form. The decoded call is rendered as JSON with two-space indentation under the `Decode:` header so even deeply nested calls (XCM, sudo, batch, dispatch_as) remain easy to scan:
826
1124
 
827
1125
  ```
828
- Call: 0x0001076465616462656566
829
- Decode: System.remark(remark: 0xdeadbeef)
1126
+ Call: 0x000010deadbeef
1127
+ Decode: System.remark
1128
+ {
1129
+ "remark": "0xdeadbeef"
1130
+ }
830
1131
  Tx: 0xabc123...
831
1132
  Status: ok
832
1133
  ```
833
1134
 
834
- Complex calls (e.g. XCM teleports) that the primary decoder cannot handle are automatically decoded via a fallback path:
835
-
836
- ```
837
- Decode: PolkadotXcm.limited_teleport_assets { dest: V3 { parents: 1, interior: X1(Parachain(5140)) }, beneficiary: V3 { ... }, assets: V3 [...], fee_asset_item: 0, weight_limit: Unlimited }
838
- ```
1135
+ Complex calls (XCM teleports, batched governance proposals) keep the same shape every nested enum becomes a `{ "type": ..., "value": ... }` block, indented one level deeper, so you can read the structure top-down without it ever wrapping past the terminal width.
839
1136
 
840
1137
  #### Exit codes
841
1138
 
842
1139
  The CLI exits with code **1** when a finalized transaction has a dispatch error (e.g. insufficient balance, bad origin). The full transaction output (events, explorer links) is still printed before the error so you can debug the failure. Module errors are formatted as `PalletName.ErrorVariant` (e.g. `Balances.InsufficientBalance`).
843
1140
 
844
1141
  ```bash
845
- dot tx.Balances.transferKeepAlive 5FHneW46... 999999999999999999 --from alice --chain polkadot
1142
+ dot polkadot.tx.Balances.transfer_keep_alive bob 999999999999999999 --from alice
846
1143
  # ... events and explorer links ...
847
1144
  # Error: Transaction dispatch error: Balances.InsufficientBalance
848
1145
  echo $? # 1
849
1146
  ```
850
1147
 
1148
+ #### Stale metadata detection
1149
+
1150
+ When a `tx`, `--dry-run`, or `query` fails with an error that smells like stale metadata — a runtime wasm trap, a SCALE codec/decode error, or a fee-estimation panic — the CLI compares your locally cached metadata's runtime fingerprint against the live chain. If it has changed, the CLI appends a one-line suggestion telling you exactly which command to run:
1151
+
1152
+ ```
1153
+ Error: The runtime rejected this transaction in the runtime's validate_transaction step.
1154
+ Cause: a runtime invariant failed — typically the call's arguments are out of range, …
1155
+
1156
+ ⚠ Local metadata for "paseo-people-next" is out of date (spec 1018 → 1020).
1157
+ Run: dot chain update paseo-people-next
1158
+ ```
1159
+
1160
+ The fingerprint includes the runtime code hash, so the check also catches local-node restarts where the wasm changed but `specVersion` was kept the same. No automatic refetch happens — the original error still propagates with a non-zero exit code, you just get an actionable suggestion.
1161
+
1162
+ The check only fires on suspected-stale errors, so the happy path pays no extra RPC. Set `DOT_TRUST_CACHED_METADATA=1` to disable the check entirely (e.g. for CI loops where you've just refreshed manually).
1163
+
851
1164
  #### Argument parsing errors
852
1165
 
853
1166
  When a call argument is invalid, the CLI shows a contextual error message with the argument name, the expected type, and a hint:
854
1167
 
855
1168
  ```bash
856
- dot tx.Balances.transferKeepAlive 5GrwvaEF... abc --encode --chain polkadot
1169
+ dot polkadot.tx.Balances.transfer_keep_alive bob abc --encode
857
1170
  # Error: Invalid value for argument 'value' (expected Compact<u128>): "abc"
858
1171
  # Hint: Compact<u128>
859
1172
  ```
@@ -866,15 +1179,15 @@ By default, `dot tx` waits for finalization (~30s on Polkadot). Use `--wait` / `
866
1179
 
867
1180
  ```bash
868
1181
  # Return as soon as the tx is broadcast (fastest)
869
- dot tx.System.remark 0xdead --from alice --chain polkadot --wait broadcast
1182
+ dot polkadot.tx.System.remark 0xdead --from alice --wait broadcast
870
1183
 
871
1184
  # Return when included in a best block
872
- dot tx.System.remark 0xdead --from alice --chain polkadot -w best-block
873
- dot tx.System.remark 0xdead --from alice --chain polkadot -w best # alias
1185
+ dot polkadot.tx.System.remark 0xdead --from alice -w best-block
1186
+ dot polkadot.tx.System.remark 0xdead --from alice -w best # alias
874
1187
 
875
1188
  # Wait for finalization (default, unchanged)
876
- dot tx.System.remark 0xdead --from alice --chain polkadot --wait finalized
877
- dot tx.System.remark 0xdead --from alice --chain polkadot # same
1189
+ dot polkadot.tx.System.remark 0xdead --from alice --wait finalized
1190
+ dot polkadot.tx.System.remark 0xdead --from alice # same
878
1191
  ```
879
1192
 
880
1193
  | Level | Resolves when | Events shown | Explorer links |
@@ -896,7 +1209,7 @@ Chains with non-standard signed extensions are auto-handled:
896
1209
  For manual override, use `--ext` with a JSON object:
897
1210
 
898
1211
  ```bash
899
- dot tx.System.remark 0xdeadbeef --from alice --chain polkadot --ext '{"MyExtension":{"value":"..."}}'
1212
+ dot polkadot.tx.System.remark 0xdeadbeef --from alice --ext '{"MyExtension":{"value":"..."}}'
900
1213
  ```
901
1214
 
902
1215
  Not sure which extensions a chain exposes? Run `dot <chain>.extensions` (see [Transaction extensions](#transaction-extensions)) to list them all with value types and a `[builtin]` / `[custom]` marker.
@@ -914,23 +1227,23 @@ Override low-level transaction parameters. Useful for rapid-fire submission (cus
914
1227
 
915
1228
  ```bash
916
1229
  # Fire-and-forget: submit two txs in rapid succession with manual nonces
917
- dot tx.System.remark 0xdead --from alice --chain polkadot --nonce 0 --wait broadcast
918
- dot tx.System.remark 0xbeef --from alice --chain polkadot --nonce 1 --wait broadcast
1230
+ dot polkadot.tx.System.remark 0xdead --from alice --nonce 0 --wait broadcast
1231
+ dot polkadot.tx.System.remark 0xbeef --from alice --nonce 1 --wait broadcast
919
1232
 
920
1233
  # Add a priority tip (in planck)
921
- dot tx.Balances.transferKeepAlive 5FHneW46... 1000000000000 --from alice --chain polkadot --tip 1000000
1234
+ dot polkadot.tx.Balances.transfer_keep_alive bob 1000000000 --from alice --tip 1000000
922
1235
 
923
1236
  # Submit an immortal transaction (no expiry)
924
- dot tx.System.remark 0xdead --from alice --chain polkadot --mortality immortal
1237
+ dot polkadot.tx.System.remark 0xdead --from alice --mortality immortal
925
1238
 
926
1239
  # Set a custom mortality period (rounds up to nearest power of two)
927
- dot tx.System.remark 0xdead --from alice --chain polkadot --mortality 128
1240
+ dot polkadot.tx.System.remark 0xdead --from alice --mortality 128
928
1241
 
929
1242
  # Validate against a specific block hash
930
- dot tx.System.remark 0xdead --from alice --chain polkadot --at 0x1234...abcd
1243
+ dot polkadot.tx.System.remark 0xdead --from alice --at 0x1234...abcd
931
1244
 
932
1245
  # Combine: rapid-fire with tip and broadcast-only
933
- dot tx.System.remark 0xdead --from alice --chain polkadot --nonce 5 --tip 500000 --wait broadcast
1246
+ dot polkadot.tx.System.remark 0xdead --from alice --nonce 5 --tip 500000 --wait broadcast
934
1247
  ```
935
1248
 
936
1249
  When set, nonce / tip / mortality / at are shown in both `--dry-run` and submission output. These flags are silently ignored with `--encode`, `--to-yaml`, and `--to-json` (which return before signing).
@@ -940,15 +1253,23 @@ When set, nonce / tip / mortality / at are shown in both `--dry-run` and submiss
940
1253
  On asset-hub-style chains (Polkadot Asset Hub, Paseo Asset Hub, etc.) the `ChargeAssetTxPayment` signed extension lets a transaction pay its fees in a non-native asset. Use `--asset <json>` to select the asset — the value is an XCM location (JSON) identifying the asset, which the runtime's asset-conversion pool swaps for native tokens at dispatch time.
941
1254
 
942
1255
  ```bash
943
- # Pay fees in USDT (asset id 1337, PalletInstance 50) on Polkadot Asset Hub
944
- dot tx.Balances.transfer_keep_alive 5FHneW46... 1000000000000 \
945
- --from alice --chain polkadot-asset-hub \
946
- --asset '{"parents":0,"interior":{"type":"X2","value":[{"type":"PalletInstance","value":50},{"type":"GeneralIndex","value":"1337"}]}}'
1256
+ # Define the USDT location once (asset id 1337, PalletInstance 50)
1257
+ USDT='{"parents":0,"interior":{"type":"X2","value":[{"type":"PalletInstance","value":50},{"type":"GeneralIndex","value":"1337"}]}}'
947
1258
 
948
1259
  # Dry-run to see the native-denominated fee estimate
949
- dot tx.Balances.transfer_keep_alive 5FHneW46... 1000000000000 \
950
- --from alice --chain polkadot-asset-hub --dry-run \
951
- --asset '{"parents":0,"interior":{"type":"X2","value":[{"type":"PalletInstance","value":50},{"type":"GeneralIndex","value":"1337"}]}}'
1260
+ dot polkadot-asset-hub.tx.Balances.transfer_keep_alive bob 1000000000 \
1261
+ --from alice --dry-run --asset "$USDT"
1262
+ # Output:
1263
+ # Chain: polkadot-asset-hub
1264
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
1265
+ # Call: 0x0a0300d435...02286bee
1266
+ # Decode: Balances.transfer_keep_alive { dest: Id(...), value: 1000000000 }
1267
+ # Asset: {"parents":0,"interior":{"type":"X2","value":[{"type":"PalletInstance","value":50},{"type":"GeneralIndex","value":"1337"}]}}
1268
+ # Estimated fees: 9249754
1269
+
1270
+ # Submit (omit --dry-run)
1271
+ dot polkadot-asset-hub.tx.Balances.transfer_keep_alive bob 1000000000 \
1272
+ --from alice --asset "$USDT"
952
1273
  ```
953
1274
 
954
1275
  The `--asset` echo is included in dry-run and submission output (and `--json`). A few things to know:
@@ -966,19 +1287,19 @@ Submit transactions without a signer using `--unsigned`. This is for calls autho
966
1287
 
967
1288
  ```bash
968
1289
  # Submit an authorized call on the People chain
969
- dot tx.People.create_people_collection --unsigned --chain polkadot-people
1290
+ dot polkadot-people.tx.People.create_people_collection --unsigned
970
1291
 
971
1292
  # Dry-run to inspect before submitting
972
- dot tx.People.create_people_collection --unsigned --chain polkadot-people --dry-run
1293
+ dot polkadot-people.tx.People.create_people_collection --unsigned --dry-run
973
1294
 
974
1295
  # Encode the full general transaction bytes
975
- dot tx.People.create_people_collection --unsigned --chain polkadot-people --encode
1296
+ dot polkadot-people.tx.People.create_people_collection --unsigned --encode
976
1297
 
977
1298
  # With raw hex call data
978
- dot tx 0x3306 --unsigned --chain polkadot-people
1299
+ dot polkadot-people.tx 0x3306 --unsigned
979
1300
 
980
1301
  # JSON output for scripting
981
- dot tx.People.create_people_collection --unsigned --chain polkadot-people --json
1302
+ dot polkadot-people.tx.People.create_people_collection --unsigned --json
982
1303
  ```
983
1304
 
984
1305
  The CLI constructs a v5 general transaction with all extension values auto-defaulted (`VerifySignature::Disabled`, `Era::Immortal`, nonce `0`, tip `0`, etc.). Override individual extensions with `--ext` if needed.
@@ -1120,8 +1441,14 @@ The same teleport in JSON:
1120
1441
  ```
1121
1442
 
1122
1443
  ```bash
1123
- # Run from file
1444
+ # Run from file (the `chain:` field comes from the YAML)
1124
1445
  dot ./teleport-dot.xcm.yaml --from alice --dry-run
1446
+ # Output:
1447
+ # Chain: polkadot-asset-hub
1448
+ # From: alice (5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY)
1449
+ # Call: 0x1f0904...
1450
+ # Decode: PolkadotXcm.limited_teleport_assets { dest: V4 { parents: 1, interior: Here }, ... }
1451
+ # Estimated fees: ...
1125
1452
 
1126
1453
  # Encode only
1127
1454
  dot ./reserve-transfer-usdc.xcm.yaml --encode
@@ -1174,7 +1501,7 @@ Hex values passed via `--var` are preserved as-is, including leading zeros. This
1174
1501
 
1175
1502
  ```bash
1176
1503
  # Encode a remark, then embed it in an XCM Transact via --var
1177
- CALL=$(dot tx.System.remark 0xdead --encode --chain polkadot)
1504
+ CALL=$(dot polkadot.tx.System.remark 0xdead --encode)
1178
1505
  dot ./xcm-transact.yaml --var CALL=$CALL --encode
1179
1506
  ```
1180
1507
 
@@ -1187,18 +1514,30 @@ Compute cryptographic hashes commonly used in Substrate. Supports BLAKE2b-256, B
1187
1514
  ```bash
1188
1515
  # Hash hex-encoded data
1189
1516
  dot hash blake2b256 0xdeadbeef
1517
+ # Output:
1518
+ # 0xf3e925002fed7cc0ded46842569eb5c90c910c091d8d04a1bdf96e0db719fd91
1190
1519
 
1191
1520
  # Hash plain text (UTF-8 encoded)
1192
1521
  dot hash sha256 hello
1522
+ # Output:
1523
+ # 0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
1193
1524
 
1194
1525
  # Hash file contents
1195
1526
  dot hash keccak256 --file ./data.bin
1196
1527
 
1197
1528
  # Read from stdin
1198
1529
  echo -n "hello" | dot hash sha256 --stdin
1530
+ # Output:
1531
+ # 0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
1199
1532
 
1200
1533
  # JSON output
1201
1534
  dot hash blake2b256 0xdeadbeef --json
1535
+ # Output:
1536
+ # {
1537
+ # "algorithm": "blake2b256",
1538
+ # "input": "0xdeadbeef",
1539
+ # "hash": "0xf3e925002fed7cc0ded46842569eb5c90c910c091d8d04a1bdf96e0db719fd91"
1540
+ # }
1202
1541
  ```
1203
1542
 
1204
1543
  Run `dot hash` with no arguments to see all available algorithms.
@@ -1210,6 +1549,11 @@ Sign arbitrary messages with an account keypair. Output is a `Sr25519(0x...)` va
1210
1549
  ```bash
1211
1550
  # Sign a text message
1212
1551
  dot sign "hello world" --from alice
1552
+ # Output:
1553
+ # Type: Sr25519
1554
+ # Message: 0x68656c6c6f20776f726c64
1555
+ # Signature: 0x4283a3bbae463c39264ca193b1bcce61702794e54e482bc2e46202c85ef6a5446750e81db57cd28af4ffd5c69aadcf5b2b3068972e0cdcb68e51db0ff600d786
1556
+ # Enum: Sr25519(0x4283a3bbae463c39264ca193b1bcce61702794e54e482bc2e46202c85ef6a5446750e81db57cd28af4ffd5c69aadcf5b2b3068972e0cdcb68e51db0ff600d786)
1213
1557
 
1214
1558
  # Sign hex-encoded bytes
1215
1559
  dot sign 0xdeadbeef --from alice
@@ -1222,6 +1566,13 @@ echo -n "hello" | dot sign --stdin --from alice
1222
1566
 
1223
1567
  # JSON output (for scripting)
1224
1568
  dot sign "hello" --from alice --json
1569
+ # Output:
1570
+ # {
1571
+ # "type": "Sr25519",
1572
+ # "message": "0x68656c6c6f",
1573
+ # "signature": "0x5a058160b62eeb6c1194116d4613489e9c310075478c544761b9c8198d3fdb38...",
1574
+ # "enum": "Sr25519(0x5a058160b62eeb6c1194116d4613489e9c310075478c544761b9c8198d3fdb38...)"
1575
+ # }
1225
1576
  ```
1226
1577
 
1227
1578
  Output shows the crypto type, message bytes in hex, raw signature, and an `Enum` value directly pasteable into tx arguments (e.g. `Sr25519(0x...)`).
@@ -1238,6 +1589,18 @@ Derive the sovereign account addresses for a parachain. These are deterministic
1238
1589
  ```bash
1239
1590
  # Show both child and sibling accounts
1240
1591
  dot parachain 1000
1592
+ # Output:
1593
+ # Parachain 1000 — Sovereign Accounts
1594
+ #
1595
+ # Child:
1596
+ # Public Key: 0x70617261e8030000000000000000000000000000000000000000000000000000
1597
+ # SS58: 5Ec4AhPZk8STuex8Wsi9TwDtJQxKqzPJRCH7348Xtcs9vZLJ
1598
+ # Prefix: 42
1599
+ #
1600
+ # Sibling:
1601
+ # Public Key: 0x7369626ce8030000000000000000000000000000000000000000000000000000
1602
+ # SS58: 5Eg2fntNprdN3FgH4sfEaaZhYtddZQSQUqvYJ1f2mLtinVhV
1603
+ # Prefix: 42
1241
1604
 
1242
1605
  # Show only the child (relay chain) account
1243
1606
  dot parachain 2004 --type child
@@ -1250,6 +1613,13 @@ dot parachain 1000 --prefix 0
1250
1613
 
1251
1614
  # JSON output
1252
1615
  dot parachain 1000 --json
1616
+ # Output:
1617
+ # {
1618
+ # "paraId": 1000,
1619
+ # "prefix": 42,
1620
+ # "child": { "publicKey": "0x70617261...", "ss58": "5Ec4AhPZ..." },
1621
+ # "sibling": { "publicKey": "0x7369626c...", "ss58": "5Eg2fntN..." }
1622
+ # }
1253
1623
  ```
1254
1624
 
1255
1625
  Run `dot parachain` with no arguments to see usage and examples.
@@ -1261,9 +1631,20 @@ Derive Bandersnatch member keys from account mnemonics for on-chain member set r
1261
1631
  ```bash
1262
1632
  # Derive unkeyed member key (lite person)
1263
1633
  dot verifiable alice
1634
+ # Output:
1635
+ # Bandersnatch Member Key
1636
+ #
1637
+ # Account: alice
1638
+ # Member Key: 0x66813b70ba616b374c90ac92edff6e3be95e12adbc93ea7a6c37cbf334ab87e2
1264
1639
 
1265
1640
  # Derive keyed member key (full person — "candidate" context)
1266
1641
  dot verifiable alice --context candidate
1642
+ # Output:
1643
+ # Bandersnatch Member Key
1644
+ #
1645
+ # Account: alice
1646
+ # Context: candidate
1647
+ # Member Key: 0x2fd5b74033d904cf5575b932507939c5d43811e488223229eaf5596565f15ae6
1267
1648
 
1268
1649
  # Arbitrary context string
1269
1650
  dot verifiable alice --context pps
@@ -1302,21 +1683,21 @@ dot hash --help # same as `dot hash` — shows algorithms and examples
1302
1683
  Use `--help` on any fully-qualified dot-path to see metadata detail and category-specific usage hints. The chain is required (so the CLI knows which metadata to load), but the call itself runs offline from the cache:
1303
1684
 
1304
1685
  ```bash
1305
- dot tx.System.remark --help --chain polkadot # call args, docs, and tx options
1306
- dot query.System.Account --help --chain polkadot # storage type, key/value info, and query options
1307
- dot const.Balances.ExistentialDeposit --help --chain polkadot # constant type and docs
1308
- dot events.Balances.Transfer --help --chain polkadot # event fields and docs
1309
- dot errors.Balances.InsufficientBalance --help --chain polkadot # error docs
1310
- dot apis.Core.version --help --chain polkadot # runtime API method signature and docs
1686
+ dot polkadot.tx.System.remark --help # call args, docs, and tx options
1687
+ dot polkadot.query.System.Account --help # storage type, key/value info, and query options
1688
+ dot polkadot.const.Balances.ExistentialDeposit --help # constant type and docs
1689
+ dot polkadot.events.Balances.Transfer --help # event fields and docs
1690
+ dot polkadot.errors.Balances.InsufficientBalance --help # error docs
1691
+ dot polkadot.apis.Core.version --help # runtime API method signature and docs
1311
1692
 
1312
- # A chain prefix is equivalent
1313
- dot polkadot.tx.System.remark --help
1693
+ # The --chain flag is equivalent to the chain prefix
1694
+ dot tx.System.remark --help --chain polkadot
1314
1695
  ```
1315
1696
 
1316
1697
  For `tx` commands, omitting both `--from` and `--encode` shows this same help output instead of an error:
1317
1698
 
1318
1699
  ```bash
1319
- dot tx.System.remark 0xdead --chain polkadot # shows call help (no error)
1700
+ dot polkadot.tx.System.remark 0xdead # shows call help (no error)
1320
1701
  ```
1321
1702
 
1322
1703
  ### Global options
@@ -1337,9 +1718,10 @@ dot tx.System.remark 0xdead --chain polkadot # shows call help (no error)
1337
1718
  Every command supports `--json` for machine-readable output. This works on data queries, metadata inspection, account management, chain configuration, and transaction submission:
1338
1719
 
1339
1720
  ```bash
1340
- dot inspect --json --chain polkadot # All pallets as JSON
1341
- dot inspect Balances --json --chain polkadot # Pallet detail with storage, constants, calls, events, errors
1721
+ dot inspect polkadot --json # All pallets as JSON
1722
+ dot inspect polkadot.Balances --json # Pallet detail with storage, constants, calls, events, errors
1342
1723
  dot chain list --json # Configured chains
1724
+ dot chain info polkadot --json # Full detail for one chain (rpc, parachains, metadata status)
1343
1725
  dot account list --json # Dev and stored accounts
1344
1726
  dot account create my-key --json # New account details (mnemonic warning on stderr)
1345
1727
  dot polkadot.tx.System.remark 0xdead --encode --json # Encoded call hex wrapped in JSON
@@ -1347,10 +1729,20 @@ dot polkadot.events.Balances --json # Event listing with field
1347
1729
  dot polkadot.const.System --json # Constant listing with types
1348
1730
  ```
1349
1731
 
1732
+ For `--encode` with `--json`, the call hex is wrapped in an object:
1733
+
1734
+ ```bash
1735
+ dot polkadot.tx.System.remark 0xdead --encode --json
1736
+ # Output:
1737
+ # {
1738
+ # "callHex": "0x000008dead"
1739
+ # }
1740
+ ```
1741
+
1350
1742
  For transaction submission, `--json` emits NDJSON (one JSON object per lifecycle event):
1351
1743
 
1352
1744
  ```bash
1353
- dot tx.System.remark 0xdead --from alice --chain polkadot --json
1745
+ dot polkadot.tx.System.remark 0xdead --from alice --json
1354
1746
  # {"event":"signed","txHash":"0x..."}
1355
1747
  # {"event":"broadcasted","txHash":"0x..."}
1356
1748
  # {"event":"finalized","blockNumber":123,"blockHash":"0x...","ok":true,"events":[...]}
@@ -1365,7 +1757,7 @@ dot polkadot.const.System.SS58Prefix --json | jq '.+1'
1365
1757
  dot polkadot.query.System.Number --json | jq
1366
1758
  dot chain list --json | jq '.chains[].name'
1367
1759
  dot account list --json | jq '.stored[].address'
1368
- dot inspect --json --chain polkadot | jq '.pallets[] | select(.events > 10) | .name'
1760
+ dot inspect polkadot --json | jq '.pallets[] | select(.events > 10) | .name'
1369
1761
  ```
1370
1762
 
1371
1763
  In an interactive terminal, both streams render together so you see progress and results normally.
@@ -1450,11 +1842,16 @@ Config and metadata caches live in `~/.polkadot/` by default:
1450
1842
  ├── update-check.json # cached update check result
1451
1843
  └── chains/
1452
1844
  └── polkadot/
1453
- └── metadata.bin # cached SCALE-encoded metadata
1845
+ ├── metadata.bin # cached SCALE-encoded metadata
1846
+ └── metadata.fingerprint.json # runtime fingerprint (specVersion, codeHash, …) for stale-metadata detection
1454
1847
  ```
1455
1848
 
1456
1849
  > **Warning:** `accounts.json` stores secrets (mnemonics and seeds) in **plain text**. Encrypted-at-rest storage is planned but not yet implemented. Keep appropriate file permissions (`chmod 600 ~/.polkadot/accounts.json`) and do not use this for high-value mainnet accounts.
1457
1850
 
1851
+ ### `DOT_TRUST_CACHED_METADATA` — skip the staleness check
1852
+
1853
+ Set `DOT_TRUST_CACHED_METADATA=1` to disable the post-failure stale-metadata check on `dot tx`, `dot tx --dry-run`, and `dot query`. When set, errors propagate exactly as the runtime / RPC reported them, with no extra `state_getRuntimeVersion` / `state_getStorageHash` round-trip. Useful in CI loops where you've just refreshed metadata manually and don't want the overhead.
1854
+
1458
1855
  ### `DOT_HOME` — redirect the config directory
1459
1856
 
1460
1857
  Set the `DOT_HOME` environment variable to point at a different directory. When set, the CLI reads and writes **everything** (config, accounts, metadata, update cache) under that path — no `.polkadot` suffix is appended.