polkadot-cli 0.13.0 → 1.1.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.
- package/README.md +79 -5
- package/dist/cli.mjs +1443 -317
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
|
5
5
|
// src/cli.ts
|
|
6
6
|
import cac from "cac";
|
|
7
7
|
// package.json
|
|
8
|
-
var version = "
|
|
8
|
+
var version = "1.1.0";
|
|
9
9
|
|
|
10
10
|
// src/config/accounts-store.ts
|
|
11
11
|
import { access as access2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
@@ -429,7 +429,7 @@ class Spinner {
|
|
|
429
429
|
start(msg) {
|
|
430
430
|
this.stop();
|
|
431
431
|
if (!isTTY) {
|
|
432
|
-
console.
|
|
432
|
+
console.error(msg);
|
|
433
433
|
return;
|
|
434
434
|
}
|
|
435
435
|
process.stdout.write(`${SPINNER_FRAMES[0]} ${msg}`);
|
|
@@ -449,9 +449,16 @@ class Spinner {
|
|
|
449
449
|
}
|
|
450
450
|
succeed(msg) {
|
|
451
451
|
this.stop();
|
|
452
|
-
console.
|
|
452
|
+
console.error(`${GREEN}${CHECK_MARK}${RESET} ${msg}`);
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
|
+
function firstSentence(docs) {
|
|
456
|
+
const text = docs.join(" ").trim();
|
|
457
|
+
if (!text)
|
|
458
|
+
return "";
|
|
459
|
+
const match = text.match(/^.*?(?<![ei]\.g|[ei]\.[eg])(?<!\betc)[.!?](?:\s|$)/);
|
|
460
|
+
return match ? match[0].trim() : text;
|
|
461
|
+
}
|
|
455
462
|
|
|
456
463
|
// src/commands/account.ts
|
|
457
464
|
var ACCOUNT_HELP = `
|
|
@@ -977,26 +984,28 @@ function listPallets(meta) {
|
|
|
977
984
|
docs: c.docs ?? [],
|
|
978
985
|
typeId: c.type
|
|
979
986
|
})),
|
|
980
|
-
calls:
|
|
987
|
+
calls: extractEnumVariants(meta, p.calls),
|
|
988
|
+
events: extractEnumVariants(meta, p.events),
|
|
989
|
+
errors: extractEnumVariants(meta, p.errors).map(({ name, docs }) => ({ name, docs }))
|
|
981
990
|
}));
|
|
982
991
|
}
|
|
983
|
-
function
|
|
984
|
-
if (!
|
|
992
|
+
function extractEnumVariants(meta, ref) {
|
|
993
|
+
if (!ref)
|
|
985
994
|
return [];
|
|
986
995
|
try {
|
|
987
|
-
const entry = meta.lookup(
|
|
996
|
+
const entry = meta.lookup(ref.type);
|
|
988
997
|
if (entry.type !== "enum")
|
|
989
998
|
return [];
|
|
990
999
|
return Object.entries(entry.value).map(([name, variant]) => ({
|
|
991
1000
|
name,
|
|
992
|
-
docs:
|
|
993
|
-
typeId:
|
|
1001
|
+
docs: entry.innerDocs?.[name] ?? [],
|
|
1002
|
+
typeId: resolveVariantTypeId(variant)
|
|
994
1003
|
}));
|
|
995
1004
|
} catch {
|
|
996
1005
|
return [];
|
|
997
1006
|
}
|
|
998
1007
|
}
|
|
999
|
-
function
|
|
1008
|
+
function resolveVariantTypeId(variant) {
|
|
1000
1009
|
if (variant.type === "lookupEntry")
|
|
1001
1010
|
return variant.value?.id ?? null;
|
|
1002
1011
|
if (variant.type === "struct")
|
|
@@ -1095,6 +1104,42 @@ function describeCallArgs(meta, palletName, callName) {
|
|
|
1095
1104
|
return "";
|
|
1096
1105
|
}
|
|
1097
1106
|
}
|
|
1107
|
+
function describeEventFields(meta, palletName, eventName) {
|
|
1108
|
+
try {
|
|
1109
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
1110
|
+
if (!palletMeta?.events)
|
|
1111
|
+
return "";
|
|
1112
|
+
const eventsEntry = meta.lookup(palletMeta.events.type);
|
|
1113
|
+
if (eventsEntry.type !== "enum")
|
|
1114
|
+
return "";
|
|
1115
|
+
const variant = eventsEntry.value[eventName];
|
|
1116
|
+
if (!variant)
|
|
1117
|
+
return "";
|
|
1118
|
+
if (variant.type === "void")
|
|
1119
|
+
return "()";
|
|
1120
|
+
if (variant.type === "struct") {
|
|
1121
|
+
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1122
|
+
return `(${fields})`;
|
|
1123
|
+
}
|
|
1124
|
+
if (variant.type === "lookupEntry") {
|
|
1125
|
+
const inner = variant.value;
|
|
1126
|
+
if (inner.type === "void")
|
|
1127
|
+
return "()";
|
|
1128
|
+
if (inner.type === "struct") {
|
|
1129
|
+
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1130
|
+
return `(${fields})`;
|
|
1131
|
+
}
|
|
1132
|
+
return `(${formatLookupEntry(inner)})`;
|
|
1133
|
+
}
|
|
1134
|
+
if (variant.type === "tuple") {
|
|
1135
|
+
const types = variant.value.map(formatLookupEntry).join(", ");
|
|
1136
|
+
return `(${types})`;
|
|
1137
|
+
}
|
|
1138
|
+
return "";
|
|
1139
|
+
} catch {
|
|
1140
|
+
return "";
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1098
1143
|
function hexToBytes(hex) {
|
|
1099
1144
|
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
1100
1145
|
const bytes = new Uint8Array(clean.length / 2);
|
|
@@ -1170,10 +1215,10 @@ async function chainAdd(name, opts) {
|
|
|
1170
1215
|
rpc: opts.rpc ?? "",
|
|
1171
1216
|
...opts.lightClient ? { lightClient: true } : {}
|
|
1172
1217
|
};
|
|
1173
|
-
console.
|
|
1218
|
+
console.error(`Connecting to ${name}...`);
|
|
1174
1219
|
const clientHandle = await createChainClient(name, chainConfig, opts.rpc);
|
|
1175
1220
|
try {
|
|
1176
|
-
console.
|
|
1221
|
+
console.error("Fetching metadata...");
|
|
1177
1222
|
await fetchMetadataFromChain(clientHandle, name);
|
|
1178
1223
|
const config = await loadConfig();
|
|
1179
1224
|
config.chains[name] = chainConfig;
|
|
@@ -1226,10 +1271,10 @@ async function chainList() {
|
|
|
1226
1271
|
async function chainUpdate(name, opts) {
|
|
1227
1272
|
const config = await loadConfig();
|
|
1228
1273
|
const { name: chainName, chain: chainConfig } = resolveChain(config, name);
|
|
1229
|
-
console.
|
|
1274
|
+
console.error(`Connecting to ${chainName}...`);
|
|
1230
1275
|
const clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
1231
1276
|
try {
|
|
1232
|
-
console.
|
|
1277
|
+
console.error("Fetching metadata...");
|
|
1233
1278
|
await fetchMetadataFromChain(clientHandle, chainName);
|
|
1234
1279
|
console.log(`Metadata for "${chainName}" updated.`);
|
|
1235
1280
|
} finally {
|
|
@@ -1288,96 +1333,822 @@ function suggestMessage(kind, input, candidates) {
|
|
|
1288
1333
|
return `Unknown ${kind} "${input}". Did you mean: ${suggestions.join(", ")}?`;
|
|
1289
1334
|
}
|
|
1290
1335
|
|
|
1291
|
-
// src/
|
|
1292
|
-
function
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
if (!parts[0] || !parts[1]) {
|
|
1303
|
-
throw new Error(`Invalid target "${input}". Expected format: Pallet.Item or Chain.Pallet (e.g. System.Account or kusama.System)`);
|
|
1304
|
-
}
|
|
1305
|
-
if (options.knownChains?.some((c) => c.toLowerCase() === parts[0].toLowerCase())) {
|
|
1306
|
-
return { chain: parts[0], pallet: parts[1] };
|
|
1307
|
-
}
|
|
1308
|
-
return { pallet: parts[0], item: parts[1] };
|
|
1309
|
-
case 3:
|
|
1310
|
-
if (!parts[0] || !parts[1] || !parts[2]) {
|
|
1311
|
-
throw new Error(`Invalid target "${input}". Expected format: Chain.Pallet.Item (e.g. kusama.System.Account)`);
|
|
1312
|
-
}
|
|
1313
|
-
return { chain: parts[0], pallet: parts[1], item: parts[2] };
|
|
1314
|
-
default:
|
|
1315
|
-
throw new Error(`Invalid target "${input}". Expected format: Pallet, Pallet.Item, or Chain.Pallet.Item`);
|
|
1336
|
+
// src/commands/focused-inspect.ts
|
|
1337
|
+
async function loadMeta(chainName, chainConfig, rpcOverride) {
|
|
1338
|
+
try {
|
|
1339
|
+
return await getOrFetchMetadata(chainName);
|
|
1340
|
+
} catch {
|
|
1341
|
+
console.error(`Fetching metadata from ${chainName}...`);
|
|
1342
|
+
const clientHandle = await createChainClient(chainName, chainConfig, rpcOverride);
|
|
1343
|
+
try {
|
|
1344
|
+
return await getOrFetchMetadata(chainName, clientHandle);
|
|
1345
|
+
} finally {
|
|
1346
|
+
clientHandle.destroy();
|
|
1316
1347
|
}
|
|
1317
1348
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1349
|
+
}
|
|
1350
|
+
function resolvePallet(meta, palletName) {
|
|
1351
|
+
const palletNames = getPalletNames(meta);
|
|
1352
|
+
const pallet = findPallet(meta, palletName);
|
|
1353
|
+
if (!pallet) {
|
|
1354
|
+
throw new Error(suggestMessage("pallet", palletName, palletNames));
|
|
1355
|
+
}
|
|
1356
|
+
return pallet;
|
|
1357
|
+
}
|
|
1358
|
+
async function handleCalls(target, opts) {
|
|
1359
|
+
if (!target) {
|
|
1360
|
+
const config2 = await loadConfig();
|
|
1361
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1362
|
+
const meta2 = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
1363
|
+
const pallets = listPallets(meta2);
|
|
1364
|
+
const withCalls = pallets.filter((p) => p.calls.length > 0);
|
|
1365
|
+
printHeading(`Pallets with calls on ${chainName2} (${withCalls.length})`);
|
|
1366
|
+
for (const p of withCalls) {
|
|
1367
|
+
printItem(p.name, `${p.calls.length} calls`);
|
|
1368
|
+
}
|
|
1369
|
+
console.log();
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
const config = await loadConfig();
|
|
1373
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1374
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1375
|
+
const dotIdx = target.indexOf(".");
|
|
1376
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1377
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1378
|
+
const pallet = resolvePallet(meta, palletName);
|
|
1379
|
+
if (!itemName) {
|
|
1380
|
+
if (pallet.calls.length === 0) {
|
|
1381
|
+
console.log(`No calls in ${pallet.name}.`);
|
|
1382
|
+
return;
|
|
1383
|
+
}
|
|
1384
|
+
printHeading(`${pallet.name} Calls`);
|
|
1385
|
+
for (const c of pallet.calls) {
|
|
1386
|
+
const args2 = describeCallArgs(meta, pallet.name, c.name);
|
|
1387
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}${args2}${RESET}`);
|
|
1388
|
+
const summary = firstSentence(c.docs);
|
|
1389
|
+
if (summary) {
|
|
1390
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1322
1391
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1392
|
+
}
|
|
1393
|
+
console.log();
|
|
1394
|
+
return;
|
|
1395
|
+
}
|
|
1396
|
+
const callItem = pallet.calls.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
1397
|
+
if (!callItem) {
|
|
1398
|
+
const names = pallet.calls.map((c) => c.name);
|
|
1399
|
+
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
1400
|
+
}
|
|
1401
|
+
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
1402
|
+
const args = describeCallArgs(meta, pallet.name, callItem.name);
|
|
1403
|
+
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
1404
|
+
if (callItem.docs.length) {
|
|
1405
|
+
console.log();
|
|
1406
|
+
printDocs(callItem.docs);
|
|
1407
|
+
}
|
|
1408
|
+
console.log();
|
|
1409
|
+
}
|
|
1410
|
+
async function handleEvents(target, opts) {
|
|
1411
|
+
if (!target) {
|
|
1412
|
+
const config2 = await loadConfig();
|
|
1413
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1414
|
+
const meta2 = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
1415
|
+
const pallets = listPallets(meta2);
|
|
1416
|
+
const withEvents = pallets.filter((p) => p.events.length > 0);
|
|
1417
|
+
printHeading(`Pallets with events on ${chainName2} (${withEvents.length})`);
|
|
1418
|
+
for (const p of withEvents) {
|
|
1419
|
+
printItem(p.name, `${p.events.length} events`);
|
|
1420
|
+
}
|
|
1421
|
+
console.log();
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
const config = await loadConfig();
|
|
1425
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1426
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1427
|
+
const dotIdx = target.indexOf(".");
|
|
1428
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1429
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1430
|
+
const pallet = resolvePallet(meta, palletName);
|
|
1431
|
+
if (!itemName) {
|
|
1432
|
+
if (pallet.events.length === 0) {
|
|
1433
|
+
console.log(`No events in ${pallet.name}.`);
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1436
|
+
printHeading(`${pallet.name} Events`);
|
|
1437
|
+
for (const e of pallet.events) {
|
|
1438
|
+
const fields2 = describeEventFields(meta, pallet.name, e.name);
|
|
1439
|
+
console.log(` ${CYAN}${e.name}${RESET}${DIM}${fields2}${RESET}`);
|
|
1440
|
+
const summary = firstSentence(e.docs);
|
|
1441
|
+
if (summary) {
|
|
1442
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1327
1443
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1444
|
+
}
|
|
1445
|
+
console.log();
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1449
|
+
if (!eventItem) {
|
|
1450
|
+
const names = pallet.events.map((e) => e.name);
|
|
1451
|
+
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
1331
1452
|
}
|
|
1453
|
+
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
1454
|
+
const fields = describeEventFields(meta, pallet.name, eventItem.name);
|
|
1455
|
+
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
1456
|
+
if (eventItem.docs.length) {
|
|
1457
|
+
console.log();
|
|
1458
|
+
printDocs(eventItem.docs);
|
|
1459
|
+
}
|
|
1460
|
+
console.log();
|
|
1332
1461
|
}
|
|
1333
|
-
function
|
|
1334
|
-
if (target
|
|
1335
|
-
|
|
1462
|
+
async function handleErrors(target, opts) {
|
|
1463
|
+
if (!target) {
|
|
1464
|
+
const config2 = await loadConfig();
|
|
1465
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1466
|
+
const meta2 = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
1467
|
+
const pallets = listPallets(meta2);
|
|
1468
|
+
const withErrors = pallets.filter((p) => p.errors.length > 0);
|
|
1469
|
+
printHeading(`Pallets with errors on ${chainName2} (${withErrors.length})`);
|
|
1470
|
+
for (const p of withErrors) {
|
|
1471
|
+
printItem(p.name, `${p.errors.length} errors`);
|
|
1472
|
+
}
|
|
1473
|
+
console.log();
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
const config = await loadConfig();
|
|
1477
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1478
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1479
|
+
const dotIdx = target.indexOf(".");
|
|
1480
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1481
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1482
|
+
const pallet = resolvePallet(meta, palletName);
|
|
1483
|
+
if (!itemName) {
|
|
1484
|
+
if (pallet.errors.length === 0) {
|
|
1485
|
+
console.log(`No errors in ${pallet.name}.`);
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
printHeading(`${pallet.name} Errors`);
|
|
1489
|
+
for (const e of pallet.errors) {
|
|
1490
|
+
console.log(` ${CYAN}${e.name}${RESET}`);
|
|
1491
|
+
const summary = firstSentence(e.docs);
|
|
1492
|
+
if (summary) {
|
|
1493
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
console.log();
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
const errorItem = pallet.errors.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1500
|
+
if (!errorItem) {
|
|
1501
|
+
const names = pallet.errors.map((e) => e.name);
|
|
1502
|
+
throw new Error(suggestMessage(`error in ${pallet.name}`, itemName, names));
|
|
1503
|
+
}
|
|
1504
|
+
printHeading(`${pallet.name}.${errorItem.name} (Error)`);
|
|
1505
|
+
if (errorItem.docs.length) {
|
|
1506
|
+
printDocs(errorItem.docs);
|
|
1507
|
+
}
|
|
1508
|
+
console.log();
|
|
1509
|
+
}
|
|
1510
|
+
async function handleStorage(target, opts) {
|
|
1511
|
+
if (!target) {
|
|
1512
|
+
const config2 = await loadConfig();
|
|
1513
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1514
|
+
const meta2 = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
1515
|
+
const pallets = listPallets(meta2);
|
|
1516
|
+
const withStorage = pallets.filter((p) => p.storage.length > 0);
|
|
1517
|
+
printHeading(`Pallets with storage on ${chainName2} (${withStorage.length})`);
|
|
1518
|
+
for (const p of withStorage) {
|
|
1519
|
+
printItem(p.name, `${p.storage.length} storage`);
|
|
1520
|
+
}
|
|
1521
|
+
console.log();
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
const config = await loadConfig();
|
|
1525
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1526
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1527
|
+
const dotIdx = target.indexOf(".");
|
|
1528
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1529
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1530
|
+
const pallet = resolvePallet(meta, palletName);
|
|
1531
|
+
if (!itemName) {
|
|
1532
|
+
if (pallet.storage.length === 0) {
|
|
1533
|
+
console.log(`No storage items in ${pallet.name}.`);
|
|
1534
|
+
return;
|
|
1535
|
+
}
|
|
1536
|
+
printHeading(`${pallet.name} Storage`);
|
|
1537
|
+
for (const s of pallet.storage) {
|
|
1538
|
+
const valueType = describeType(meta.lookup, s.valueTypeId);
|
|
1539
|
+
let typeSuffix;
|
|
1540
|
+
if (s.keyTypeId != null) {
|
|
1541
|
+
const keyType = describeType(meta.lookup, s.keyTypeId);
|
|
1542
|
+
typeSuffix = `: ${keyType} → ${valueType} [map]`;
|
|
1543
|
+
} else {
|
|
1544
|
+
typeSuffix = `: ${valueType}`;
|
|
1545
|
+
}
|
|
1546
|
+
console.log(` ${CYAN}${s.name}${RESET}${DIM}${typeSuffix}${RESET}`);
|
|
1547
|
+
const summary = firstSentence(s.docs);
|
|
1548
|
+
if (summary) {
|
|
1549
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
console.log();
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
const storageItem = pallet.storage.find((s) => s.name.toLowerCase() === itemName.toLowerCase());
|
|
1556
|
+
if (!storageItem) {
|
|
1557
|
+
const names = pallet.storage.map((s) => s.name);
|
|
1558
|
+
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
1559
|
+
}
|
|
1560
|
+
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
1561
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
1562
|
+
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
1563
|
+
if (storageItem.keyTypeId != null) {
|
|
1564
|
+
console.log(` ${BOLD}Key:${RESET} ${describeType(meta.lookup, storageItem.keyTypeId)}`);
|
|
1565
|
+
}
|
|
1566
|
+
if (storageItem.docs.length) {
|
|
1567
|
+
console.log();
|
|
1568
|
+
printDocs(storageItem.docs);
|
|
1569
|
+
}
|
|
1570
|
+
console.log();
|
|
1571
|
+
}
|
|
1572
|
+
async function showItemHelp(category, target, opts) {
|
|
1573
|
+
const config = await loadConfig();
|
|
1574
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1575
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1576
|
+
const dotIdx = target.indexOf(".");
|
|
1577
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1578
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1579
|
+
const pallet = resolvePallet(meta, palletName);
|
|
1580
|
+
if (!itemName) {
|
|
1581
|
+
switch (category) {
|
|
1582
|
+
case "tx":
|
|
1583
|
+
await handleCalls(target, opts);
|
|
1584
|
+
return;
|
|
1585
|
+
case "query":
|
|
1586
|
+
await handleStorage(target, opts);
|
|
1587
|
+
return;
|
|
1588
|
+
case "const":
|
|
1589
|
+
return;
|
|
1590
|
+
case "events":
|
|
1591
|
+
await handleEvents(target, opts);
|
|
1592
|
+
return;
|
|
1593
|
+
case "errors":
|
|
1594
|
+
await handleErrors(target, opts);
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
switch (category) {
|
|
1599
|
+
case "tx": {
|
|
1600
|
+
const callItem = pallet.calls.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
1601
|
+
if (!callItem) {
|
|
1602
|
+
const names = pallet.calls.map((c) => c.name);
|
|
1603
|
+
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
1604
|
+
}
|
|
1605
|
+
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
1606
|
+
const args = describeCallArgs(meta, pallet.name, callItem.name);
|
|
1607
|
+
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
1608
|
+
if (callItem.docs.length) {
|
|
1609
|
+
console.log();
|
|
1610
|
+
printDocs(callItem.docs);
|
|
1611
|
+
}
|
|
1612
|
+
console.log();
|
|
1613
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1614
|
+
console.log(` dot tx.${pallet.name}.${callItem.name} --from <account>`);
|
|
1615
|
+
console.log(` dot tx.${pallet.name}.${callItem.name} --encode`);
|
|
1616
|
+
console.log();
|
|
1617
|
+
console.log(`${BOLD}Options:${RESET}`);
|
|
1618
|
+
console.log(` --from <name> Account to sign with`);
|
|
1619
|
+
console.log(` --dry-run Estimate fees without submitting`);
|
|
1620
|
+
console.log(` --encode Encode call to hex without signing`);
|
|
1621
|
+
console.log(` --ext <json> Custom signed extension values as JSON`);
|
|
1622
|
+
console.log();
|
|
1623
|
+
return;
|
|
1624
|
+
}
|
|
1625
|
+
case "query": {
|
|
1626
|
+
const storageItem = pallet.storage.find((s) => s.name.toLowerCase() === itemName.toLowerCase());
|
|
1627
|
+
if (!storageItem) {
|
|
1628
|
+
const names = pallet.storage.map((s) => s.name);
|
|
1629
|
+
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
1630
|
+
}
|
|
1631
|
+
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
1632
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
1633
|
+
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
1634
|
+
if (storageItem.keyTypeId != null) {
|
|
1635
|
+
console.log(` ${BOLD}Key:${RESET} ${describeType(meta.lookup, storageItem.keyTypeId)}`);
|
|
1636
|
+
}
|
|
1637
|
+
if (storageItem.docs.length) {
|
|
1638
|
+
console.log();
|
|
1639
|
+
printDocs(storageItem.docs);
|
|
1640
|
+
}
|
|
1641
|
+
console.log();
|
|
1642
|
+
if (storageItem.keyTypeId != null) {
|
|
1643
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1644
|
+
console.log(` dot query.${pallet.name}.${storageItem.name} <key>`);
|
|
1645
|
+
console.log(` dot query.${pallet.name}.${storageItem.name} # all entries`);
|
|
1646
|
+
} else {
|
|
1647
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1648
|
+
console.log(` dot query.${pallet.name}.${storageItem.name}`);
|
|
1649
|
+
}
|
|
1650
|
+
console.log();
|
|
1651
|
+
console.log(`${BOLD}Options:${RESET}`);
|
|
1652
|
+
console.log(` --limit <n> Max entries for map queries (0 = unlimited, default: 100)`);
|
|
1653
|
+
console.log();
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
case "const": {
|
|
1657
|
+
const constItem = pallet.constants.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
1658
|
+
if (!constItem) {
|
|
1659
|
+
const names = pallet.constants.map((c) => c.name);
|
|
1660
|
+
throw new Error(suggestMessage(`constant in ${pallet.name}`, itemName, names));
|
|
1661
|
+
}
|
|
1662
|
+
printHeading(`${pallet.name}.${constItem.name} (Constant)`);
|
|
1663
|
+
console.log(` ${BOLD}Type:${RESET} ${describeType(meta.lookup, constItem.typeId)}`);
|
|
1664
|
+
if (constItem.docs.length) {
|
|
1665
|
+
console.log();
|
|
1666
|
+
printDocs(constItem.docs);
|
|
1667
|
+
}
|
|
1668
|
+
console.log();
|
|
1669
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1670
|
+
console.log(` dot const.${pallet.name}.${constItem.name}`);
|
|
1671
|
+
console.log();
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
case "events": {
|
|
1675
|
+
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1676
|
+
if (!eventItem) {
|
|
1677
|
+
const names = pallet.events.map((e) => e.name);
|
|
1678
|
+
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
1679
|
+
}
|
|
1680
|
+
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
1681
|
+
const fields = describeEventFields(meta, pallet.name, eventItem.name);
|
|
1682
|
+
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
1683
|
+
if (eventItem.docs.length) {
|
|
1684
|
+
console.log();
|
|
1685
|
+
printDocs(eventItem.docs);
|
|
1686
|
+
}
|
|
1687
|
+
console.log();
|
|
1688
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1689
|
+
console.log(` dot events.${pallet.name}.${eventItem.name}`);
|
|
1690
|
+
console.log();
|
|
1691
|
+
return;
|
|
1692
|
+
}
|
|
1693
|
+
case "errors": {
|
|
1694
|
+
const errorItem = pallet.errors.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1695
|
+
if (!errorItem) {
|
|
1696
|
+
const names = pallet.errors.map((e) => e.name);
|
|
1697
|
+
throw new Error(suggestMessage(`error in ${pallet.name}`, itemName, names));
|
|
1698
|
+
}
|
|
1699
|
+
printHeading(`${pallet.name}.${errorItem.name} (Error)`);
|
|
1700
|
+
if (errorItem.docs.length) {
|
|
1701
|
+
printDocs(errorItem.docs);
|
|
1702
|
+
}
|
|
1703
|
+
console.log();
|
|
1704
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
1705
|
+
console.log(` dot errors.${pallet.name}.${errorItem.name}`);
|
|
1706
|
+
console.log();
|
|
1707
|
+
return;
|
|
1708
|
+
}
|
|
1336
1709
|
}
|
|
1337
|
-
return target.chain ?? chainFlag;
|
|
1338
1710
|
}
|
|
1339
1711
|
|
|
1340
1712
|
// src/commands/const.ts
|
|
1341
|
-
function
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1713
|
+
async function handleConst(target, opts) {
|
|
1714
|
+
if (!target) {
|
|
1715
|
+
const config2 = await loadConfig();
|
|
1716
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1717
|
+
const meta = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
1718
|
+
const pallets = listPallets(meta);
|
|
1719
|
+
const withConsts = pallets.filter((p) => p.constants.length > 0);
|
|
1720
|
+
printHeading(`Pallets with constants on ${chainName2} (${withConsts.length})`);
|
|
1721
|
+
for (const p of withConsts) {
|
|
1722
|
+
printItem(p.name, `${p.constants.length} constants`);
|
|
1723
|
+
}
|
|
1724
|
+
console.log();
|
|
1725
|
+
return;
|
|
1726
|
+
}
|
|
1727
|
+
const dotIdx = target.indexOf(".");
|
|
1728
|
+
const pallet = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1729
|
+
const item = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1730
|
+
const config = await loadConfig();
|
|
1731
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1732
|
+
if (!item) {
|
|
1733
|
+
const meta = await loadMeta(chainName, chainConfig, opts.rpc);
|
|
1734
|
+
const palletNames = getPalletNames(meta);
|
|
1735
|
+
const palletInfo = findPallet(meta, pallet);
|
|
1736
|
+
if (!palletInfo) {
|
|
1737
|
+
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
1738
|
+
}
|
|
1739
|
+
if (palletInfo.constants.length === 0) {
|
|
1740
|
+
console.log(`No constants in ${palletInfo.name}.`);
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
printHeading(`${palletInfo.name} Constants`);
|
|
1744
|
+
for (const c of palletInfo.constants) {
|
|
1745
|
+
const typeStr = describeType(meta.lookup, c.typeId);
|
|
1746
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}: ${typeStr}${RESET}`);
|
|
1747
|
+
const summary = firstSentence(c.docs);
|
|
1748
|
+
if (summary) {
|
|
1749
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
console.log();
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
const clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
1756
|
+
try {
|
|
1757
|
+
const meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
1758
|
+
const palletNames = getPalletNames(meta);
|
|
1759
|
+
const palletInfo = findPallet(meta, pallet);
|
|
1760
|
+
if (!palletInfo) {
|
|
1761
|
+
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
1762
|
+
}
|
|
1763
|
+
const constantItem = palletInfo.constants.find((c) => c.name.toLowerCase() === item.toLowerCase());
|
|
1764
|
+
if (!constantItem) {
|
|
1765
|
+
const constNames = palletInfo.constants.map((c) => c.name);
|
|
1766
|
+
throw new Error(suggestMessage(`constant in ${palletInfo.name}`, item, constNames));
|
|
1767
|
+
}
|
|
1768
|
+
const unsafeApi = clientHandle.client.getUnsafeApi();
|
|
1769
|
+
const runtimeToken = await unsafeApi.runtimeToken;
|
|
1770
|
+
const result = unsafeApi.constants[palletInfo.name][constantItem.name](runtimeToken);
|
|
1771
|
+
const format = opts.output ?? "pretty";
|
|
1772
|
+
printResult(result, format);
|
|
1773
|
+
} finally {
|
|
1774
|
+
clientHandle.destroy();
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
// src/commands/focused-inspect.ts
|
|
1779
|
+
async function loadMeta2(chainName, chainConfig, rpcOverride) {
|
|
1780
|
+
try {
|
|
1781
|
+
return await getOrFetchMetadata(chainName);
|
|
1782
|
+
} catch {
|
|
1783
|
+
console.error(`Fetching metadata from ${chainName}...`);
|
|
1784
|
+
const clientHandle = await createChainClient(chainName, chainConfig, rpcOverride);
|
|
1785
|
+
try {
|
|
1786
|
+
return await getOrFetchMetadata(chainName, clientHandle);
|
|
1787
|
+
} finally {
|
|
1788
|
+
clientHandle.destroy();
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
function resolvePallet2(meta, palletName) {
|
|
1793
|
+
const palletNames = getPalletNames(meta);
|
|
1794
|
+
const pallet = findPallet(meta, palletName);
|
|
1795
|
+
if (!pallet) {
|
|
1796
|
+
throw new Error(suggestMessage("pallet", palletName, palletNames));
|
|
1797
|
+
}
|
|
1798
|
+
return pallet;
|
|
1799
|
+
}
|
|
1800
|
+
async function handleCalls2(target, opts) {
|
|
1801
|
+
if (!target) {
|
|
1802
|
+
const config2 = await loadConfig();
|
|
1803
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1804
|
+
const meta2 = await loadMeta2(chainName2, chainConfig2, opts.rpc);
|
|
1805
|
+
const pallets = listPallets(meta2);
|
|
1806
|
+
const withCalls = pallets.filter((p) => p.calls.length > 0);
|
|
1807
|
+
printHeading(`Pallets with calls on ${chainName2} (${withCalls.length})`);
|
|
1808
|
+
for (const p of withCalls) {
|
|
1809
|
+
printItem(p.name, `${p.calls.length} calls`);
|
|
1810
|
+
}
|
|
1811
|
+
console.log();
|
|
1812
|
+
return;
|
|
1813
|
+
}
|
|
1814
|
+
const config = await loadConfig();
|
|
1815
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1816
|
+
const meta = await loadMeta2(chainName, chainConfig, opts.rpc);
|
|
1817
|
+
const dotIdx = target.indexOf(".");
|
|
1818
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1819
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1820
|
+
const pallet = resolvePallet2(meta, palletName);
|
|
1821
|
+
if (!itemName) {
|
|
1822
|
+
if (pallet.calls.length === 0) {
|
|
1823
|
+
console.log(`No calls in ${pallet.name}.`);
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
printHeading(`${pallet.name} Calls`);
|
|
1827
|
+
for (const c of pallet.calls) {
|
|
1828
|
+
const args2 = describeCallArgs(meta, pallet.name, c.name);
|
|
1829
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}${args2}${RESET}`);
|
|
1830
|
+
const summary = firstSentence(c.docs);
|
|
1831
|
+
if (summary) {
|
|
1832
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
console.log();
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
const callItem = pallet.calls.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
1839
|
+
if (!callItem) {
|
|
1840
|
+
const names = pallet.calls.map((c) => c.name);
|
|
1841
|
+
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
1842
|
+
}
|
|
1843
|
+
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
1844
|
+
const args = describeCallArgs(meta, pallet.name, callItem.name);
|
|
1845
|
+
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
1846
|
+
if (callItem.docs.length) {
|
|
1847
|
+
console.log();
|
|
1848
|
+
printDocs(callItem.docs);
|
|
1849
|
+
}
|
|
1850
|
+
console.log();
|
|
1851
|
+
}
|
|
1852
|
+
async function handleEvents2(target, opts) {
|
|
1853
|
+
if (!target) {
|
|
1854
|
+
const config2 = await loadConfig();
|
|
1855
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1856
|
+
const meta2 = await loadMeta2(chainName2, chainConfig2, opts.rpc);
|
|
1857
|
+
const pallets = listPallets(meta2);
|
|
1858
|
+
const withEvents = pallets.filter((p) => p.events.length > 0);
|
|
1859
|
+
printHeading(`Pallets with events on ${chainName2} (${withEvents.length})`);
|
|
1860
|
+
for (const p of withEvents) {
|
|
1861
|
+
printItem(p.name, `${p.events.length} events`);
|
|
1862
|
+
}
|
|
1863
|
+
console.log();
|
|
1864
|
+
return;
|
|
1865
|
+
}
|
|
1866
|
+
const config = await loadConfig();
|
|
1867
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1868
|
+
const meta = await loadMeta2(chainName, chainConfig, opts.rpc);
|
|
1869
|
+
const dotIdx = target.indexOf(".");
|
|
1870
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1871
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1872
|
+
const pallet = resolvePallet2(meta, palletName);
|
|
1873
|
+
if (!itemName) {
|
|
1874
|
+
if (pallet.events.length === 0) {
|
|
1875
|
+
console.log(`No events in ${pallet.name}.`);
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1878
|
+
printHeading(`${pallet.name} Events`);
|
|
1879
|
+
for (const e of pallet.events) {
|
|
1880
|
+
const fields2 = describeEventFields(meta, pallet.name, e.name);
|
|
1881
|
+
console.log(` ${CYAN}${e.name}${RESET}${DIM}${fields2}${RESET}`);
|
|
1882
|
+
const summary = firstSentence(e.docs);
|
|
1883
|
+
if (summary) {
|
|
1884
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
console.log();
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1890
|
+
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1891
|
+
if (!eventItem) {
|
|
1892
|
+
const names = pallet.events.map((e) => e.name);
|
|
1893
|
+
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
1894
|
+
}
|
|
1895
|
+
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
1896
|
+
const fields = describeEventFields(meta, pallet.name, eventItem.name);
|
|
1897
|
+
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
1898
|
+
if (eventItem.docs.length) {
|
|
1899
|
+
console.log();
|
|
1900
|
+
printDocs(eventItem.docs);
|
|
1901
|
+
}
|
|
1902
|
+
console.log();
|
|
1903
|
+
}
|
|
1904
|
+
async function handleErrors2(target, opts) {
|
|
1905
|
+
if (!target) {
|
|
1906
|
+
const config2 = await loadConfig();
|
|
1907
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1908
|
+
const meta2 = await loadMeta2(chainName2, chainConfig2, opts.rpc);
|
|
1909
|
+
const pallets = listPallets(meta2);
|
|
1910
|
+
const withErrors = pallets.filter((p) => p.errors.length > 0);
|
|
1911
|
+
printHeading(`Pallets with errors on ${chainName2} (${withErrors.length})`);
|
|
1912
|
+
for (const p of withErrors) {
|
|
1913
|
+
printItem(p.name, `${p.errors.length} errors`);
|
|
1914
|
+
}
|
|
1915
|
+
console.log();
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
const config = await loadConfig();
|
|
1919
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1920
|
+
const meta = await loadMeta2(chainName, chainConfig, opts.rpc);
|
|
1921
|
+
const dotIdx = target.indexOf(".");
|
|
1922
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1923
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1924
|
+
const pallet = resolvePallet2(meta, palletName);
|
|
1925
|
+
if (!itemName) {
|
|
1926
|
+
if (pallet.errors.length === 0) {
|
|
1927
|
+
console.log(`No errors in ${pallet.name}.`);
|
|
1928
|
+
return;
|
|
1929
|
+
}
|
|
1930
|
+
printHeading(`${pallet.name} Errors`);
|
|
1931
|
+
for (const e of pallet.errors) {
|
|
1932
|
+
console.log(` ${CYAN}${e.name}${RESET}`);
|
|
1933
|
+
const summary = firstSentence(e.docs);
|
|
1934
|
+
if (summary) {
|
|
1935
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
console.log();
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
const errorItem = pallet.errors.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
1942
|
+
if (!errorItem) {
|
|
1943
|
+
const names = pallet.errors.map((e) => e.name);
|
|
1944
|
+
throw new Error(suggestMessage(`error in ${pallet.name}`, itemName, names));
|
|
1945
|
+
}
|
|
1946
|
+
printHeading(`${pallet.name}.${errorItem.name} (Error)`);
|
|
1947
|
+
if (errorItem.docs.length) {
|
|
1948
|
+
printDocs(errorItem.docs);
|
|
1949
|
+
}
|
|
1950
|
+
console.log();
|
|
1951
|
+
}
|
|
1952
|
+
async function handleStorage2(target, opts) {
|
|
1953
|
+
if (!target) {
|
|
1954
|
+
const config2 = await loadConfig();
|
|
1955
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
1956
|
+
const meta2 = await loadMeta2(chainName2, chainConfig2, opts.rpc);
|
|
1957
|
+
const pallets = listPallets(meta2);
|
|
1958
|
+
const withStorage = pallets.filter((p) => p.storage.length > 0);
|
|
1959
|
+
printHeading(`Pallets with storage on ${chainName2} (${withStorage.length})`);
|
|
1960
|
+
for (const p of withStorage) {
|
|
1961
|
+
printItem(p.name, `${p.storage.length} storage`);
|
|
1962
|
+
}
|
|
1963
|
+
console.log();
|
|
1964
|
+
return;
|
|
1965
|
+
}
|
|
1966
|
+
const config = await loadConfig();
|
|
1967
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
1968
|
+
const meta = await loadMeta2(chainName, chainConfig, opts.rpc);
|
|
1969
|
+
const dotIdx = target.indexOf(".");
|
|
1970
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
1971
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
1972
|
+
const pallet = resolvePallet2(meta, palletName);
|
|
1973
|
+
if (!itemName) {
|
|
1974
|
+
if (pallet.storage.length === 0) {
|
|
1975
|
+
console.log(`No storage items in ${pallet.name}.`);
|
|
1976
|
+
return;
|
|
1977
|
+
}
|
|
1978
|
+
printHeading(`${pallet.name} Storage`);
|
|
1979
|
+
for (const s of pallet.storage) {
|
|
1980
|
+
const valueType = describeType(meta.lookup, s.valueTypeId);
|
|
1981
|
+
let typeSuffix;
|
|
1982
|
+
if (s.keyTypeId != null) {
|
|
1983
|
+
const keyType = describeType(meta.lookup, s.keyTypeId);
|
|
1984
|
+
typeSuffix = `: ${keyType} → ${valueType} [map]`;
|
|
1985
|
+
} else {
|
|
1986
|
+
typeSuffix = `: ${valueType}`;
|
|
1987
|
+
}
|
|
1988
|
+
console.log(` ${CYAN}${s.name}${RESET}${DIM}${typeSuffix}${RESET}`);
|
|
1989
|
+
const summary = firstSentence(s.docs);
|
|
1990
|
+
if (summary) {
|
|
1991
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
console.log();
|
|
1995
|
+
return;
|
|
1996
|
+
}
|
|
1997
|
+
const storageItem = pallet.storage.find((s) => s.name.toLowerCase() === itemName.toLowerCase());
|
|
1998
|
+
if (!storageItem) {
|
|
1999
|
+
const names = pallet.storage.map((s) => s.name);
|
|
2000
|
+
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
2001
|
+
}
|
|
2002
|
+
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
2003
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
2004
|
+
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
2005
|
+
if (storageItem.keyTypeId != null) {
|
|
2006
|
+
console.log(` ${BOLD}Key:${RESET} ${describeType(meta.lookup, storageItem.keyTypeId)}`);
|
|
2007
|
+
}
|
|
2008
|
+
if (storageItem.docs.length) {
|
|
2009
|
+
console.log();
|
|
2010
|
+
printDocs(storageItem.docs);
|
|
2011
|
+
}
|
|
2012
|
+
console.log();
|
|
2013
|
+
}
|
|
2014
|
+
async function showItemHelp2(category, target, opts) {
|
|
2015
|
+
const config = await loadConfig();
|
|
2016
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
2017
|
+
const meta = await loadMeta2(chainName, chainConfig, opts.rpc);
|
|
2018
|
+
const dotIdx = target.indexOf(".");
|
|
2019
|
+
const palletName = dotIdx === -1 ? target : target.slice(0, dotIdx);
|
|
2020
|
+
const itemName = dotIdx === -1 ? undefined : target.slice(dotIdx + 1);
|
|
2021
|
+
const pallet = resolvePallet2(meta, palletName);
|
|
2022
|
+
if (!itemName) {
|
|
2023
|
+
switch (category) {
|
|
2024
|
+
case "tx":
|
|
2025
|
+
await handleCalls2(target, opts);
|
|
2026
|
+
return;
|
|
2027
|
+
case "query":
|
|
2028
|
+
await handleStorage2(target, opts);
|
|
2029
|
+
return;
|
|
2030
|
+
case "const":
|
|
2031
|
+
return;
|
|
2032
|
+
case "events":
|
|
2033
|
+
await handleEvents2(target, opts);
|
|
2034
|
+
return;
|
|
2035
|
+
case "errors":
|
|
2036
|
+
await handleErrors2(target, opts);
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
switch (category) {
|
|
2041
|
+
case "tx": {
|
|
2042
|
+
const callItem = pallet.calls.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
2043
|
+
if (!callItem) {
|
|
2044
|
+
const names = pallet.calls.map((c) => c.name);
|
|
2045
|
+
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
2046
|
+
}
|
|
2047
|
+
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
2048
|
+
const args = describeCallArgs(meta, pallet.name, callItem.name);
|
|
2049
|
+
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
2050
|
+
if (callItem.docs.length) {
|
|
2051
|
+
console.log();
|
|
2052
|
+
printDocs(callItem.docs);
|
|
2053
|
+
}
|
|
2054
|
+
console.log();
|
|
2055
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2056
|
+
console.log(` dot tx.${pallet.name}.${callItem.name} --from <account>`);
|
|
2057
|
+
console.log(` dot tx.${pallet.name}.${callItem.name} --encode`);
|
|
2058
|
+
console.log();
|
|
2059
|
+
console.log(`${BOLD}Options:${RESET}`);
|
|
2060
|
+
console.log(` --from <name> Account to sign with`);
|
|
2061
|
+
console.log(` --dry-run Estimate fees without submitting`);
|
|
2062
|
+
console.log(` --encode Encode call to hex without signing`);
|
|
2063
|
+
console.log(` --ext <json> Custom signed extension values as JSON`);
|
|
2064
|
+
console.log();
|
|
2065
|
+
return;
|
|
2066
|
+
}
|
|
2067
|
+
case "query": {
|
|
2068
|
+
const storageItem = pallet.storage.find((s) => s.name.toLowerCase() === itemName.toLowerCase());
|
|
2069
|
+
if (!storageItem) {
|
|
2070
|
+
const names = pallet.storage.map((s) => s.name);
|
|
2071
|
+
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
2072
|
+
}
|
|
2073
|
+
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
2074
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
2075
|
+
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
2076
|
+
if (storageItem.keyTypeId != null) {
|
|
2077
|
+
console.log(` ${BOLD}Key:${RESET} ${describeType(meta.lookup, storageItem.keyTypeId)}`);
|
|
2078
|
+
}
|
|
2079
|
+
if (storageItem.docs.length) {
|
|
2080
|
+
console.log();
|
|
2081
|
+
printDocs(storageItem.docs);
|
|
2082
|
+
}
|
|
2083
|
+
console.log();
|
|
2084
|
+
if (storageItem.keyTypeId != null) {
|
|
2085
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2086
|
+
console.log(` dot query.${pallet.name}.${storageItem.name} <key>`);
|
|
2087
|
+
console.log(` dot query.${pallet.name}.${storageItem.name} # all entries`);
|
|
2088
|
+
} else {
|
|
2089
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2090
|
+
console.log(` dot query.${pallet.name}.${storageItem.name}`);
|
|
2091
|
+
}
|
|
2092
|
+
console.log();
|
|
2093
|
+
console.log(`${BOLD}Options:${RESET}`);
|
|
2094
|
+
console.log(` --limit <n> Max entries for map queries (0 = unlimited, default: 100)`);
|
|
2095
|
+
console.log();
|
|
2096
|
+
return;
|
|
2097
|
+
}
|
|
2098
|
+
case "const": {
|
|
2099
|
+
const constItem = pallet.constants.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
2100
|
+
if (!constItem) {
|
|
2101
|
+
const names = pallet.constants.map((c) => c.name);
|
|
2102
|
+
throw new Error(suggestMessage(`constant in ${pallet.name}`, itemName, names));
|
|
2103
|
+
}
|
|
2104
|
+
printHeading(`${pallet.name}.${constItem.name} (Constant)`);
|
|
2105
|
+
console.log(` ${BOLD}Type:${RESET} ${describeType(meta.lookup, constItem.typeId)}`);
|
|
2106
|
+
if (constItem.docs.length) {
|
|
2107
|
+
console.log();
|
|
2108
|
+
printDocs(constItem.docs);
|
|
2109
|
+
}
|
|
2110
|
+
console.log();
|
|
2111
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2112
|
+
console.log(` dot const.${pallet.name}.${constItem.name}`);
|
|
2113
|
+
console.log();
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
case "events": {
|
|
2117
|
+
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
2118
|
+
if (!eventItem) {
|
|
2119
|
+
const names = pallet.events.map((e) => e.name);
|
|
2120
|
+
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
2121
|
+
}
|
|
2122
|
+
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
2123
|
+
const fields = describeEventFields(meta, pallet.name, eventItem.name);
|
|
2124
|
+
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
2125
|
+
if (eventItem.docs.length) {
|
|
2126
|
+
console.log();
|
|
2127
|
+
printDocs(eventItem.docs);
|
|
2128
|
+
}
|
|
2129
|
+
console.log();
|
|
2130
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2131
|
+
console.log(` dot events.${pallet.name}.${eventItem.name}`);
|
|
2132
|
+
console.log();
|
|
1350
2133
|
return;
|
|
1351
2134
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
const pallet = parsed.pallet;
|
|
1358
|
-
const item = parsed.item;
|
|
1359
|
-
const clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
1360
|
-
try {
|
|
1361
|
-
const meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
1362
|
-
const palletNames = getPalletNames(meta);
|
|
1363
|
-
const palletInfo = findPallet(meta, pallet);
|
|
1364
|
-
if (!palletInfo) {
|
|
1365
|
-
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
2135
|
+
case "errors": {
|
|
2136
|
+
const errorItem = pallet.errors.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
2137
|
+
if (!errorItem) {
|
|
2138
|
+
const names = pallet.errors.map((e) => e.name);
|
|
2139
|
+
throw new Error(suggestMessage(`error in ${pallet.name}`, itemName, names));
|
|
1366
2140
|
}
|
|
1367
|
-
|
|
1368
|
-
if (
|
|
1369
|
-
|
|
1370
|
-
throw new Error(suggestMessage(`constant in ${palletInfo.name}`, item, constNames));
|
|
2141
|
+
printHeading(`${pallet.name}.${errorItem.name} (Error)`);
|
|
2142
|
+
if (errorItem.docs.length) {
|
|
2143
|
+
printDocs(errorItem.docs);
|
|
1371
2144
|
}
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
} finally {
|
|
1378
|
-
clientHandle.destroy();
|
|
2145
|
+
console.log();
|
|
2146
|
+
console.log(`${BOLD}Usage:${RESET}`);
|
|
2147
|
+
console.log(` dot errors.${pallet.name}.${errorItem.name}`);
|
|
2148
|
+
console.log();
|
|
2149
|
+
return;
|
|
1379
2150
|
}
|
|
1380
|
-
}
|
|
2151
|
+
}
|
|
1381
2152
|
}
|
|
1382
2153
|
|
|
1383
2154
|
// src/core/hash.ts
|
|
@@ -1511,9 +2282,58 @@ function registerHashCommand(cli) {
|
|
|
1511
2282
|
});
|
|
1512
2283
|
}
|
|
1513
2284
|
|
|
2285
|
+
// src/utils/parse-target.ts
|
|
2286
|
+
function parseTarget(input, options) {
|
|
2287
|
+
const parts = input.split(".");
|
|
2288
|
+
if (options?.allowPalletOnly) {
|
|
2289
|
+
switch (parts.length) {
|
|
2290
|
+
case 1:
|
|
2291
|
+
if (!parts[0]) {
|
|
2292
|
+
throw new Error(`Invalid target "${input}". Expected format: Pallet or Pallet.Item (e.g. System or System.Account)`);
|
|
2293
|
+
}
|
|
2294
|
+
return { pallet: parts[0] };
|
|
2295
|
+
case 2:
|
|
2296
|
+
if (!parts[0] || !parts[1]) {
|
|
2297
|
+
throw new Error(`Invalid target "${input}". Expected format: Pallet.Item or Chain.Pallet (e.g. System.Account or kusama.System)`);
|
|
2298
|
+
}
|
|
2299
|
+
if (options.knownChains?.some((c) => c.toLowerCase() === parts[0].toLowerCase())) {
|
|
2300
|
+
return { chain: parts[0], pallet: parts[1] };
|
|
2301
|
+
}
|
|
2302
|
+
return { pallet: parts[0], item: parts[1] };
|
|
2303
|
+
case 3:
|
|
2304
|
+
if (!parts[0] || !parts[1] || !parts[2]) {
|
|
2305
|
+
throw new Error(`Invalid target "${input}". Expected format: Chain.Pallet.Item (e.g. kusama.System.Account)`);
|
|
2306
|
+
}
|
|
2307
|
+
return { chain: parts[0], pallet: parts[1], item: parts[2] };
|
|
2308
|
+
default:
|
|
2309
|
+
throw new Error(`Invalid target "${input}". Expected format: Pallet, Pallet.Item, or Chain.Pallet.Item`);
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
switch (parts.length) {
|
|
2313
|
+
case 2:
|
|
2314
|
+
if (!parts[0] || !parts[1]) {
|
|
2315
|
+
throw new Error(`Invalid target "${input}". Expected format: Pallet.Item (e.g. System.Account)`);
|
|
2316
|
+
}
|
|
2317
|
+
return { pallet: parts[0], item: parts[1] };
|
|
2318
|
+
case 3:
|
|
2319
|
+
if (!parts[0] || !parts[1] || !parts[2]) {
|
|
2320
|
+
throw new Error(`Invalid target "${input}". Expected format: Chain.Pallet.Item (e.g. kusama.System.Account)`);
|
|
2321
|
+
}
|
|
2322
|
+
return { chain: parts[0], pallet: parts[1], item: parts[2] };
|
|
2323
|
+
default:
|
|
2324
|
+
throw new Error(`Invalid target "${input}". Expected format: Pallet.Item (e.g. System.Account)`);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
function resolveTargetChain(target, chainFlag) {
|
|
2328
|
+
if (target.chain && chainFlag) {
|
|
2329
|
+
throw new Error(`Chain specified both as prefix ("${target.chain}") and as --chain flag ("${chainFlag}"). Use one or the other.`);
|
|
2330
|
+
}
|
|
2331
|
+
return target.chain ?? chainFlag;
|
|
2332
|
+
}
|
|
2333
|
+
|
|
1514
2334
|
// src/commands/inspect.ts
|
|
1515
2335
|
function registerInspectCommand(cli) {
|
|
1516
|
-
cli.command("inspect [target]", "Inspect chain metadata (pallets, storage, constants)").option("--chain <name>", "Target chain").option("--rpc <url>", "Override RPC endpoint").action(async (target, opts) => {
|
|
2336
|
+
cli.command("inspect [target]", "Inspect chain metadata (pallets, storage, constants, calls, events, errors)").alias("explore").option("--chain <name>", "Target chain").option("--rpc <url>", "Override RPC endpoint").action(async (target, opts) => {
|
|
1517
2337
|
const config = await loadConfig();
|
|
1518
2338
|
const knownChains = Object.keys(config.chains);
|
|
1519
2339
|
let effectiveChain = opts.chain;
|
|
@@ -1530,7 +2350,7 @@ function registerInspectCommand(cli) {
|
|
|
1530
2350
|
try {
|
|
1531
2351
|
meta = await getOrFetchMetadata(chainName);
|
|
1532
2352
|
} catch {
|
|
1533
|
-
console.
|
|
2353
|
+
console.error(`Fetching metadata from ${chainName}...`);
|
|
1534
2354
|
const clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
1535
2355
|
try {
|
|
1536
2356
|
meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
@@ -1549,6 +2369,10 @@ function registerInspectCommand(cli) {
|
|
|
1549
2369
|
counts.push(`${p.constants.length} constants`);
|
|
1550
2370
|
if (p.calls.length)
|
|
1551
2371
|
counts.push(`${p.calls.length} calls`);
|
|
2372
|
+
if (p.events.length)
|
|
2373
|
+
counts.push(`${p.events.length} events`);
|
|
2374
|
+
if (p.errors.length)
|
|
2375
|
+
counts.push(`${p.errors.length} errors`);
|
|
1552
2376
|
printItem(p.name, counts.join(", "));
|
|
1553
2377
|
}
|
|
1554
2378
|
console.log();
|
|
@@ -1568,24 +2392,66 @@ function registerInspectCommand(cli) {
|
|
|
1568
2392
|
if (pallet2.storage.length) {
|
|
1569
2393
|
console.log(` ${BOLD}Storage Items:${RESET}`);
|
|
1570
2394
|
for (const s of pallet2.storage) {
|
|
1571
|
-
const
|
|
1572
|
-
|
|
2395
|
+
const valueType = describeType(meta.lookup, s.valueTypeId);
|
|
2396
|
+
let typeSuffix;
|
|
2397
|
+
if (s.keyTypeId != null) {
|
|
2398
|
+
const keyType = describeType(meta.lookup, s.keyTypeId);
|
|
2399
|
+
typeSuffix = `: ${keyType} → ${valueType} [map]`;
|
|
2400
|
+
} else {
|
|
2401
|
+
typeSuffix = `: ${valueType}`;
|
|
2402
|
+
}
|
|
2403
|
+
console.log(` ${CYAN}${s.name}${RESET}${DIM}${typeSuffix}${RESET}`);
|
|
2404
|
+
const summary = firstSentence(s.docs);
|
|
2405
|
+
if (summary) {
|
|
2406
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2407
|
+
}
|
|
1573
2408
|
}
|
|
1574
2409
|
console.log();
|
|
1575
2410
|
}
|
|
1576
2411
|
if (pallet2.constants.length) {
|
|
1577
2412
|
console.log(` ${BOLD}Constants:${RESET}`);
|
|
1578
2413
|
for (const c of pallet2.constants) {
|
|
1579
|
-
const
|
|
1580
|
-
console.log(` ${CYAN}${c.name}${RESET}${DIM}${
|
|
2414
|
+
const typeStr = describeType(meta.lookup, c.typeId);
|
|
2415
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}: ${typeStr}${RESET}`);
|
|
2416
|
+
const summary = firstSentence(c.docs);
|
|
2417
|
+
if (summary) {
|
|
2418
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2419
|
+
}
|
|
1581
2420
|
}
|
|
1582
2421
|
console.log();
|
|
1583
2422
|
}
|
|
1584
2423
|
if (pallet2.calls.length) {
|
|
1585
2424
|
console.log(` ${BOLD}Calls:${RESET}`);
|
|
1586
2425
|
for (const c of pallet2.calls) {
|
|
1587
|
-
const
|
|
1588
|
-
console.log(` ${CYAN}${c.name}${RESET}${DIM}${
|
|
2426
|
+
const args = describeCallArgs(meta, pallet2.name, c.name);
|
|
2427
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}${args}${RESET}`);
|
|
2428
|
+
const summary = firstSentence(c.docs);
|
|
2429
|
+
if (summary) {
|
|
2430
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2431
|
+
}
|
|
2432
|
+
}
|
|
2433
|
+
console.log();
|
|
2434
|
+
}
|
|
2435
|
+
if (pallet2.events.length) {
|
|
2436
|
+
console.log(` ${BOLD}Events:${RESET}`);
|
|
2437
|
+
for (const e of pallet2.events) {
|
|
2438
|
+
const fields = describeEventFields(meta, pallet2.name, e.name);
|
|
2439
|
+
console.log(` ${CYAN}${e.name}${RESET}${DIM}${fields}${RESET}`);
|
|
2440
|
+
const summary = firstSentence(e.docs);
|
|
2441
|
+
if (summary) {
|
|
2442
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
console.log();
|
|
2446
|
+
}
|
|
2447
|
+
if (pallet2.errors.length) {
|
|
2448
|
+
console.log(` ${BOLD}Errors:${RESET}`);
|
|
2449
|
+
for (const e of pallet2.errors) {
|
|
2450
|
+
console.log(` ${CYAN}${e.name}${RESET}`);
|
|
2451
|
+
const summary = firstSentence(e.docs);
|
|
2452
|
+
if (summary) {
|
|
2453
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2454
|
+
}
|
|
1589
2455
|
}
|
|
1590
2456
|
console.log();
|
|
1591
2457
|
}
|
|
@@ -1634,10 +2500,33 @@ function registerInspectCommand(cli) {
|
|
|
1634
2500
|
console.log();
|
|
1635
2501
|
return;
|
|
1636
2502
|
}
|
|
2503
|
+
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
2504
|
+
if (eventItem) {
|
|
2505
|
+
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
2506
|
+
const fields = describeEventFields(meta, pallet.name, eventItem.name);
|
|
2507
|
+
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
2508
|
+
if (eventItem.docs.length) {
|
|
2509
|
+
console.log();
|
|
2510
|
+
printDocs(eventItem.docs);
|
|
2511
|
+
}
|
|
2512
|
+
console.log();
|
|
2513
|
+
return;
|
|
2514
|
+
}
|
|
2515
|
+
const errorItem = pallet.errors.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
2516
|
+
if (errorItem) {
|
|
2517
|
+
printHeading(`${pallet.name}.${errorItem.name} (Error)`);
|
|
2518
|
+
if (errorItem.docs.length) {
|
|
2519
|
+
printDocs(errorItem.docs);
|
|
2520
|
+
}
|
|
2521
|
+
console.log();
|
|
2522
|
+
return;
|
|
2523
|
+
}
|
|
1637
2524
|
const allItems = [
|
|
1638
2525
|
...pallet.storage.map((s) => s.name),
|
|
1639
2526
|
...pallet.constants.map((c) => c.name),
|
|
1640
|
-
...pallet.calls.map((c) => c.name)
|
|
2527
|
+
...pallet.calls.map((c) => c.name),
|
|
2528
|
+
...pallet.events.map((e) => e.name),
|
|
2529
|
+
...pallet.errors.map((e) => e.name)
|
|
1641
2530
|
];
|
|
1642
2531
|
throw new Error(suggestMessage(`item in ${pallet.name}`, itemName, allItems));
|
|
1643
2532
|
});
|
|
@@ -1964,77 +2853,101 @@ var PAPI_BUILTIN_EXTENSIONS = new Set([
|
|
|
1964
2853
|
var NO_DEFAULT = Symbol("no-default");
|
|
1965
2854
|
|
|
1966
2855
|
// src/commands/query.ts
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
2856
|
+
async function handleQuery(target, keys, opts) {
|
|
2857
|
+
if (!target) {
|
|
2858
|
+
const config2 = await loadConfig();
|
|
2859
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
2860
|
+
const meta = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
2861
|
+
const pallets = listPallets(meta);
|
|
2862
|
+
const withStorage = pallets.filter((p) => p.storage.length > 0);
|
|
2863
|
+
printHeading(`Pallets with storage on ${chainName2} (${withStorage.length})`);
|
|
2864
|
+
for (const p of withStorage) {
|
|
2865
|
+
printItem(p.name, `${p.storage.length} storage items`);
|
|
2866
|
+
}
|
|
2867
|
+
console.log();
|
|
2868
|
+
return;
|
|
2869
|
+
}
|
|
2870
|
+
const dotIdx = target.indexOf(".");
|
|
2871
|
+
if (dotIdx === -1) {
|
|
2872
|
+
const config2 = await loadConfig();
|
|
2873
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
2874
|
+
const meta = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
2875
|
+
const pallet2 = resolvePallet(meta, palletName(target));
|
|
2876
|
+
if (pallet2.storage.length === 0) {
|
|
2877
|
+
console.log(`No storage items in ${pallet2.name}.`);
|
|
1983
2878
|
return;
|
|
1984
2879
|
}
|
|
1985
|
-
|
|
1986
|
-
const
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
const meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
1995
|
-
const palletNames = getPalletNames(meta);
|
|
1996
|
-
const palletInfo = findPallet(meta, pallet);
|
|
1997
|
-
if (!palletInfo) {
|
|
1998
|
-
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
2880
|
+
printHeading(`${pallet2.name} Storage`);
|
|
2881
|
+
for (const s of pallet2.storage) {
|
|
2882
|
+
const valueType = describeType(meta.lookup, s.valueTypeId);
|
|
2883
|
+
let typeSuffix;
|
|
2884
|
+
if (s.keyTypeId != null) {
|
|
2885
|
+
const keyType = describeType(meta.lookup, s.keyTypeId);
|
|
2886
|
+
typeSuffix = `: ${keyType} → ${valueType} [map]`;
|
|
2887
|
+
} else {
|
|
2888
|
+
typeSuffix = `: ${valueType}`;
|
|
1999
2889
|
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
}
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2890
|
+
console.log(` ${CYAN}${s.name}${RESET}${DIM}${typeSuffix}${RESET}`);
|
|
2891
|
+
const summary = firstSentence(s.docs);
|
|
2892
|
+
if (summary) {
|
|
2893
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
console.log();
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
const pallet = target.slice(0, dotIdx);
|
|
2900
|
+
const item = target.slice(dotIdx + 1);
|
|
2901
|
+
const config = await loadConfig();
|
|
2902
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
2903
|
+
const clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
2904
|
+
try {
|
|
2905
|
+
const meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
2906
|
+
const palletNames = getPalletNames(meta);
|
|
2907
|
+
const palletInfo = findPallet(meta, pallet);
|
|
2908
|
+
if (!palletInfo) {
|
|
2909
|
+
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
2910
|
+
}
|
|
2911
|
+
const storageItem = palletInfo.storage.find((s) => s.name.toLowerCase() === item.toLowerCase());
|
|
2912
|
+
if (!storageItem) {
|
|
2913
|
+
const storageNames = palletInfo.storage.map((s) => s.name);
|
|
2914
|
+
throw new Error(suggestMessage(`storage item in ${palletInfo.name}`, item, storageNames));
|
|
2915
|
+
}
|
|
2916
|
+
const unsafeApi = clientHandle.client.getUnsafeApi();
|
|
2917
|
+
const storageApi = unsafeApi.query[palletInfo.name][storageItem.name];
|
|
2918
|
+
const parsedKeys = parseStorageKeys(meta, palletInfo.name, storageItem, keys);
|
|
2919
|
+
const format = opts.output ?? "pretty";
|
|
2920
|
+
if (storageItem.type === "map" && parsedKeys.length === 0) {
|
|
2921
|
+
const entries = await storageApi.getEntries();
|
|
2922
|
+
const limit = Number(opts.limit);
|
|
2923
|
+
const truncated = limit > 0 && entries.length > limit;
|
|
2924
|
+
const display = truncated ? entries.slice(0, limit) : entries;
|
|
2925
|
+
printResult(display.map((e) => ({
|
|
2926
|
+
keys: e.keyArgs,
|
|
2927
|
+
value: e.value
|
|
2928
|
+
})), format);
|
|
2929
|
+
if (truncated) {
|
|
2930
|
+
console.error(`
|
|
2020
2931
|
${DIM}Showing ${limit} of ${entries.length} entries. Use --limit 0 for all.${RESET}`);
|
|
2021
|
-
}
|
|
2022
|
-
} else {
|
|
2023
|
-
const result = await storageApi.getValue(...parsedKeys);
|
|
2024
|
-
printResult(result, format);
|
|
2025
2932
|
}
|
|
2026
|
-
}
|
|
2027
|
-
|
|
2933
|
+
} else {
|
|
2934
|
+
const result = await storageApi.getValue(...parsedKeys);
|
|
2935
|
+
printResult(result, format);
|
|
2028
2936
|
}
|
|
2029
|
-
}
|
|
2937
|
+
} finally {
|
|
2938
|
+
clientHandle.destroy();
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
function palletName(name) {
|
|
2942
|
+
return name;
|
|
2030
2943
|
}
|
|
2031
|
-
function parseStorageKeys(meta,
|
|
2944
|
+
function parseStorageKeys(meta, palletName2, storageItem, args) {
|
|
2032
2945
|
if (storageItem.type === "plain" || storageItem.keyTypeId == null) {
|
|
2033
2946
|
return args.map(parseValue);
|
|
2034
2947
|
}
|
|
2035
2948
|
if (args.length === 0)
|
|
2036
2949
|
return [];
|
|
2037
|
-
const storageEntry = meta.builder.buildStorage(
|
|
2950
|
+
const storageEntry = meta.builder.buildStorage(palletName2, storageItem.name);
|
|
2038
2951
|
const len = storageEntry.len;
|
|
2039
2952
|
const keyEntry = meta.lookup(storageItem.keyTypeId);
|
|
2040
2953
|
if (len === 1) {
|
|
@@ -2042,11 +2955,11 @@ function parseStorageKeys(meta, palletName, storageItem, args) {
|
|
|
2042
2955
|
return [parseTypedArg(meta, keyEntry, args[0])];
|
|
2043
2956
|
}
|
|
2044
2957
|
if (keyEntry.type === "struct") {
|
|
2045
|
-
const label = `${
|
|
2958
|
+
const label = `${palletName2}.${storageItem.name} key`;
|
|
2046
2959
|
return [parseStructArgs(meta, keyEntry.value, args, label)];
|
|
2047
2960
|
}
|
|
2048
2961
|
const typeDesc = describeType(meta.lookup, storageItem.keyTypeId);
|
|
2049
|
-
throw new Error(`${
|
|
2962
|
+
throw new Error(`${palletName2}.${storageItem.name} key expects ${typeDesc}
|
|
2050
2963
|
` + ` Pass 1 argument. Got ${args.length}.`);
|
|
2051
2964
|
}
|
|
2052
2965
|
if (args.length !== len) {
|
|
@@ -2056,7 +2969,7 @@ function parseStorageKeys(meta, palletName, storageItem, args) {
|
|
|
2056
2969
|
} else {
|
|
2057
2970
|
typeDesc = describeType(meta.lookup, storageItem.keyTypeId);
|
|
2058
2971
|
}
|
|
2059
|
-
throw new Error(`${
|
|
2972
|
+
throw new Error(`${palletName2}.${storageItem.name} expects ${len} key arg(s): (${typeDesc}). Got ${args.length}.`);
|
|
2060
2973
|
}
|
|
2061
2974
|
if (keyEntry.type === "tuple") {
|
|
2062
2975
|
const entries = keyEntry.value;
|
|
@@ -2068,156 +2981,180 @@ function parseStorageKeys(meta, palletName, storageItem, args) {
|
|
|
2068
2981
|
// src/commands/tx.ts
|
|
2069
2982
|
import { getViewBuilder as getViewBuilder2 } from "@polkadot-api/view-builder";
|
|
2070
2983
|
import { Binary as Binary3 } from "polkadot-api";
|
|
2071
|
-
function
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
console.log(" $ dot tx kusama.Balances.transferKeepAlive 5FHn... 1000000000000 --from alice");
|
|
2082
|
-
return;
|
|
2984
|
+
async function handleTx(target, args, opts) {
|
|
2985
|
+
if (!target) {
|
|
2986
|
+
const config2 = await loadConfig();
|
|
2987
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
2988
|
+
const meta = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
2989
|
+
const pallets = listPallets(meta);
|
|
2990
|
+
const withCalls = pallets.filter((p) => p.calls.length > 0);
|
|
2991
|
+
printHeading(`Pallets with calls on ${chainName2} (${withCalls.length})`);
|
|
2992
|
+
for (const p of withCalls) {
|
|
2993
|
+
printItem(p.name, `${p.calls.length} calls`);
|
|
2083
2994
|
}
|
|
2084
|
-
|
|
2085
|
-
|
|
2995
|
+
console.log();
|
|
2996
|
+
return;
|
|
2997
|
+
}
|
|
2998
|
+
const isRawCall = /^0x[0-9a-fA-F]+$/.test(target);
|
|
2999
|
+
if (!isRawCall && target.indexOf(".") === -1) {
|
|
3000
|
+
const config2 = await loadConfig();
|
|
3001
|
+
const { name: chainName2, chain: chainConfig2 } = resolveChain(config2, opts.chain);
|
|
3002
|
+
const meta = await loadMeta(chainName2, chainConfig2, opts.rpc);
|
|
3003
|
+
const pallet2 = resolvePallet(meta, target);
|
|
3004
|
+
if (pallet2.calls.length === 0) {
|
|
3005
|
+
console.log(`No calls in ${pallet2.name}.`);
|
|
3006
|
+
return;
|
|
2086
3007
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
3008
|
+
printHeading(`${pallet2.name} Calls`);
|
|
3009
|
+
for (const c of pallet2.calls) {
|
|
3010
|
+
const callArgs = describeCallArgs(meta, pallet2.name, c.name);
|
|
3011
|
+
console.log(` ${CYAN}${c.name}${RESET}${DIM}${callArgs}${RESET}`);
|
|
3012
|
+
const summary = firstSentence(c.docs);
|
|
3013
|
+
if (summary) {
|
|
3014
|
+
console.log(` ${DIM}${summary}${RESET}`);
|
|
3015
|
+
}
|
|
2089
3016
|
}
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
3017
|
+
console.log();
|
|
3018
|
+
return;
|
|
3019
|
+
}
|
|
3020
|
+
if (!opts.from && !opts.encode) {
|
|
3021
|
+
if (isRawCall) {
|
|
3022
|
+
throw new Error("--from is required (or use --encode to output hex without signing)");
|
|
2093
3023
|
}
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
3024
|
+
await showItemHelp("tx", target, opts);
|
|
3025
|
+
return;
|
|
3026
|
+
}
|
|
3027
|
+
if (opts.encode && opts.dryRun) {
|
|
3028
|
+
throw new Error("--encode and --dry-run are mutually exclusive");
|
|
3029
|
+
}
|
|
3030
|
+
if (opts.encode && isRawCall) {
|
|
3031
|
+
throw new Error("--encode cannot be used with raw call hex (already encoded)");
|
|
3032
|
+
}
|
|
3033
|
+
const config = await loadConfig();
|
|
3034
|
+
const effectiveChain = opts.chain;
|
|
3035
|
+
let pallet;
|
|
3036
|
+
let callName;
|
|
3037
|
+
if (!isRawCall) {
|
|
3038
|
+
const dotIdx = target.indexOf(".");
|
|
3039
|
+
pallet = target.slice(0, dotIdx);
|
|
3040
|
+
callName = target.slice(dotIdx + 1);
|
|
3041
|
+
}
|
|
3042
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, effectiveChain);
|
|
3043
|
+
const signer = opts.encode ? undefined : await resolveAccountSigner(opts.from);
|
|
3044
|
+
let clientHandle;
|
|
3045
|
+
if (!opts.encode) {
|
|
3046
|
+
clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
3047
|
+
}
|
|
3048
|
+
try {
|
|
3049
|
+
let meta;
|
|
3050
|
+
if (clientHandle) {
|
|
3051
|
+
meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
3052
|
+
} else {
|
|
3053
|
+
try {
|
|
3054
|
+
meta = await getOrFetchMetadata(chainName);
|
|
3055
|
+
} catch {
|
|
3056
|
+
clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
3057
|
+
meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
3058
|
+
}
|
|
2101
3059
|
}
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
let clientHandle;
|
|
3060
|
+
let unsafeApi;
|
|
3061
|
+
let txOptions;
|
|
2105
3062
|
if (!opts.encode) {
|
|
2106
|
-
|
|
3063
|
+
const userExtOverrides = parseExtOption(opts.ext);
|
|
3064
|
+
const customSignedExtensions = buildCustomSignedExtensions(meta, userExtOverrides);
|
|
3065
|
+
txOptions = Object.keys(customSignedExtensions).length > 0 ? { customSignedExtensions } : undefined;
|
|
3066
|
+
unsafeApi = clientHandle?.client.getUnsafeApi();
|
|
2107
3067
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
try {
|
|
2114
|
-
meta = await getOrFetchMetadata(chainName);
|
|
2115
|
-
} catch {
|
|
2116
|
-
clientHandle = await createChainClient(chainName, chainConfig, opts.rpc);
|
|
2117
|
-
meta = await getOrFetchMetadata(chainName, clientHandle);
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
let unsafeApi;
|
|
2121
|
-
let txOptions;
|
|
2122
|
-
if (!opts.encode) {
|
|
2123
|
-
const userExtOverrides = parseExtOption(opts.ext);
|
|
2124
|
-
const customSignedExtensions = buildCustomSignedExtensions(meta, userExtOverrides);
|
|
2125
|
-
txOptions = Object.keys(customSignedExtensions).length > 0 ? { customSignedExtensions } : undefined;
|
|
2126
|
-
unsafeApi = clientHandle?.client.getUnsafeApi();
|
|
2127
|
-
}
|
|
2128
|
-
let tx;
|
|
2129
|
-
let callHex;
|
|
2130
|
-
if (isRawCall) {
|
|
2131
|
-
if (args.length > 0) {
|
|
2132
|
-
throw new Error(`Extra arguments are not allowed when submitting a raw call hex.
|
|
3068
|
+
let tx;
|
|
3069
|
+
let callHex;
|
|
3070
|
+
if (isRawCall) {
|
|
3071
|
+
if (args.length > 0) {
|
|
3072
|
+
throw new Error(`Extra arguments are not allowed when submitting a raw call hex.
|
|
2133
3073
|
` + "Usage: dot tx 0x<call_hex> --from <account>");
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
const
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
const fullCall = new Uint8Array([location[0], location[1], ...encodedArgs]);
|
|
2156
|
-
console.log(Binary3.fromBytes(fullCall).asHex());
|
|
2157
|
-
return;
|
|
2158
|
-
}
|
|
2159
|
-
tx = unsafeApi.tx[palletInfo.name][callInfo.name](callData);
|
|
2160
|
-
const encodedCall = await tx.getEncodedData();
|
|
2161
|
-
callHex = encodedCall.asHex();
|
|
2162
|
-
}
|
|
2163
|
-
const decodedStr = decodeCall(meta, callHex);
|
|
2164
|
-
if (opts.dryRun) {
|
|
2165
|
-
const signerAddress = toSs58(signer.publicKey);
|
|
2166
|
-
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
2167
|
-
console.log(` ${BOLD}From:${RESET} ${opts.from} (${signerAddress})`);
|
|
2168
|
-
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
2169
|
-
console.log(` ${BOLD}Decode:${RESET} ${decodedStr}`);
|
|
2170
|
-
try {
|
|
2171
|
-
const fees = await tx.getEstimatedFees(signer?.publicKey, txOptions);
|
|
2172
|
-
console.log(` ${BOLD}Estimated fees:${RESET} ${fees}`);
|
|
2173
|
-
} catch (err) {
|
|
2174
|
-
console.log(` ${BOLD}Estimated fees:${RESET} ${YELLOW}unable to estimate${RESET}`);
|
|
2175
|
-
console.log(` ${DIM}${err.message ?? err}${RESET}`);
|
|
2176
|
-
}
|
|
3074
|
+
}
|
|
3075
|
+
const callBinary = Binary3.fromHex(target);
|
|
3076
|
+
tx = await unsafeApi.txFromCallData(callBinary);
|
|
3077
|
+
callHex = target;
|
|
3078
|
+
} else {
|
|
3079
|
+
const palletNames = getPalletNames(meta);
|
|
3080
|
+
const palletInfo = findPallet(meta, pallet);
|
|
3081
|
+
if (!palletInfo) {
|
|
3082
|
+
throw new Error(suggestMessage("pallet", pallet, palletNames));
|
|
3083
|
+
}
|
|
3084
|
+
const callInfo = palletInfo.calls.find((c) => c.name.toLowerCase() === callName.toLowerCase());
|
|
3085
|
+
if (!callInfo) {
|
|
3086
|
+
const callNames = palletInfo.calls.map((c) => c.name);
|
|
3087
|
+
throw new Error(suggestMessage(`call in ${palletInfo.name}`, callName, callNames));
|
|
3088
|
+
}
|
|
3089
|
+
const callData = parseCallArgs(meta, palletInfo.name, callInfo.name, args);
|
|
3090
|
+
if (opts.encode) {
|
|
3091
|
+
const { codec, location } = meta.builder.buildCall(palletInfo.name, callInfo.name);
|
|
3092
|
+
const encodedArgs = codec.enc(callData);
|
|
3093
|
+
const fullCall = new Uint8Array([location[0], location[1], ...encodedArgs]);
|
|
3094
|
+
console.log(Binary3.fromBytes(fullCall).asHex());
|
|
2177
3095
|
return;
|
|
2178
3096
|
}
|
|
2179
|
-
|
|
2180
|
-
|
|
3097
|
+
tx = unsafeApi.tx[palletInfo.name][callInfo.name](callData);
|
|
3098
|
+
const encodedCall = await tx.getEncodedData();
|
|
3099
|
+
callHex = encodedCall.asHex();
|
|
3100
|
+
}
|
|
3101
|
+
const decodedStr = decodeCall(meta, callHex);
|
|
3102
|
+
if (opts.dryRun) {
|
|
3103
|
+
const signerAddress = toSs58(signer.publicKey);
|
|
2181
3104
|
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
3105
|
+
console.log(` ${BOLD}From:${RESET} ${opts.from} (${signerAddress})`);
|
|
2182
3106
|
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
2183
3107
|
console.log(` ${BOLD}Decode:${RESET} ${decodedStr}`);
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
console.log(` ${BOLD}Status:${RESET} ${RED}dispatch error${RESET}`);
|
|
2191
|
-
console.log(` ${BOLD}Error:${RESET} ${dispatchErrorMsg}`);
|
|
3108
|
+
try {
|
|
3109
|
+
const fees = await tx.getEstimatedFees(signer?.publicKey, txOptions);
|
|
3110
|
+
console.log(` ${BOLD}Estimated fees:${RESET} ${fees}`);
|
|
3111
|
+
} catch (err) {
|
|
3112
|
+
console.log(` ${BOLD}Estimated fees:${RESET} ${YELLOW}unable to estimate${RESET}`);
|
|
3113
|
+
console.log(` ${DIM}${err.message ?? err}${RESET}`);
|
|
2192
3114
|
}
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
3115
|
+
return;
|
|
3116
|
+
}
|
|
3117
|
+
const result = await watchTransaction(tx.signSubmitAndWatch(signer, txOptions));
|
|
3118
|
+
console.log();
|
|
3119
|
+
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
3120
|
+
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
3121
|
+
console.log(` ${BOLD}Decode:${RESET} ${decodedStr}`);
|
|
3122
|
+
console.log(` ${BOLD}Tx:${RESET} ${result.txHash}`);
|
|
3123
|
+
let dispatchErrorMsg;
|
|
3124
|
+
if (result.ok) {
|
|
3125
|
+
console.log(` ${BOLD}Status:${RESET} ${GREEN}ok${RESET}`);
|
|
3126
|
+
} else {
|
|
3127
|
+
dispatchErrorMsg = formatDispatchError(result.dispatchError);
|
|
3128
|
+
console.log(` ${BOLD}Status:${RESET} ${RED}dispatch error${RESET}`);
|
|
3129
|
+
console.log(` ${BOLD}Error:${RESET} ${dispatchErrorMsg}`);
|
|
3130
|
+
}
|
|
3131
|
+
if (result.events && result.events.length > 0) {
|
|
3132
|
+
console.log(` ${BOLD}Events:${RESET}`);
|
|
3133
|
+
for (const event of result.events) {
|
|
3134
|
+
const name = `${CYAN}${event.type}${RESET}.${CYAN}${event.value?.type ?? ""}${RESET}`;
|
|
3135
|
+
const payload = event.value?.value;
|
|
3136
|
+
if (payload && typeof payload === "object") {
|
|
3137
|
+
const fields = Object.entries(payload).map(([k, v]) => `${k}: ${formatEventValue(v)}`).join(", ");
|
|
3138
|
+
console.log(` ${name} { ${fields} }`);
|
|
3139
|
+
} else {
|
|
3140
|
+
console.log(` ${name}`);
|
|
2204
3141
|
}
|
|
2205
3142
|
}
|
|
2206
|
-
const rpcUrl = primaryRpc(opts.rpc ?? chainConfig.rpc);
|
|
2207
|
-
if (rpcUrl) {
|
|
2208
|
-
const blockHash = result.block.hash;
|
|
2209
|
-
console.log(` ${BOLD}Explorer:${RESET}`);
|
|
2210
|
-
console.log(` ${DIM}PolkadotJS${RESET} ${pjsAppsLink(rpcUrl, blockHash)}`);
|
|
2211
|
-
console.log(` ${DIM}PAPI${RESET} ${papiLink(rpcUrl, blockHash)}`);
|
|
2212
|
-
}
|
|
2213
|
-
console.log();
|
|
2214
|
-
if (!result.ok) {
|
|
2215
|
-
throw new CliError(`Transaction dispatch error: ${dispatchErrorMsg}`);
|
|
2216
|
-
}
|
|
2217
|
-
} finally {
|
|
2218
|
-
clientHandle?.destroy();
|
|
2219
3143
|
}
|
|
2220
|
-
|
|
3144
|
+
const rpcUrl = primaryRpc(opts.rpc ?? chainConfig.rpc);
|
|
3145
|
+
if (rpcUrl) {
|
|
3146
|
+
const blockHash = result.block.hash;
|
|
3147
|
+
console.log(` ${BOLD}Explorer:${RESET}`);
|
|
3148
|
+
console.log(` ${DIM}PolkadotJS${RESET} ${pjsAppsLink(rpcUrl, blockHash)}`);
|
|
3149
|
+
console.log(` ${DIM}PAPI${RESET} ${papiLink(rpcUrl, blockHash)}`);
|
|
3150
|
+
}
|
|
3151
|
+
console.log();
|
|
3152
|
+
if (!result.ok) {
|
|
3153
|
+
throw new CliError(`Transaction dispatch error: ${dispatchErrorMsg}`);
|
|
3154
|
+
}
|
|
3155
|
+
} finally {
|
|
3156
|
+
clientHandle?.destroy();
|
|
3157
|
+
}
|
|
2221
3158
|
}
|
|
2222
3159
|
function formatDispatchError(err) {
|
|
2223
3160
|
if (err.type === "Module" && err.value && typeof err.value === "object") {
|
|
@@ -2240,10 +3177,10 @@ function decodeCall(meta, callHex) {
|
|
|
2240
3177
|
try {
|
|
2241
3178
|
const viewBuilder = getViewBuilder2(meta.lookup);
|
|
2242
3179
|
const decoded = viewBuilder.callDecoder(callHex);
|
|
2243
|
-
const
|
|
3180
|
+
const palletName2 = decoded.pallet.value.name;
|
|
2244
3181
|
const callName = decoded.call.value.name;
|
|
2245
3182
|
const argsStr = formatDecodedArgs(decoded.args.value);
|
|
2246
|
-
return `${
|
|
3183
|
+
return `${palletName2}.${callName}${argsStr}`;
|
|
2247
3184
|
} catch {}
|
|
2248
3185
|
try {
|
|
2249
3186
|
return decodeCallFallback(meta, callHex);
|
|
@@ -2257,15 +3194,15 @@ function decodeCallFallback(meta, callHex) {
|
|
|
2257
3194
|
throw new Error("No RuntimeCall type ID");
|
|
2258
3195
|
const codec = meta.builder.buildDefinition(callTypeId);
|
|
2259
3196
|
const decoded = codec.dec(Binary3.fromHex(callHex).asBytes());
|
|
2260
|
-
const
|
|
3197
|
+
const palletName2 = decoded.type;
|
|
2261
3198
|
const call = decoded.value;
|
|
2262
3199
|
const callName = call.type;
|
|
2263
3200
|
const args = call.value;
|
|
2264
3201
|
if (args === undefined || args === null) {
|
|
2265
|
-
return `${
|
|
3202
|
+
return `${palletName2}.${callName}`;
|
|
2266
3203
|
}
|
|
2267
3204
|
const argsStr = formatRawDecoded(args);
|
|
2268
|
-
return `${
|
|
3205
|
+
return `${palletName2}.${callName} ${argsStr}`;
|
|
2269
3206
|
}
|
|
2270
3207
|
function formatRawDecoded(value) {
|
|
2271
3208
|
if (value === undefined || value === null)
|
|
@@ -2398,8 +3335,8 @@ function formatEventValue(v) {
|
|
|
2398
3335
|
}
|
|
2399
3336
|
return JSON.stringify(v, (_k, val) => typeof val === "bigint" ? val.toString() : val);
|
|
2400
3337
|
}
|
|
2401
|
-
function parseCallArgs(meta,
|
|
2402
|
-
const palletMeta = meta.unified.pallets.find((p) => p.name ===
|
|
3338
|
+
function parseCallArgs(meta, palletName2, callName, args) {
|
|
3339
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName2);
|
|
2403
3340
|
if (!palletMeta?.calls)
|
|
2404
3341
|
return;
|
|
2405
3342
|
const callsEntry = meta.lookup(palletMeta.calls.type);
|
|
@@ -2410,22 +3347,22 @@ function parseCallArgs(meta, palletName, callName, args) {
|
|
|
2410
3347
|
return;
|
|
2411
3348
|
if (variant.type === "void") {
|
|
2412
3349
|
if (args.length > 0) {
|
|
2413
|
-
throw new Error(`${
|
|
3350
|
+
throw new Error(`${palletName2}.${callName} takes no arguments, but ${args.length} provided.`);
|
|
2414
3351
|
}
|
|
2415
3352
|
return;
|
|
2416
3353
|
}
|
|
2417
3354
|
if (variant.type === "struct") {
|
|
2418
|
-
return parseStructArgs2(meta, variant.value, args, `${
|
|
3355
|
+
return parseStructArgs2(meta, variant.value, args, `${palletName2}.${callName}`);
|
|
2419
3356
|
}
|
|
2420
3357
|
if (variant.type === "lookupEntry") {
|
|
2421
3358
|
const inner = variant.value;
|
|
2422
3359
|
if (inner.type === "struct") {
|
|
2423
|
-
return parseStructArgs2(meta, inner.value, args, `${
|
|
3360
|
+
return parseStructArgs2(meta, inner.value, args, `${palletName2}.${callName}`);
|
|
2424
3361
|
}
|
|
2425
3362
|
if (inner.type === "void")
|
|
2426
3363
|
return;
|
|
2427
3364
|
if (args.length !== 1) {
|
|
2428
|
-
throw new Error(`${
|
|
3365
|
+
throw new Error(`${palletName2}.${callName} takes 1 argument (${describeType(meta.lookup, inner.id)}), but ${args.length} provided.`);
|
|
2429
3366
|
}
|
|
2430
3367
|
try {
|
|
2431
3368
|
return parseTypedArg2(meta, inner, args[0]);
|
|
@@ -2437,7 +3374,7 @@ function parseCallArgs(meta, palletName, callName, args) {
|
|
|
2437
3374
|
if (variant.type === "tuple") {
|
|
2438
3375
|
const entries = variant.value;
|
|
2439
3376
|
if (args.length !== entries.length) {
|
|
2440
|
-
throw new Error(`${
|
|
3377
|
+
throw new Error(`${palletName2}.${callName} takes ${entries.length} arguments, but ${args.length} provided.`);
|
|
2441
3378
|
}
|
|
2442
3379
|
return entries.map((entry, i) => {
|
|
2443
3380
|
try {
|
|
@@ -2830,10 +3767,46 @@ function watchTransaction(observable) {
|
|
|
2830
3767
|
});
|
|
2831
3768
|
}
|
|
2832
3769
|
|
|
3770
|
+
// src/config/store.ts
|
|
3771
|
+
import { access as access3, mkdir as mkdir3, readFile as readFile3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
3772
|
+
import { homedir as homedir2 } from "node:os";
|
|
3773
|
+
import { join as join3 } from "node:path";
|
|
3774
|
+
var DOT_DIR2 = join3(homedir2(), ".polkadot");
|
|
3775
|
+
var CONFIG_PATH2 = join3(DOT_DIR2, "config.json");
|
|
3776
|
+
var CHAINS_DIR2 = join3(DOT_DIR2, "chains");
|
|
3777
|
+
async function ensureDir3(dir) {
|
|
3778
|
+
await mkdir3(dir, { recursive: true });
|
|
3779
|
+
}
|
|
3780
|
+
async function fileExists3(path) {
|
|
3781
|
+
try {
|
|
3782
|
+
await access3(path);
|
|
3783
|
+
return true;
|
|
3784
|
+
} catch {
|
|
3785
|
+
return false;
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
async function loadConfig2() {
|
|
3789
|
+
await ensureDir3(DOT_DIR2);
|
|
3790
|
+
if (await fileExists3(CONFIG_PATH2)) {
|
|
3791
|
+
const saved = JSON.parse(await readFile3(CONFIG_PATH2, "utf-8"));
|
|
3792
|
+
return {
|
|
3793
|
+
...saved,
|
|
3794
|
+
chains: { ...DEFAULT_CONFIG.chains, ...saved.chains }
|
|
3795
|
+
};
|
|
3796
|
+
}
|
|
3797
|
+
await saveConfig2(DEFAULT_CONFIG);
|
|
3798
|
+
return DEFAULT_CONFIG;
|
|
3799
|
+
}
|
|
3800
|
+
async function saveConfig2(config) {
|
|
3801
|
+
await ensureDir3(DOT_DIR2);
|
|
3802
|
+
await writeFile3(CONFIG_PATH2, `${JSON.stringify(config, null, 2)}
|
|
3803
|
+
`);
|
|
3804
|
+
}
|
|
3805
|
+
|
|
2833
3806
|
// src/core/update-notifier.ts
|
|
2834
3807
|
import { readFileSync } from "node:fs";
|
|
2835
|
-
import { mkdir as
|
|
2836
|
-
import { join as
|
|
3808
|
+
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
3809
|
+
import { join as join4 } from "node:path";
|
|
2837
3810
|
var CACHE_FILE = "update-check.json";
|
|
2838
3811
|
var STALE_MS = 24 * 60 * 60 * 1000;
|
|
2839
3812
|
var FETCH_TIMEOUT_MS = 5000;
|
|
@@ -2889,7 +3862,7 @@ function buildNotificationBox(current, latest) {
|
|
|
2889
3862
|
`);
|
|
2890
3863
|
}
|
|
2891
3864
|
function getCachePath() {
|
|
2892
|
-
return
|
|
3865
|
+
return join4(getConfigDir(), CACHE_FILE);
|
|
2893
3866
|
}
|
|
2894
3867
|
function readCache() {
|
|
2895
3868
|
try {
|
|
@@ -2901,8 +3874,8 @@ function readCache() {
|
|
|
2901
3874
|
}
|
|
2902
3875
|
async function writeCache(cache) {
|
|
2903
3876
|
try {
|
|
2904
|
-
await
|
|
2905
|
-
await
|
|
3877
|
+
await mkdir4(getConfigDir(), { recursive: true });
|
|
3878
|
+
await writeFile4(getCachePath(), `${JSON.stringify(cache)}
|
|
2906
3879
|
`);
|
|
2907
3880
|
} catch {}
|
|
2908
3881
|
}
|
|
@@ -2957,6 +3930,67 @@ class CliError2 extends Error {
|
|
|
2957
3930
|
}
|
|
2958
3931
|
}
|
|
2959
3932
|
|
|
3933
|
+
// src/utils/parse-dot-path.ts
|
|
3934
|
+
var CATEGORY_ALIASES = {
|
|
3935
|
+
query: "query",
|
|
3936
|
+
tx: "tx",
|
|
3937
|
+
const: "const",
|
|
3938
|
+
consts: "const",
|
|
3939
|
+
constants: "const",
|
|
3940
|
+
events: "events",
|
|
3941
|
+
event: "events",
|
|
3942
|
+
errors: "errors",
|
|
3943
|
+
error: "errors"
|
|
3944
|
+
};
|
|
3945
|
+
function matchCategory(segment) {
|
|
3946
|
+
return CATEGORY_ALIASES[segment.toLowerCase()];
|
|
3947
|
+
}
|
|
3948
|
+
function matchChain(segment, knownChains) {
|
|
3949
|
+
return knownChains.some((c) => c.toLowerCase() === segment.toLowerCase());
|
|
3950
|
+
}
|
|
3951
|
+
function parseDotPath(input, knownChains = []) {
|
|
3952
|
+
const parts = input.split(".");
|
|
3953
|
+
switch (parts.length) {
|
|
3954
|
+
case 1: {
|
|
3955
|
+
const cat = matchCategory(parts[0]);
|
|
3956
|
+
if (cat)
|
|
3957
|
+
return { category: cat };
|
|
3958
|
+
throw new Error(`Unknown command "${parts[0]}". Expected a category (query, tx, const, events, errors) or a named command.`);
|
|
3959
|
+
}
|
|
3960
|
+
case 2: {
|
|
3961
|
+
const cat = matchCategory(parts[0]);
|
|
3962
|
+
if (cat) {
|
|
3963
|
+
return { category: cat, pallet: parts[1] };
|
|
3964
|
+
}
|
|
3965
|
+
const cat2 = matchCategory(parts[1]);
|
|
3966
|
+
if (cat2 && matchChain(parts[0], knownChains)) {
|
|
3967
|
+
return { chain: parts[0], category: cat2 };
|
|
3968
|
+
}
|
|
3969
|
+
throw new Error(`Unknown command "${input}". Expected format: category.Pallet or Chain.category (e.g. query.System or polkadot.query)`);
|
|
3970
|
+
}
|
|
3971
|
+
case 3: {
|
|
3972
|
+
const cat = matchCategory(parts[0]);
|
|
3973
|
+
if (cat) {
|
|
3974
|
+
return { category: cat, pallet: parts[1], item: parts[2] };
|
|
3975
|
+
}
|
|
3976
|
+
const cat2 = matchCategory(parts[1]);
|
|
3977
|
+
if (cat2 && matchChain(parts[0], knownChains)) {
|
|
3978
|
+
return { chain: parts[0], category: cat2, pallet: parts[2] };
|
|
3979
|
+
}
|
|
3980
|
+
throw new Error(`Unknown command "${input}". Expected format: category.Pallet.Item or Chain.category.Pallet`);
|
|
3981
|
+
}
|
|
3982
|
+
case 4: {
|
|
3983
|
+
const cat = matchCategory(parts[1]);
|
|
3984
|
+
if (cat && matchChain(parts[0], knownChains)) {
|
|
3985
|
+
return { chain: parts[0], category: cat, pallet: parts[2], item: parts[3] };
|
|
3986
|
+
}
|
|
3987
|
+
throw new Error(`Unknown command "${input}". Expected format: Chain.category.Pallet.Item (e.g. polkadot.query.System.Account)`);
|
|
3988
|
+
}
|
|
3989
|
+
default:
|
|
3990
|
+
throw new Error(`Unknown command "${input}". Too many segments. Expected format: [Chain.]category[.Pallet[.Item]]`);
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
|
|
2960
3994
|
// src/cli.ts
|
|
2961
3995
|
startBackgroundCheck(version);
|
|
2962
3996
|
var cli = cac("dot");
|
|
@@ -2968,13 +4002,105 @@ cli.option("--output <format>", "Output format: pretty or json", {
|
|
|
2968
4002
|
});
|
|
2969
4003
|
registerChainCommands(cli);
|
|
2970
4004
|
registerInspectCommand(cli);
|
|
2971
|
-
registerQueryCommand(cli);
|
|
2972
|
-
registerConstCommand(cli);
|
|
2973
4005
|
registerAccountCommands(cli);
|
|
2974
|
-
registerTxCommand(cli);
|
|
2975
4006
|
registerHashCommand(cli);
|
|
4007
|
+
cli.command("[dotpath] [...args]").option("--from <name>", "Account to sign with (for tx)").option("--dry-run", "Estimate fees without submitting (for tx)").option("--encode", "Encode call to hex without signing (for tx)").option("--ext <json>", "Custom signed extension values as JSON (for tx)").option("--limit <n>", "Max entries to return for map queries (0 = unlimited)", {
|
|
4008
|
+
default: 100
|
|
4009
|
+
}).action(async (dotpath, args, opts) => {
|
|
4010
|
+
if (!dotpath) {
|
|
4011
|
+
printHelp();
|
|
4012
|
+
return;
|
|
4013
|
+
}
|
|
4014
|
+
const config = await loadConfig2();
|
|
4015
|
+
const knownChains = Object.keys(config.chains);
|
|
4016
|
+
let parsed;
|
|
4017
|
+
try {
|
|
4018
|
+
parsed = parseDotPath(dotpath, knownChains);
|
|
4019
|
+
} catch {
|
|
4020
|
+
throw new CliError2(`Unknown command "${dotpath}". Run "dot --help" for available commands.`);
|
|
4021
|
+
}
|
|
4022
|
+
if (parsed.chain && opts.chain) {
|
|
4023
|
+
throw new CliError2(`Chain specified both as prefix ("${parsed.chain}") and as --chain flag ("${opts.chain}"). Use one or the other.`);
|
|
4024
|
+
}
|
|
4025
|
+
const effectiveChain = parsed.chain ?? opts.chain;
|
|
4026
|
+
const handlerOpts = { chain: effectiveChain, rpc: opts.rpc, output: opts.output };
|
|
4027
|
+
const target = parsed.pallet ? parsed.item ? `${parsed.pallet}.${parsed.item}` : parsed.pallet : undefined;
|
|
4028
|
+
if (cli.options.help && parsed.pallet && parsed.item) {
|
|
4029
|
+
await showItemHelp2(parsed.category, target, handlerOpts);
|
|
4030
|
+
return;
|
|
4031
|
+
}
|
|
4032
|
+
switch (parsed.category) {
|
|
4033
|
+
case "query":
|
|
4034
|
+
await handleQuery(target, args, { ...handlerOpts, limit: opts.limit });
|
|
4035
|
+
break;
|
|
4036
|
+
case "tx":
|
|
4037
|
+
if (parsed.pallet && /^0x[0-9a-fA-F]+$/.test(parsed.pallet)) {
|
|
4038
|
+
await handleTx(parsed.pallet, args, {
|
|
4039
|
+
...handlerOpts,
|
|
4040
|
+
from: opts.from,
|
|
4041
|
+
dryRun: opts.dryRun,
|
|
4042
|
+
encode: opts.encode,
|
|
4043
|
+
ext: opts.ext
|
|
4044
|
+
});
|
|
4045
|
+
} else {
|
|
4046
|
+
await handleTx(target, args, {
|
|
4047
|
+
...handlerOpts,
|
|
4048
|
+
from: opts.from,
|
|
4049
|
+
dryRun: opts.dryRun,
|
|
4050
|
+
encode: opts.encode,
|
|
4051
|
+
ext: opts.ext
|
|
4052
|
+
});
|
|
4053
|
+
}
|
|
4054
|
+
break;
|
|
4055
|
+
case "const":
|
|
4056
|
+
await handleConst(target, handlerOpts);
|
|
4057
|
+
break;
|
|
4058
|
+
case "events":
|
|
4059
|
+
await handleEvents2(target, handlerOpts);
|
|
4060
|
+
break;
|
|
4061
|
+
case "errors":
|
|
4062
|
+
await handleErrors2(target, handlerOpts);
|
|
4063
|
+
break;
|
|
4064
|
+
}
|
|
4065
|
+
});
|
|
2976
4066
|
cli.option("--help, -h", "Display this message");
|
|
2977
4067
|
cli.version(version);
|
|
4068
|
+
function printHelp() {
|
|
4069
|
+
console.log(`dot/${version} \u2014 Polkadot CLI`);
|
|
4070
|
+
console.log();
|
|
4071
|
+
console.log("Usage:");
|
|
4072
|
+
console.log(" dot <category>[.Pallet[.Item]] [args] [options]");
|
|
4073
|
+
console.log(" dot [Chain.]<category>[.Pallet[.Item]] [args] [options]");
|
|
4074
|
+
console.log();
|
|
4075
|
+
console.log("Categories:");
|
|
4076
|
+
console.log(" query Query on-chain storage");
|
|
4077
|
+
console.log(" tx Submit an extrinsic");
|
|
4078
|
+
console.log(" const Look up or list pallet constants");
|
|
4079
|
+
console.log(" events List or inspect pallet events");
|
|
4080
|
+
console.log(" errors List or inspect pallet errors");
|
|
4081
|
+
console.log();
|
|
4082
|
+
console.log("Examples:");
|
|
4083
|
+
console.log(" dot query.System.Account <addr> Query a storage item");
|
|
4084
|
+
console.log(" dot query.System List storage items in System");
|
|
4085
|
+
console.log(" dot tx.System.remark 0xdead --from alice");
|
|
4086
|
+
console.log(" dot const.Balances.ExistentialDeposit");
|
|
4087
|
+
console.log(" dot events.Balances List events in Balances");
|
|
4088
|
+
console.log(" dot polkadot.query.System.Number With chain prefix");
|
|
4089
|
+
console.log();
|
|
4090
|
+
console.log("Commands:");
|
|
4091
|
+
console.log(" inspect [target] Inspect chain metadata (alias: explore)");
|
|
4092
|
+
console.log(" chain Manage chain configurations");
|
|
4093
|
+
console.log(" account Manage accounts");
|
|
4094
|
+
console.log(" hash Hash utilities");
|
|
4095
|
+
console.log();
|
|
4096
|
+
console.log("Global options:");
|
|
4097
|
+
console.log(" --chain <name> Target chain (default from config)");
|
|
4098
|
+
console.log(" --rpc <url> Override RPC endpoint");
|
|
4099
|
+
console.log(" --light-client Use Smoldot light client");
|
|
4100
|
+
console.log(" --output <format> Output format: pretty or json");
|
|
4101
|
+
console.log(" --help, -h Display this message");
|
|
4102
|
+
console.log(" --version Show version");
|
|
4103
|
+
}
|
|
2978
4104
|
async function showUpdateAndExit(code) {
|
|
2979
4105
|
await waitForPendingCheck();
|
|
2980
4106
|
const note = getUpdateNotification(version);
|
|
@@ -2999,17 +4125,17 @@ async function main() {
|
|
|
2999
4125
|
if (cli.options.version) {
|
|
3000
4126
|
await showUpdateAndExit(0);
|
|
3001
4127
|
} else if (cli.options.help) {
|
|
3002
|
-
if (cli.
|
|
4128
|
+
if (cli.matchedCommand) {
|
|
3003
4129
|
const result = cli.runMatchedCommand();
|
|
3004
4130
|
if (result && typeof result.then === "function") {
|
|
3005
4131
|
await result.then(() => showUpdateAndExit(0), handleError);
|
|
3006
4132
|
}
|
|
3007
4133
|
} else {
|
|
3008
|
-
|
|
4134
|
+
printHelp();
|
|
3009
4135
|
await showUpdateAndExit(0);
|
|
3010
4136
|
}
|
|
3011
|
-
} else if (!cli.
|
|
3012
|
-
|
|
4137
|
+
} else if (!cli.matchedCommand) {
|
|
4138
|
+
printHelp();
|
|
3013
4139
|
await showUpdateAndExit(0);
|
|
3014
4140
|
} else {
|
|
3015
4141
|
const result = cli.runMatchedCommand();
|