polkadot-cli 0.0.0-beta-20260316075937

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 +613 -0
  2. package/dist/cli.mjs +4683 -0
  3. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,613 @@
1
+ [![codecov](https://codecov.io/gh/peetzweg/polkadot-cli/branch/main/graph/badge.svg)](https://codecov.io/gh/peetzweg/polkadot-cli)
2
+
3
+ # polkadot-cli
4
+
5
+ A command-line tool for interacting with Polkadot-ecosystem chains. Manage chains and accounts, query storage, look up constants, inspect metadata, submit extrinsics, and compute hashes — all from your terminal.
6
+
7
+ Ships with Polkadot and all system parachains preconfigured with multiple fallback RPC endpoints. Add any Substrate-based chain by pointing to its RPC endpoint(s).
8
+
9
+ ### Preconfigured chains
10
+
11
+ | Network | Chain | Light client |
12
+ |---------|-------|:---:|
13
+ | Polkadot | `polkadot` (relay, default) | yes |
14
+ | | `polkadot-asset-hub` | yes |
15
+ | | `polkadot-bridge-hub` | yes |
16
+ | | `polkadot-collectives` | yes |
17
+ | | `polkadot-coretime` | yes |
18
+ | | `polkadot-people` | yes |
19
+ | Paseo (testnet) | `paseo` (relay) | yes |
20
+ | | `paseo-asset-hub` | yes |
21
+ | | `paseo-bridge-hub` | — |
22
+ | | `paseo-collectives` | — |
23
+ | | `paseo-coretime` | yes |
24
+ | | `paseo-people` | yes |
25
+
26
+ Each chain ships with multiple RPC endpoints from decentralized infrastructure providers (IBP, Dotters, Dwellir, and others). The CLI automatically falls back to the next endpoint if the primary is unreachable.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ npm install -g polkadot-cli@latest
32
+ ```
33
+
34
+ This installs the `dot` command globally.
35
+
36
+ ## Usage
37
+
38
+ ### Manage chains
39
+
40
+ ```bash
41
+ # Show chain help
42
+ dot chain # shows available actions
43
+ dot chains # shorthand, same as above
44
+
45
+ # Add a chain (single RPC)
46
+ dot chain add kusama --rpc wss://kusama-rpc.polkadot.io
47
+
48
+ # Add a chain with fallback RPCs (repeat --rpc for each endpoint)
49
+ dot chain add kusama --rpc wss://kusama-rpc.polkadot.io --rpc wss://kusama-rpc.dwellir.com
50
+
51
+ # Add a chain via light client
52
+ dot chain add westend --light-client
53
+
54
+ # List configured chains
55
+ dot chain list
56
+
57
+ # Re-fetch metadata after a runtime upgrade
58
+ dot chain update # updates default chain
59
+ dot chain update kusama # updates a specific chain
60
+
61
+ # Set default chain
62
+ dot chain default kusama
63
+
64
+ # Remove a chain
65
+ dot chain remove westend
66
+ ```
67
+
68
+ ### Manage accounts
69
+
70
+ Dev accounts (Alice, Bob, Charlie, Dave, Eve, Ferdie) are always available for testnets. Create or import your own accounts for any chain.
71
+
72
+ > **Security warning:** Account secrets (mnemonics and seeds) are currently stored **unencrypted** in `~/.polkadot/accounts.json`. Do not use this for high-value accounts on mainnet. Encrypted storage is planned for a future release. Use `--env` to keep secrets off disk entirely.
73
+
74
+ ```bash
75
+ # Show account help
76
+ dot account # shows available actions
77
+ dot accounts # shorthand, same as above
78
+
79
+ # List all accounts (dev + stored)
80
+ dot account list
81
+
82
+ # Add a watch-only address (no secret — for use as tx recipient or query target)
83
+ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
84
+ dot account add council 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
85
+
86
+ # Create a new account (generates a mnemonic)
87
+ dot account create my-validator
88
+
89
+ # Create with a derivation path
90
+ dot account create my-staking --path //staking
91
+
92
+ # Import from a BIP39 mnemonic
93
+ dot account import treasury --secret "word1 word2 ... word12"
94
+
95
+ # Import with a derivation path
96
+ dot account import hot-wallet --secret "word1 word2 ... word12" --path //hot
97
+
98
+ # Import an env-var-backed account (secret stays off disk)
99
+ dot account import ci-signer --env MY_SECRET
100
+
101
+ # Derive a child account from an existing one
102
+ dot account derive treasury treasury-staking --path //staking
103
+
104
+ # Use it — the env var is read at signing time
105
+ MY_SECRET="word1 word2 ..." dot tx System.remark 0xdead --from ci-signer
106
+
107
+ # Remove one or more accounts
108
+ dot account remove my-validator
109
+ dot account delete my-validator stale-key
110
+
111
+ # Inspect an account — show public key and SS58 address
112
+ dot account inspect alice
113
+ dot account alice # shorthand (same as inspect)
114
+ dot account inspect 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
115
+ dot account inspect 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
116
+ dot account inspect alice --prefix 0 # Polkadot mainnet prefix
117
+ dot account inspect alice --output json # JSON output
118
+ ```
119
+
120
+ #### Watch-only accounts
121
+
122
+ Add named addresses without secrets — useful for saving frequently-used recipients, multisig members, or query targets:
123
+
124
+ ```bash
125
+ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
126
+ dot account add council 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
127
+ ```
128
+
129
+ Watch-only accounts appear in `dot account list` with a `(watch-only)` badge and can be inspected and removed like any other account. They cannot be used with `--from` (signing) or as a source for `derive`.
130
+
131
+ The `add` subcommand is context-sensitive: bare `add <name> <address>` creates a watch-only entry, while `add --secret` or `add --env` imports a keyed account (same as `import`).
132
+
133
+ #### Named address resolution
134
+
135
+ Named accounts (both watch-only and keyed) resolve automatically everywhere an AccountId32 or MultiAddress is expected — in `dot tx` arguments and `dot query` keys:
136
+
137
+ ```bash
138
+ # Use a named account as transfer recipient
139
+ dot tx Balances.transferKeepAlive treasury 1000000000000 --from alice
140
+
141
+ # Query by account name
142
+ dot query System.Account treasury
143
+
144
+ # Dev accounts also resolve
145
+ dot tx Balances.transferKeepAlive bob 1000000000000 --from alice
146
+ ```
147
+
148
+ Resolution order: dev account name > stored account name > SS58 address > hex public key. If the input doesn't match any, the CLI shows an error listing available account names.
149
+
150
+ #### Inspect accounts
151
+
152
+ Convert between SS58 addresses, hex public keys, and account names. Accepts any of:
153
+
154
+ - **Dev account name** (`alice`, `bob`, etc.) — resolves to public key and SS58
155
+ - **Stored account name** — looks up the public key from the accounts file
156
+ - **SS58 address** — decodes to the underlying public key
157
+ - **Hex public key** (`0x` + 64 hex chars) — encodes to SS58
158
+
159
+ ```bash
160
+ dot account inspect alice
161
+ dot account alice # shorthand — unknown subcommands fall through to inspect
162
+
163
+ dot account inspect 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
164
+ dot account inspect 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
165
+ ```
166
+
167
+ Use `--prefix` to encode the SS58 address with a specific network prefix (default: 42):
168
+
169
+ ```bash
170
+ dot account inspect alice --prefix 0 # Polkadot mainnet (prefix 0, starts with '1')
171
+ dot account inspect alice --prefix 2 # Kusama (prefix 2)
172
+ ```
173
+
174
+ JSON output:
175
+
176
+ ```bash
177
+ dot account inspect alice --output json
178
+ # {"publicKey":"0xd435...a27d","ss58":"5Grw...utQY","prefix":42,"name":"Alice"}
179
+ ```
180
+
181
+ #### Env-var-backed accounts
182
+
183
+ For CI/CD and security-conscious workflows, store a reference to an environment variable instead of the secret itself:
184
+
185
+ ```bash
186
+ dot account import ci-signer --env MY_SECRET
187
+ ```
188
+
189
+ `--secret` and `--env` are mutually exclusive. `add` is an alias for `import`.
190
+
191
+ The secret is never written to disk. At signing time, the CLI reads `$MY_SECRET` and derives the keypair. If the variable is not set, the CLI errors with a clear message. `account list` shows an `(env: MY_SECRET)` badge and resolves the address live when the variable is available.
192
+
193
+ #### Derivation paths
194
+
195
+ Use `--path` with `create`, `import`, or the `derive` action to derive child keys from the same secret. Different paths produce different keypairs, enabling key separation (e.g. staking vs. governance) without managing multiple mnemonics.
196
+
197
+ ```bash
198
+ # Create with a derivation path
199
+ dot account create my-staking --path //staking
200
+
201
+ # Multi-segment path (hard + soft junctions)
202
+ dot account create multi --path //polkadot//0/wallet
203
+
204
+ # Import with a path
205
+ dot account import hot --secret "word1 word2 ..." --path //hot
206
+
207
+ # Derive a child from an existing account
208
+ dot account derive treasury treasury-staking --path //staking
209
+ ```
210
+
211
+ `derive` copies the source account's secret and applies the given path. It requires both a source name, a new name, and `--path`. Works with env-backed accounts too — the derived account shares the same env var reference.
212
+
213
+ `account list` shows the derivation path next to the account name:
214
+
215
+ ```
216
+ treasury-staking (//staking) 5FHneW46...
217
+ ci-signer (//ci) (env: MY_SECRET) 5EPCUjPx...
218
+ ```
219
+
220
+ **Supported secret formats for import:**
221
+
222
+ | Format | Example | Status |
223
+ |--------|---------|--------|
224
+ | BIP39 mnemonic (12/24 words) | `"abandon abandon ... about"` | Supported |
225
+ | Hex seed (`0x` + 64 hex chars) | `0xabcdef0123...` | Not supported via CLI (see below) |
226
+
227
+ **Known limitation:** Hex seed import (`--secret 0x...`) does not work from the command line. The CLI argument parser (`cac`) interprets `0x`-prefixed values as JavaScript numbers, which loses precision for 32-byte seeds. Use a BIP39 mnemonic instead. If you need to import a raw seed programmatically, write it directly to `~/.polkadot/accounts.json`.
228
+
229
+ ### Chain prefix
230
+
231
+ Instead of the `--chain` flag, you can prefix any target with the chain name using dot notation:
232
+
233
+ ```bash
234
+ dot query kusama.System.Account 5GrwvaEF...
235
+ dot const kusama.Balances.ExistentialDeposit
236
+ dot tx kusama.Balances.transferKeepAlive 5FHneW46... 1000000000000 --from alice
237
+ dot inspect kusama.System
238
+ dot inspect kusama.System.Account
239
+ ```
240
+
241
+ Chain names are case-insensitive — `Polkadot.System.Account`, `POLKADOT.System.Account`, and `polkadot.System.Account` all resolve the same way. The same applies to `--chain Polkadot` and `dot chain default Polkadot`.
242
+
243
+ The `--chain` flag and default chain still work as before. If both a chain prefix and `--chain` flag are provided, the CLI errors.
244
+
245
+ ### Query storage
246
+
247
+ ```bash
248
+ # Plain storage value
249
+ dot query System.Number
250
+
251
+ # Map entry by key
252
+ dot query System.Account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
253
+
254
+ # All map entries (default limit: 100)
255
+ dot query System.Account --limit 10
256
+
257
+ # Pipe-safe — stdout is clean data, progress messages go to stderr
258
+ dot query System.Account --limit 5 | jq '.[0].value.data.free'
259
+ dot query System.Number --output json | jq '.+1'
260
+
261
+ # Query a specific chain using chain prefix
262
+ dot query kusama.System.Account 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
263
+ ```
264
+
265
+ #### Output formatting
266
+
267
+ Query results automatically convert on-chain types for readability:
268
+
269
+ - **BigInt** values (e.g. balances) render as decimal strings
270
+ - **Binary** fields (e.g. token `name`, `symbol`) render as text when valid UTF-8, or as `0x`-prefixed hex otherwise
271
+ - **Uint8Array** values render as `0x`-prefixed hex
272
+
273
+ ```bash
274
+ # Token metadata — symbol and name display as text, not {}
275
+ dot query assethub-paseo.Assets.Metadata 50000413
276
+ # { "deposit": "6693666000", "name": "Paseo Token", "symbol": "PAS", ... }
277
+ ```
278
+
279
+ ### Look up constants
280
+
281
+ ```bash
282
+ dot const Balances.ExistentialDeposit
283
+ dot const System.SS58Prefix --chain kusama
284
+ dot const kusama.Balances.ExistentialDeposit
285
+
286
+ # Pipe-safe — stdout is clean JSON, progress messages go to stderr
287
+ dot const Balances.ExistentialDeposit --output json | jq
288
+ ```
289
+
290
+ ### Inspect metadata
291
+
292
+ Works offline from cached metadata after the first fetch.
293
+
294
+ ```bash
295
+ # List all pallets (shows storage, constants, calls, events, and errors counts)
296
+ dot inspect
297
+
298
+ # List a pallet's storage items, constants, calls, events, and errors
299
+ dot inspect System
300
+
301
+ # Detailed type info for a specific storage item or constant
302
+ dot inspect System.Account
303
+
304
+ # Call detail — shows argument signature and docs
305
+ dot inspect Balances.transfer_allow_death
306
+
307
+ # Event detail — shows field signature and docs
308
+ dot inspect Balances.Transfer
309
+
310
+ # Error detail — shows docs
311
+ dot inspect Balances.InsufficientBalance
312
+
313
+ # Inspect a specific chain using chain prefix
314
+ dot inspect kusama.System
315
+ dot inspect kusama.System.Account
316
+ ```
317
+
318
+ The pallet listing view shows type information inline so you can understand item shapes at a glance:
319
+
320
+ - **Storage**: key/value types with `[map]` tag for map items (e.g. `Account: AccountId32 → { nonce: u32, ... } [map]`)
321
+ - **Constants**: the constant's type (e.g. `ExistentialDeposit: u128`)
322
+ - **Calls**: full argument signature (e.g. `transfer_allow_death(dest: enum(5 variants), value: Compact<u128>)`)
323
+ - **Events**: field signature (e.g. `Transfer(from: AccountId32, to: AccountId32, amount: u128)`)
324
+ - **Errors**: name and documentation (e.g. `InsufficientBalance`)
325
+
326
+ 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.
327
+
328
+ ### Focused commands
329
+
330
+ Browse specific metadata categories directly without using `dot inspect`:
331
+
332
+ ```bash
333
+ # List all pallets
334
+ dot pallets
335
+
336
+ # List pallet calls with argument signatures
337
+ dot calls Balances
338
+ dot calls Balances.transfer_allow_death # call detail
339
+
340
+ # List pallet events with field signatures
341
+ dot events Balances
342
+ dot events Balances.Transfer # event detail
343
+
344
+ # List pallet errors
345
+ dot errors Balances
346
+ dot errors Balances.InsufficientBalance # error detail
347
+
348
+ # List pallet storage items with types
349
+ dot storage System
350
+ dot storage System.Account # storage detail
351
+
352
+ # List pallet constants (dual-purpose — also works as value lookup)
353
+ dot const Balances # list constants
354
+ dot const Balances.ExistentialDeposit # look up value
355
+ ```
356
+
357
+ Each command supports `--chain <name>`, `--rpc <url>`, and chain prefix syntax. Singular and plural forms are interchangeable (e.g. `dot call` = `dot calls`, `dot event` = `dot events`).
358
+
359
+ ### Submit extrinsics
360
+
361
+ 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.
362
+
363
+ ```bash
364
+ # Simple remark
365
+ dot tx System.remark 0xdeadbeef --from alice
366
+
367
+ # Transfer (amount in plancks)
368
+ dot tx Balances.transferKeepAlive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --from alice
369
+
370
+ # Estimate fees without submitting
371
+ dot tx Balances.transferKeepAlive 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty 1000000000000 --from alice --dry-run
372
+
373
+ # Submit a raw SCALE-encoded call (e.g. from a multisig proposal or another tool)
374
+ dot tx 0x0503008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48 --from alice
375
+
376
+ # Batch multiple transfers with Utility.batchAll
377
+ dot tx Utility.batchAll '[{"type":"Balances","value":{"type":"transfer_keep_alive","value":{"dest":"5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty","value":1000000000000}}},{"type":"Balances","value":{"type":"transfer_keep_alive","value":{"dest":"5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y","value":2000000000000}}}]' --from alice
378
+ ```
379
+
380
+ #### Enum shorthand
381
+
382
+ Enum arguments accept a concise `Variant(value)` syntax instead of verbose JSON:
383
+
384
+ ```bash
385
+ # Instead of: '{"type":"system","value":{"type":"Authorized"}}'
386
+ dot tx Utility.dispatch_as 'system(Authorized)' $(dot tx System.remark 0xcafe --encode) --from alice
387
+
388
+ # Nested enums work too
389
+ dot tx Utility.dispatch_as 'system(Signed(5FHneW46...))' <call> --from alice
390
+
391
+ # Void variants — empty parens or just the name
392
+ dot tx ... 'Root()' ...
393
+ dot tx ... 'Root' ...
394
+
395
+ # JSON inside parens for struct values
396
+ dot tx ... 'AccountId32({"id":"0xd435..."})' ...
397
+ ```
398
+
399
+ Variant matching is case-insensitive (`system` resolves to `system`, `authorized` to `Authorized`). All existing formats (JSON objects, hex, SS58 addresses) continue to work unchanged.
400
+
401
+ #### Encode call data
402
+
403
+ Encode a call to hex without signing or submitting. Useful for preparing calls to pass to `Sudo.sudo`, multisig proposals, or governance. Works offline from cached metadata and does not require `--from`.
404
+
405
+ ```bash
406
+ # Encode a remark call
407
+ dot tx System.remark 0xdeadbeef --encode
408
+
409
+ # Encode a transfer (use the hex output in a batch or sudo call)
410
+ dot tx Balances.transfer_keep_alive 5FHneW46... 1000000000000 --encode
411
+
412
+ # Use encoded output with Sudo.sudo
413
+ dot tx Sudo.sudo $(dot tx System.remark 0xcafe --encode) --from alice
414
+ ```
415
+
416
+ Both dry-run and submission display the encoded call hex and a decoded human-readable form:
417
+
418
+ ```
419
+ Call: 0x0001076465616462656566
420
+ Decode: System.remark(remark: 0xdeadbeef)
421
+ Tx: 0xabc123...
422
+ Status: ok
423
+ ```
424
+
425
+ Complex calls (e.g. XCM teleports) that the primary decoder cannot handle are automatically decoded via a fallback path:
426
+
427
+ ```
428
+ Decode: PolkadotXcm.limited_teleport_assets { dest: V3 { parents: 1, interior: X1(Parachain(5140)) }, beneficiary: V3 { ... }, assets: V3 [...], fee_asset_item: 0, weight_limit: Unlimited }
429
+ ```
430
+
431
+ #### Exit codes
432
+
433
+ 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`).
434
+
435
+ ```bash
436
+ dot tx Balances.transferKeepAlive 5FHneW46... 999999999999999999 --from alice
437
+ # ... events and explorer links ...
438
+ # Error: Transaction dispatch error: Balances.InsufficientBalance
439
+ echo $? # 1
440
+ ```
441
+
442
+ #### Argument parsing errors
443
+
444
+ When a call argument is invalid, the CLI shows a contextual error message with the argument name, the expected type, and a hint:
445
+
446
+ ```bash
447
+ dot tx Balances.transferKeepAlive 5GrwvaEF... abc --encode
448
+ # Error: Invalid value for argument 'value' (expected Compact<u128>): "abc"
449
+ # Hint: Compact<u128>
450
+ ```
451
+
452
+ For struct-based calls, the error identifies the specific field that failed. For tuple-based calls, it shows the argument index. The original parse error is preserved as the `cause` for programmatic access.
453
+
454
+ #### Custom signed extensions
455
+
456
+ Chains with non-standard signed extensions (e.g. `people-preview`) are auto-handled:
457
+
458
+ - `void` → empty bytes
459
+ - `Option<T>` → `None`
460
+ - enum with `Disabled` variant → `Disabled`
461
+
462
+ For manual override, use `--ext` with a JSON object:
463
+
464
+ ```bash
465
+ dot tx System.remark 0xdeadbeef --from alice --ext '{"MyExtension":{"value":"..."}}'
466
+ ```
467
+
468
+ ### Compute hashes
469
+
470
+ Compute cryptographic hashes commonly used in Substrate. Supports BLAKE2b-256, BLAKE2b-128, Keccak-256, and SHA-256.
471
+
472
+ ```bash
473
+ # Hash hex-encoded data
474
+ dot hash blake2b256 0xdeadbeef
475
+
476
+ # Hash plain text (UTF-8 encoded)
477
+ dot hash sha256 hello
478
+
479
+ # Hash file contents
480
+ dot hash keccak256 --file ./data.bin
481
+
482
+ # Read from stdin
483
+ echo -n "hello" | dot hash sha256 --stdin
484
+
485
+ # JSON output
486
+ dot hash blake2b256 0xdeadbeef --output json
487
+ ```
488
+
489
+ Run `dot hash` with no arguments to see all available algorithms.
490
+
491
+ ### Getting help
492
+
493
+ Every command supports `--help` to show its detailed usage, available actions, and examples:
494
+
495
+ ```bash
496
+ dot --help # global help with all commands
497
+ dot account --help # same as `dot account` — shows account actions
498
+ dot chain --help # same as `dot chain` — shows chain actions
499
+ dot hash --help # same as `dot hash` — shows algorithms and examples
500
+ ```
501
+
502
+ #### Item-level help
503
+
504
+ Use `--help` on any fully-qualified dot-path to see metadata detail and category-specific usage hints — all offline, no chain connection required:
505
+
506
+ ```bash
507
+ dot tx.System.remark --help # call args, docs, and tx options
508
+ dot query.System.Account --help # storage type, key/value info, and query options
509
+ dot const.Balances.ExistentialDeposit --help # constant type and docs
510
+ dot events.Balances.Transfer --help # event fields and docs
511
+ dot errors.Balances.InsufficientBalance --help # error docs
512
+ ```
513
+
514
+ For `tx` commands, omitting both `--from` and `--encode` shows this same help output instead of an error:
515
+
516
+ ```bash
517
+ dot tx.System.remark 0xdead # shows call help (no error)
518
+ ```
519
+
520
+ ### Global options
521
+
522
+ | Flag | Description |
523
+ |------|-------------|
524
+ | `--help` | Show help (global or command-specific) |
525
+ | `--chain <name>` | Target chain (default from config) |
526
+ | `--rpc <url>` | Override RPC endpoint(s) for this call (repeat for fallback) |
527
+ | `--light-client` | Use Smoldot light client |
528
+ | `--output json` | Raw JSON output (default: pretty) |
529
+ | `--limit <n>` | Max entries for map queries (0 = unlimited, default: 100) |
530
+
531
+ ### Pipe-safe output
532
+
533
+ All commands follow Unix conventions: **data goes to stdout, progress goes to stderr**. This means you can safely pipe `--output json` into `jq` or other tools without progress messages ("Fetching metadata...", spinner output, "Connecting...") corrupting the data stream:
534
+
535
+ ```bash
536
+ dot const System.SS58Prefix --output json | jq '.+1'
537
+ dot query System.Number --output json | jq
538
+ ```
539
+
540
+ In an interactive terminal, both streams render together so you see progress and results normally.
541
+
542
+ ## How it compares
543
+
544
+ | | polkadot-cli | @polkadot/api-cli | subxt-cli | Pop CLI |
545
+ |---|---|---|---|---|
546
+ | **Query storage** | SS58 keys, map iteration | yes (full `--ws` URL required) | yes (keys as SCALE tuples, no SS58) | — |
547
+ | **Read constants** | yes | yes | yes | — |
548
+ | **Submit extrinsics** | yes, with dry-run | yes (via `--seed`) | — | ink! contract calls only |
549
+ | **Inspect metadata** | yes | — | yes (excellent browser) | — |
550
+ | **Chain presets** | built-in aliases (`--chain kusama`) | — (manual `--ws` every call) | — | parachain templates |
551
+ | **Tx tracking + explorer links** | spinner progress, block + explorer link | basic events | — | — |
552
+
553
+ polkadot-cli aims to be the single tool for day-to-day chain interaction: storage reads, constant lookups, transaction submission, and metadata browsing with a polished terminal UX. @polkadot/api-cli covers similar ground but is in maintenance mode and requires verbose flags. subxt-cli has an excellent metadata explorer but cannot sign or submit transactions. Pop CLI targets a different workflow — scaffolding parachains and deploying ink! contracts rather than end-user chain queries.
554
+
555
+ Outside Polkadot, the closest comparable in terms of interactive UX is [near-cli-rs](https://github.com/near/near-cli-rs) (NEAR).
556
+
557
+ ## Update notifications
558
+
559
+ After each command, the CLI checks whether a newer version is available on npm and displays a notification:
560
+
561
+ ```
562
+ ╭───────────────────────────────────────────────╮
563
+ │ │
564
+ │ Update available! 0.6.2 → 0.7.0 │
565
+ │ Run npm i -g polkadot-cli to update │
566
+ │ │
567
+ ╰───────────────────────────────────────────────╯
568
+ ```
569
+
570
+ The version check runs in the background on startup and caches the result for 24 hours in `~/.polkadot/update-check.json`. Before exiting, the CLI waits up to 500ms for the check to finish so the cache file is written — even for fast commands like `--help` and `--version`. Long-running commands (queries, transactions) are unaffected since the check completes well before they finish.
571
+
572
+ If the network is unreachable, the failed check is cached for 1 hour so subsequent runs don't incur the 500ms wait repeatedly.
573
+
574
+ The notification is automatically suppressed when:
575
+
576
+ - `DOT_NO_UPDATE_CHECK=1` is set
577
+ - `CI` environment variable is set (any value)
578
+ - stderr is not a TTY (e.g. piped output)
579
+
580
+ ## Configuration
581
+
582
+ Config and metadata caches live in `~/.polkadot/`:
583
+
584
+ ```
585
+ ~/.polkadot/
586
+ ├── config.json # chains and default chain
587
+ ├── accounts.json # stored accounts (⚠️ secrets are NOT encrypted — see below)
588
+ ├── update-check.json # cached update check result
589
+ └── chains/
590
+ └── polkadot/
591
+ └── metadata.bin # cached SCALE-encoded metadata
592
+ ```
593
+
594
+ > **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.
595
+
596
+ ## Environment compatibility
597
+
598
+ The CLI works in Node.js, Bun, and sandboxed runtimes (e.g. LLM tool-use / MCP environments) that lack a native `globalThis.WebSocket`. WebSocket connections use the [`ws`](https://github.com/websockets/ws) package explicitly, so no global polyfill is required.
599
+
600
+ ## Development
601
+
602
+ Requires [Bun](https://bun.sh).
603
+
604
+ ```bash
605
+ bun install
606
+ bun run dev -- query System.Number
607
+ bun run build
608
+ bun test
609
+ ```
610
+
611
+ ## License
612
+
613
+ MIT