polkadot-cli 1.16.0 → 1.18.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 +677 -171
- package/dist/cli.mjs +1924 -311
- package/package.json +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -240,6 +240,9 @@ function getMetadataPath(chainName) {
|
|
|
240
240
|
function getMetadataFingerprintPath(chainName) {
|
|
241
241
|
return join(getChainDir(chainName), "metadata.fingerprint.json");
|
|
242
242
|
}
|
|
243
|
+
function getRpcMethodsPath(chainName) {
|
|
244
|
+
return join(getChainDir(chainName), "rpc-methods.json");
|
|
245
|
+
}
|
|
243
246
|
function getConfigPath() {
|
|
244
247
|
return join(getConfigDir(), "config.json");
|
|
245
248
|
}
|
|
@@ -305,6 +308,31 @@ async function loadMetadataFingerprint(chainName) {
|
|
|
305
308
|
return null;
|
|
306
309
|
}
|
|
307
310
|
}
|
|
311
|
+
async function loadRpcMethods(chainName) {
|
|
312
|
+
const path = getRpcMethodsPath(chainName);
|
|
313
|
+
if (!await fileExists(path))
|
|
314
|
+
return null;
|
|
315
|
+
try {
|
|
316
|
+
const parsed = JSON.parse(await readFile(path, "utf-8"));
|
|
317
|
+
if (parsed && Array.isArray(parsed.methods) && typeof parsed.version === "number" && typeof parsed.fetchedAt === "string") {
|
|
318
|
+
return parsed;
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
} catch {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
async function saveRpcMethods(chainName, methods, version2) {
|
|
326
|
+
const dir = getChainDir(chainName);
|
|
327
|
+
await ensureDir(dir);
|
|
328
|
+
const cache = {
|
|
329
|
+
methods,
|
|
330
|
+
version: version2,
|
|
331
|
+
fetchedAt: new Date().toISOString()
|
|
332
|
+
};
|
|
333
|
+
await writeFile(getRpcMethodsPath(chainName), `${JSON.stringify(cache, null, 2)}
|
|
334
|
+
`);
|
|
335
|
+
}
|
|
308
336
|
async function removeChainData(chainName) {
|
|
309
337
|
const dir = getChainDir(chainName);
|
|
310
338
|
await rm(dir, { recursive: true, force: true });
|
|
@@ -375,6 +403,15 @@ function isEnvSecret(secret) {
|
|
|
375
403
|
function isWatchOnly(account) {
|
|
376
404
|
return account.secret === undefined;
|
|
377
405
|
}
|
|
406
|
+
function classifyAccount(account) {
|
|
407
|
+
if (account.source?.kind === "pallet")
|
|
408
|
+
return "pallet";
|
|
409
|
+
if (account.source?.kind === "parachain")
|
|
410
|
+
return "parachain";
|
|
411
|
+
if (account.secret !== undefined)
|
|
412
|
+
return "signer";
|
|
413
|
+
return "watch-only";
|
|
414
|
+
}
|
|
378
415
|
|
|
379
416
|
// src/utils/fuzzy-match.ts
|
|
380
417
|
function levenshtein(a, b) {
|
|
@@ -674,6 +711,11 @@ function printResult(data, format = "pretty") {
|
|
|
674
711
|
function isJsonOutput(opts) {
|
|
675
712
|
return opts.json === true || opts.output === "json";
|
|
676
713
|
}
|
|
714
|
+
function writeStdout(text) {
|
|
715
|
+
return new Promise((resolve) => {
|
|
716
|
+
process.stdout.write(text, () => resolve());
|
|
717
|
+
});
|
|
718
|
+
}
|
|
677
719
|
function printJsonLine(data) {
|
|
678
720
|
console.log(JSON.stringify(data, replacer));
|
|
679
721
|
}
|
|
@@ -853,6 +895,324 @@ var init_client = __esm(() => {
|
|
|
853
895
|
init_errors();
|
|
854
896
|
});
|
|
855
897
|
|
|
898
|
+
// src/core/pretty-type.ts
|
|
899
|
+
function visualWidth(s) {
|
|
900
|
+
return s.replace(ANSI_RE, "").length;
|
|
901
|
+
}
|
|
902
|
+
function paint(color, code, text) {
|
|
903
|
+
return color ? `${code}${text}${RESET2}` : text;
|
|
904
|
+
}
|
|
905
|
+
function defaultWidth() {
|
|
906
|
+
return process.stdout.columns ?? 80;
|
|
907
|
+
}
|
|
908
|
+
function resolveOpts(opts) {
|
|
909
|
+
return {
|
|
910
|
+
indent: opts.indent ?? 0,
|
|
911
|
+
prefix: opts.prefix ?? 0,
|
|
912
|
+
width: opts.width ?? defaultWidth(),
|
|
913
|
+
color: opts.color ?? isTTY
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
function compactEntry(entry, color) {
|
|
917
|
+
if (!entry)
|
|
918
|
+
return "";
|
|
919
|
+
switch (entry.type) {
|
|
920
|
+
case "primitive":
|
|
921
|
+
return paint(color, YELLOW2, entry.value);
|
|
922
|
+
case "compact": {
|
|
923
|
+
const inner = entry.isBig ? "u128" : "u64";
|
|
924
|
+
return `${paint(color, MAGENTA2, "Compact")}<${paint(color, YELLOW2, inner)}>`;
|
|
925
|
+
}
|
|
926
|
+
case "AccountId32":
|
|
927
|
+
return paint(color, GREEN2, "AccountId32");
|
|
928
|
+
case "bitSequence":
|
|
929
|
+
return paint(color, MAGENTA2, "BitSequence");
|
|
930
|
+
case "sequence":
|
|
931
|
+
return `${paint(color, MAGENTA2, "Vec")}<${compactEntry(entry.value, color)}>`;
|
|
932
|
+
case "array":
|
|
933
|
+
return `[${compactEntry(entry.value, color)}; ${entry.len}]`;
|
|
934
|
+
case "tuple":
|
|
935
|
+
return `(${entry.value.map((v) => compactEntry(v, color)).join(", ")})`;
|
|
936
|
+
case "struct": {
|
|
937
|
+
const fields = Object.entries(entry.value);
|
|
938
|
+
if (fields.length === 0)
|
|
939
|
+
return "{}";
|
|
940
|
+
const inner = fields.map(([k, v]) => `${paint(color, CYAN2, k)}: ${compactEntry(v, color)}`).join(", ");
|
|
941
|
+
return `{ ${inner} }`;
|
|
942
|
+
}
|
|
943
|
+
case "option":
|
|
944
|
+
return `${paint(color, MAGENTA2, "Option")}<${compactEntry(entry.value, color)}>`;
|
|
945
|
+
case "result":
|
|
946
|
+
return `${paint(color, MAGENTA2, "Result")}<${compactEntry(entry.value.ok, color)}, ${compactEntry(entry.value.ko, color)}>`;
|
|
947
|
+
case "enum": {
|
|
948
|
+
const variants = Object.keys(entry.value);
|
|
949
|
+
if (variants.length > ENUM_COMPACT_LIMIT) {
|
|
950
|
+
return `enum(${variants.length} variants)`;
|
|
951
|
+
}
|
|
952
|
+
return variants.map((v) => paint(color, GREEN2, v)).join(" | ");
|
|
953
|
+
}
|
|
954
|
+
case "void":
|
|
955
|
+
return "()";
|
|
956
|
+
case "lookupEntry":
|
|
957
|
+
return compactEntry(entry.value, color);
|
|
958
|
+
default:
|
|
959
|
+
return "unknown";
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
function expandEntry(entry, indent, width, color, prefix = 0) {
|
|
963
|
+
const compact = compactEntry(entry, color);
|
|
964
|
+
if (visualWidth(compact) + indent + prefix <= width)
|
|
965
|
+
return compact;
|
|
966
|
+
switch (entry.type) {
|
|
967
|
+
case "struct":
|
|
968
|
+
return expandStruct(entry.value, indent, width, color);
|
|
969
|
+
case "tuple":
|
|
970
|
+
return expandTuple(entry.value, indent, width, color);
|
|
971
|
+
case "sequence":
|
|
972
|
+
return wrapMultiline("Vec", "<", ">", entry.value, indent, width, color);
|
|
973
|
+
case "array": {
|
|
974
|
+
const inner = expandEntry(entry.value, indent + 1, width, color);
|
|
975
|
+
return `[${inner}; ${entry.len}]`;
|
|
976
|
+
}
|
|
977
|
+
case "option":
|
|
978
|
+
return wrapMultiline("Option", "<", ">", entry.value, indent, width, color);
|
|
979
|
+
case "result": {
|
|
980
|
+
const innerIndent = indent + 2;
|
|
981
|
+
const padding = " ".repeat(innerIndent);
|
|
982
|
+
const closePadding = " ".repeat(indent);
|
|
983
|
+
const ok = expandEntry(entry.value.ok, innerIndent, width, color);
|
|
984
|
+
const ko = expandEntry(entry.value.ko, innerIndent, width, color);
|
|
985
|
+
return `${paint(color, MAGENTA2, "Result")}<
|
|
986
|
+
${padding}${ok},
|
|
987
|
+
${padding}${ko}
|
|
988
|
+
${closePadding}>`;
|
|
989
|
+
}
|
|
990
|
+
case "enum": {
|
|
991
|
+
const variants = Object.keys(entry.value);
|
|
992
|
+
if (variants.length > ENUM_COMPACT_LIMIT)
|
|
993
|
+
return `enum(${variants.length} variants)`;
|
|
994
|
+
return expandEnum(variants, indent, color);
|
|
995
|
+
}
|
|
996
|
+
case "lookupEntry":
|
|
997
|
+
return expandEntry(entry.value, indent, width, color);
|
|
998
|
+
default:
|
|
999
|
+
return compact;
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
function expandStruct(fields, indent, width, color) {
|
|
1003
|
+
const entries = Object.entries(fields);
|
|
1004
|
+
if (entries.length === 0)
|
|
1005
|
+
return "{}";
|
|
1006
|
+
return renderFieldList(entries, "{", "}", indent, width, color);
|
|
1007
|
+
}
|
|
1008
|
+
function expandTuple(items, indent, width, color) {
|
|
1009
|
+
if (items.length === 0)
|
|
1010
|
+
return "()";
|
|
1011
|
+
const inner = " ".repeat(indent + 2);
|
|
1012
|
+
const close = " ".repeat(indent);
|
|
1013
|
+
const lines = items.map((v) => `${inner}${expandEntry(v, indent + 2, width, color)}`);
|
|
1014
|
+
return `(
|
|
1015
|
+
${lines.join(`,
|
|
1016
|
+
`)},
|
|
1017
|
+
${close})`;
|
|
1018
|
+
}
|
|
1019
|
+
function wrapMultiline(name, open, close, inner, indent, width, color) {
|
|
1020
|
+
const innerIndent = indent + 2;
|
|
1021
|
+
const padding = " ".repeat(innerIndent);
|
|
1022
|
+
const closePadding = " ".repeat(indent);
|
|
1023
|
+
const innerStr = expandEntry(inner, innerIndent, width, color);
|
|
1024
|
+
return `${paint(color, MAGENTA2, name)}${open}
|
|
1025
|
+
${padding}${innerStr}
|
|
1026
|
+
${closePadding}${close}`;
|
|
1027
|
+
}
|
|
1028
|
+
function expandEnum(variants, indent, color) {
|
|
1029
|
+
const prefix = `
|
|
1030
|
+
${" ".repeat(indent)}| `;
|
|
1031
|
+
const [first, ...rest] = variants;
|
|
1032
|
+
const head = paint(color, GREEN2, first ?? "");
|
|
1033
|
+
if (rest.length === 0)
|
|
1034
|
+
return head;
|
|
1035
|
+
const tail = rest.map((v) => paint(color, GREEN2, v)).join(prefix);
|
|
1036
|
+
return `${head}${prefix}${tail}`;
|
|
1037
|
+
}
|
|
1038
|
+
function renderFieldList(fields, open, close, indent, width, color) {
|
|
1039
|
+
const innerIndent = indent + 2;
|
|
1040
|
+
const maxNameLen = Math.max(...fields.map(([k]) => k.length));
|
|
1041
|
+
const align = maxNameLen <= ALIGN_PADDING_LIMIT;
|
|
1042
|
+
const padTo = align ? maxNameLen : 0;
|
|
1043
|
+
const padding = " ".repeat(innerIndent);
|
|
1044
|
+
const closePadding = " ".repeat(indent);
|
|
1045
|
+
const lines = fields.map(([k, v]) => {
|
|
1046
|
+
const paddedName = align ? k.padEnd(padTo) : k;
|
|
1047
|
+
const fieldPrefix = (align ? padTo : k.length) + 2;
|
|
1048
|
+
const value = expandEntry(v, innerIndent, width, color, fieldPrefix);
|
|
1049
|
+
return `${padding}${paint(color, CYAN2, paddedName)}: ${value}`;
|
|
1050
|
+
});
|
|
1051
|
+
return `${open}
|
|
1052
|
+
${lines.join(`,
|
|
1053
|
+
`)},
|
|
1054
|
+
${closePadding}${close}`;
|
|
1055
|
+
}
|
|
1056
|
+
function prettyType(entry, opts = {}) {
|
|
1057
|
+
const { indent, prefix, width, color } = resolveOpts(opts);
|
|
1058
|
+
const compact = compactEntry(entry, color);
|
|
1059
|
+
if (visualWidth(compact) + indent + prefix <= width)
|
|
1060
|
+
return compact;
|
|
1061
|
+
return expandEntry(entry, indent, width, color);
|
|
1062
|
+
}
|
|
1063
|
+
function prettyTypeById(lookup, typeId, opts = {}) {
|
|
1064
|
+
try {
|
|
1065
|
+
const entry = lookup(typeId);
|
|
1066
|
+
if (!entry || typeof entry.type !== "string")
|
|
1067
|
+
return `type(${typeId})`;
|
|
1068
|
+
return prettyType(entry, opts);
|
|
1069
|
+
} catch {
|
|
1070
|
+
return `type(${typeId})`;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
function prettyCallArgs(meta, palletName, callName, opts = {}) {
|
|
1074
|
+
const fields = getCallFields(meta, palletName, callName);
|
|
1075
|
+
if (fields === null)
|
|
1076
|
+
return "";
|
|
1077
|
+
return renderArgsFromFields(fields, opts);
|
|
1078
|
+
}
|
|
1079
|
+
function prettyEventFields(meta, palletName, eventName, opts = {}) {
|
|
1080
|
+
const fields = getEventFields(meta, palletName, eventName);
|
|
1081
|
+
if (fields === null)
|
|
1082
|
+
return "";
|
|
1083
|
+
return renderArgsFromFields(fields, opts);
|
|
1084
|
+
}
|
|
1085
|
+
function prettyRuntimeApiArgs(lookup, inputs, opts = {}) {
|
|
1086
|
+
if (inputs.length === 0)
|
|
1087
|
+
return "()";
|
|
1088
|
+
const namedFields = inputs.map((i) => {
|
|
1089
|
+
let entry;
|
|
1090
|
+
try {
|
|
1091
|
+
entry = lookup(i.type);
|
|
1092
|
+
if (!entry || typeof entry.type !== "string")
|
|
1093
|
+
entry = { type: "unknown" };
|
|
1094
|
+
} catch {
|
|
1095
|
+
entry = { type: "unknown" };
|
|
1096
|
+
}
|
|
1097
|
+
return [i.name, entry];
|
|
1098
|
+
});
|
|
1099
|
+
return renderArgsFromFields({ kind: "named", fields: namedFields }, opts);
|
|
1100
|
+
}
|
|
1101
|
+
function unwrapVariant(variant) {
|
|
1102
|
+
if (!variant)
|
|
1103
|
+
return null;
|
|
1104
|
+
if (variant.type === "void")
|
|
1105
|
+
return { kind: "void" };
|
|
1106
|
+
if (variant.type === "struct") {
|
|
1107
|
+
return {
|
|
1108
|
+
kind: "named",
|
|
1109
|
+
fields: Object.entries(variant.value)
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
if (variant.type === "tuple") {
|
|
1113
|
+
return { kind: "positional", types: variant.value };
|
|
1114
|
+
}
|
|
1115
|
+
if (variant.type === "lookupEntry") {
|
|
1116
|
+
const inner = variant.value;
|
|
1117
|
+
if (inner.type === "void")
|
|
1118
|
+
return { kind: "void" };
|
|
1119
|
+
if (inner.type === "struct") {
|
|
1120
|
+
return {
|
|
1121
|
+
kind: "named",
|
|
1122
|
+
fields: Object.entries(inner.value)
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
return { kind: "single", type: inner };
|
|
1126
|
+
}
|
|
1127
|
+
return null;
|
|
1128
|
+
}
|
|
1129
|
+
function getCallFields(meta, palletName, callName) {
|
|
1130
|
+
try {
|
|
1131
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
1132
|
+
if (!palletMeta?.calls)
|
|
1133
|
+
return null;
|
|
1134
|
+
const callsEntry = meta.lookup(palletMeta.calls.type);
|
|
1135
|
+
if (callsEntry.type !== "enum")
|
|
1136
|
+
return null;
|
|
1137
|
+
const variant = callsEntry.value[callName];
|
|
1138
|
+
return unwrapVariant(variant);
|
|
1139
|
+
} catch {
|
|
1140
|
+
return null;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
function getEventFields(meta, palletName, eventName) {
|
|
1144
|
+
try {
|
|
1145
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
1146
|
+
if (!palletMeta?.events)
|
|
1147
|
+
return null;
|
|
1148
|
+
const eventsEntry = meta.lookup(palletMeta.events.type);
|
|
1149
|
+
if (eventsEntry.type !== "enum")
|
|
1150
|
+
return null;
|
|
1151
|
+
const variant = eventsEntry.value[eventName];
|
|
1152
|
+
return unwrapVariant(variant);
|
|
1153
|
+
} catch {
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
function renderArgsFromFields(fields, opts) {
|
|
1158
|
+
const { indent, prefix, width, color } = resolveOpts(opts);
|
|
1159
|
+
const lead = indent + prefix;
|
|
1160
|
+
switch (fields.kind) {
|
|
1161
|
+
case "void":
|
|
1162
|
+
return "()";
|
|
1163
|
+
case "named": {
|
|
1164
|
+
const compact = `(${fields.fields.map(([k, v]) => `${paint(color, CYAN2, k)}: ${compactEntry(v, color)}`).join(", ")})`;
|
|
1165
|
+
if (visualWidth(compact) + lead <= width)
|
|
1166
|
+
return compact;
|
|
1167
|
+
return renderFieldList(fields.fields, "(", ")", indent, width, color);
|
|
1168
|
+
}
|
|
1169
|
+
case "positional": {
|
|
1170
|
+
const compact = `(${fields.types.map((t) => compactEntry(t, color)).join(", ")})`;
|
|
1171
|
+
if (visualWidth(compact) + lead <= width)
|
|
1172
|
+
return compact;
|
|
1173
|
+
const innerIndent = indent + 2;
|
|
1174
|
+
const padding = " ".repeat(innerIndent);
|
|
1175
|
+
const closePadding = " ".repeat(indent);
|
|
1176
|
+
const lines = fields.types.map((t) => `${padding}${expandEntry(t, innerIndent, width, color)}`);
|
|
1177
|
+
return `(
|
|
1178
|
+
${lines.join(`,
|
|
1179
|
+
`)},
|
|
1180
|
+
${closePadding})`;
|
|
1181
|
+
}
|
|
1182
|
+
case "single": {
|
|
1183
|
+
const compact = `(${compactEntry(fields.type, color)})`;
|
|
1184
|
+
if (visualWidth(compact) + lead <= width)
|
|
1185
|
+
return compact;
|
|
1186
|
+
const inner = expandEntry(fields.type, indent + 2, width, color);
|
|
1187
|
+
return `(
|
|
1188
|
+
${" ".repeat(indent + 2)}${inner},
|
|
1189
|
+
${" ".repeat(indent)})`;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
function compactTypeString(entry) {
|
|
1194
|
+
return compactEntry(entry, false);
|
|
1195
|
+
}
|
|
1196
|
+
function compactArgsString(fields) {
|
|
1197
|
+
if (fields === null)
|
|
1198
|
+
return "";
|
|
1199
|
+
switch (fields.kind) {
|
|
1200
|
+
case "void":
|
|
1201
|
+
return "()";
|
|
1202
|
+
case "named":
|
|
1203
|
+
return `(${fields.fields.map(([k, v]) => `${k}: ${compactEntry(v, false)}`).join(", ")})`;
|
|
1204
|
+
case "positional":
|
|
1205
|
+
return `(${fields.types.map((t) => compactEntry(t, false)).join(", ")})`;
|
|
1206
|
+
case "single":
|
|
1207
|
+
return `(${compactEntry(fields.type, false)})`;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
var RESET2 = "\x1B[0m", CYAN2 = "\x1B[36m", GREEN2 = "\x1B[32m", YELLOW2 = "\x1B[33m", MAGENTA2 = "\x1B[35m", ANSI_RE, ENUM_COMPACT_LIMIT = 24, ALIGN_PADDING_LIMIT = 16;
|
|
1211
|
+
var init_pretty_type = __esm(() => {
|
|
1212
|
+
init_output();
|
|
1213
|
+
ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
1214
|
+
});
|
|
1215
|
+
|
|
856
1216
|
// src/core/metadata.ts
|
|
857
1217
|
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders";
|
|
858
1218
|
import {
|
|
@@ -1067,114 +1427,18 @@ function describeRuntimeApiMethodArgs(meta, method) {
|
|
|
1067
1427
|
function describeType(lookup, typeId) {
|
|
1068
1428
|
try {
|
|
1069
1429
|
const entry = lookup(typeId);
|
|
1070
|
-
|
|
1430
|
+
if (!entry || typeof entry.type !== "string")
|
|
1431
|
+
return `type(${typeId})`;
|
|
1432
|
+
return compactTypeString(entry);
|
|
1071
1433
|
} catch {
|
|
1072
1434
|
return `type(${typeId})`;
|
|
1073
1435
|
}
|
|
1074
1436
|
}
|
|
1075
|
-
function formatLookupEntry(entry) {
|
|
1076
|
-
switch (entry.type) {
|
|
1077
|
-
case "primitive":
|
|
1078
|
-
return entry.value;
|
|
1079
|
-
case "compact":
|
|
1080
|
-
return `Compact<${formatLookupEntry(entry.isBig ? { type: "primitive", value: "u128" } : { type: "primitive", value: "u64" })}>`;
|
|
1081
|
-
case "AccountId32":
|
|
1082
|
-
return "AccountId32";
|
|
1083
|
-
case "bitSequence":
|
|
1084
|
-
return "BitSequence";
|
|
1085
|
-
case "sequence":
|
|
1086
|
-
return `Vec<${formatLookupEntry(entry.value)}>`;
|
|
1087
|
-
case "array":
|
|
1088
|
-
return `[${formatLookupEntry(entry.value)}; ${entry.len}]`;
|
|
1089
|
-
case "tuple":
|
|
1090
|
-
return `(${entry.value.map(formatLookupEntry).join(", ")})`;
|
|
1091
|
-
case "struct":
|
|
1092
|
-
return `{ ${Object.entries(entry.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ")} }`;
|
|
1093
|
-
case "option":
|
|
1094
|
-
return `Option<${formatLookupEntry(entry.value)}>`;
|
|
1095
|
-
case "result":
|
|
1096
|
-
return `Result<${formatLookupEntry(entry.value.ok)}, ${formatLookupEntry(entry.value.ko)}>`;
|
|
1097
|
-
case "enum": {
|
|
1098
|
-
const variants = Object.keys(entry.value);
|
|
1099
|
-
if (variants.length <= 4)
|
|
1100
|
-
return variants.join(" | ");
|
|
1101
|
-
return `enum(${variants.length} variants)`;
|
|
1102
|
-
}
|
|
1103
|
-
default:
|
|
1104
|
-
return "unknown";
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1107
1437
|
function describeCallArgs(meta, palletName, callName) {
|
|
1108
|
-
|
|
1109
|
-
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
1110
|
-
if (!palletMeta?.calls)
|
|
1111
|
-
return "";
|
|
1112
|
-
const callsEntry = meta.lookup(palletMeta.calls.type);
|
|
1113
|
-
if (callsEntry.type !== "enum")
|
|
1114
|
-
return "";
|
|
1115
|
-
const variant = callsEntry.value[callName];
|
|
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
|
-
}
|
|
1438
|
+
return compactArgsString(getCallFields(meta, palletName, callName));
|
|
1142
1439
|
}
|
|
1143
1440
|
function describeEventFields(meta, palletName, eventName) {
|
|
1144
|
-
|
|
1145
|
-
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
1146
|
-
if (!palletMeta?.events)
|
|
1147
|
-
return "";
|
|
1148
|
-
const eventsEntry = meta.lookup(palletMeta.events.type);
|
|
1149
|
-
if (eventsEntry.type !== "enum")
|
|
1150
|
-
return "";
|
|
1151
|
-
const variant = eventsEntry.value[eventName];
|
|
1152
|
-
if (!variant)
|
|
1153
|
-
return "";
|
|
1154
|
-
if (variant.type === "void")
|
|
1155
|
-
return "()";
|
|
1156
|
-
if (variant.type === "struct") {
|
|
1157
|
-
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1158
|
-
return `(${fields})`;
|
|
1159
|
-
}
|
|
1160
|
-
if (variant.type === "lookupEntry") {
|
|
1161
|
-
const inner = variant.value;
|
|
1162
|
-
if (inner.type === "void")
|
|
1163
|
-
return "()";
|
|
1164
|
-
if (inner.type === "struct") {
|
|
1165
|
-
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1166
|
-
return `(${fields})`;
|
|
1167
|
-
}
|
|
1168
|
-
return `(${formatLookupEntry(inner)})`;
|
|
1169
|
-
}
|
|
1170
|
-
if (variant.type === "tuple") {
|
|
1171
|
-
const types = variant.value.map(formatLookupEntry).join(", ");
|
|
1172
|
-
return `(${types})`;
|
|
1173
|
-
}
|
|
1174
|
-
return "";
|
|
1175
|
-
} catch {
|
|
1176
|
-
return "";
|
|
1177
|
-
}
|
|
1441
|
+
return compactArgsString(getEventFields(meta, palletName, eventName));
|
|
1178
1442
|
}
|
|
1179
1443
|
function hexToBytes(hex) {
|
|
1180
1444
|
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
@@ -1188,6 +1452,7 @@ var METADATA_TIMEOUT_MS = 15000, optionalOpaqueBytes, v15Arg, PAPI_BUILTIN_EXTEN
|
|
|
1188
1452
|
var init_metadata = __esm(() => {
|
|
1189
1453
|
init_store();
|
|
1190
1454
|
init_errors();
|
|
1455
|
+
init_pretty_type();
|
|
1191
1456
|
optionalOpaqueBytes = Option(Bytes());
|
|
1192
1457
|
v15Arg = toHex(u32.enc(15));
|
|
1193
1458
|
PAPI_BUILTIN_EXTENSIONS = new Set([
|
|
@@ -1584,6 +1849,7 @@ var init_tx = __esm(() => {
|
|
|
1584
1849
|
init_client();
|
|
1585
1850
|
init_metadata();
|
|
1586
1851
|
init_output();
|
|
1852
|
+
init_pretty_type();
|
|
1587
1853
|
init_resolve_address();
|
|
1588
1854
|
init_binary_display();
|
|
1589
1855
|
init_errors();
|
|
@@ -1799,8 +2065,11 @@ async function handleCalls(target, opts) {
|
|
|
1799
2065
|
}
|
|
1800
2066
|
printHeading(`${pallet.name} Calls`);
|
|
1801
2067
|
for (const c of pallet.calls) {
|
|
1802
|
-
const args2 =
|
|
1803
|
-
|
|
2068
|
+
const args2 = prettyCallArgs(meta, pallet.name, c.name, {
|
|
2069
|
+
indent: 2,
|
|
2070
|
+
prefix: c.name.length
|
|
2071
|
+
});
|
|
2072
|
+
console.log(` ${CYAN}${c.name}${RESET}${args2}`);
|
|
1804
2073
|
const summary = firstSentence(c.docs);
|
|
1805
2074
|
if (summary) {
|
|
1806
2075
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -1826,7 +2095,10 @@ async function handleCalls(target, opts) {
|
|
|
1826
2095
|
return;
|
|
1827
2096
|
}
|
|
1828
2097
|
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
1829
|
-
const args =
|
|
2098
|
+
const args = prettyCallArgs(meta, pallet.name, callItem.name, {
|
|
2099
|
+
indent: 2,
|
|
2100
|
+
prefix: 6
|
|
2101
|
+
});
|
|
1830
2102
|
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
1831
2103
|
if (callItem.docs.length) {
|
|
1832
2104
|
console.log();
|
|
@@ -1885,8 +2157,11 @@ async function handleEvents(target, opts) {
|
|
|
1885
2157
|
}
|
|
1886
2158
|
printHeading(`${pallet.name} Events`);
|
|
1887
2159
|
for (const e of pallet.events) {
|
|
1888
|
-
const fields2 =
|
|
1889
|
-
|
|
2160
|
+
const fields2 = prettyEventFields(meta, pallet.name, e.name, {
|
|
2161
|
+
indent: 2,
|
|
2162
|
+
prefix: e.name.length
|
|
2163
|
+
});
|
|
2164
|
+
console.log(` ${CYAN}${e.name}${RESET}${fields2}`);
|
|
1890
2165
|
const summary = firstSentence(e.docs);
|
|
1891
2166
|
if (summary) {
|
|
1892
2167
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -1912,7 +2187,10 @@ async function handleEvents(target, opts) {
|
|
|
1912
2187
|
return;
|
|
1913
2188
|
}
|
|
1914
2189
|
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
1915
|
-
const fields =
|
|
2190
|
+
const fields = prettyEventFields(meta, pallet.name, eventItem.name, {
|
|
2191
|
+
indent: 2,
|
|
2192
|
+
prefix: 8
|
|
2193
|
+
});
|
|
1916
2194
|
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
1917
2195
|
if (eventItem.docs.length) {
|
|
1918
2196
|
console.log();
|
|
@@ -2039,24 +2317,30 @@ async function handleStorage(target, opts) {
|
|
|
2039
2317
|
chain: chainName,
|
|
2040
2318
|
pallet: pallet.name,
|
|
2041
2319
|
storage: pallet.storage.map((s) => {
|
|
2042
|
-
const
|
|
2320
|
+
const valueType2 = describeType(meta.lookup, s.valueTypeId);
|
|
2043
2321
|
const keyType = s.keyTypeId != null ? describeType(meta.lookup, s.keyTypeId) : undefined;
|
|
2044
|
-
return { name: s.name, type: s.type, valueType, keyType, docs: firstSentence(s.docs) };
|
|
2322
|
+
return { name: s.name, type: s.type, valueType: valueType2, keyType, docs: firstSentence(s.docs) };
|
|
2045
2323
|
})
|
|
2046
2324
|
}));
|
|
2047
2325
|
return;
|
|
2048
2326
|
}
|
|
2049
2327
|
printHeading(`${pallet.name} Storage`);
|
|
2050
2328
|
for (const s of pallet.storage) {
|
|
2051
|
-
const
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2329
|
+
const isMap = s.keyTypeId != null;
|
|
2330
|
+
const tag = isMap ? `${DIM} [map]${RESET}` : "";
|
|
2331
|
+
console.log(` ${CYAN}${s.name}${RESET}${tag}`);
|
|
2332
|
+
if (isMap) {
|
|
2333
|
+
const keyType = prettyTypeById(meta.lookup, s.keyTypeId, {
|
|
2334
|
+
indent: 4,
|
|
2335
|
+
prefix: 5
|
|
2336
|
+
});
|
|
2337
|
+
console.log(` ${DIM}Key:${RESET} ${keyType}`);
|
|
2058
2338
|
}
|
|
2059
|
-
|
|
2339
|
+
const valueType2 = prettyTypeById(meta.lookup, s.valueTypeId, {
|
|
2340
|
+
indent: 4,
|
|
2341
|
+
prefix: 7
|
|
2342
|
+
});
|
|
2343
|
+
console.log(` ${DIM}Value:${RESET} ${valueType2}`);
|
|
2060
2344
|
const summary = firstSentence(s.docs);
|
|
2061
2345
|
if (summary) {
|
|
2062
2346
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -2071,7 +2355,7 @@ async function handleStorage(target, opts) {
|
|
|
2071
2355
|
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
2072
2356
|
}
|
|
2073
2357
|
if (isJsonOutput(opts)) {
|
|
2074
|
-
const
|
|
2358
|
+
const valueType2 = describeType(meta.lookup, storageItem.valueTypeId);
|
|
2075
2359
|
const keyType = storageItem.keyTypeId != null ? describeType(meta.lookup, storageItem.keyTypeId) : undefined;
|
|
2076
2360
|
console.log(formatJson({
|
|
2077
2361
|
chain: chainName,
|
|
@@ -2079,18 +2363,26 @@ async function handleStorage(target, opts) {
|
|
|
2079
2363
|
item: storageItem.name,
|
|
2080
2364
|
category: "storage",
|
|
2081
2365
|
type: storageItem.type,
|
|
2082
|
-
valueType,
|
|
2366
|
+
valueType: valueType2,
|
|
2083
2367
|
keyType,
|
|
2084
2368
|
docs: storageItem.docs
|
|
2085
2369
|
}));
|
|
2086
2370
|
return;
|
|
2087
2371
|
}
|
|
2088
2372
|
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
2089
|
-
console.log(` ${BOLD}Type:${RESET}
|
|
2090
|
-
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
2373
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
2091
2374
|
if (storageItem.keyTypeId != null) {
|
|
2092
|
-
|
|
2375
|
+
const keyType = prettyTypeById(meta.lookup, storageItem.keyTypeId, {
|
|
2376
|
+
indent: 2,
|
|
2377
|
+
prefix: 7
|
|
2378
|
+
});
|
|
2379
|
+
console.log(` ${BOLD}Key:${RESET} ${keyType}`);
|
|
2093
2380
|
}
|
|
2381
|
+
const valueType = prettyTypeById(meta.lookup, storageItem.valueTypeId, {
|
|
2382
|
+
indent: 2,
|
|
2383
|
+
prefix: 7
|
|
2384
|
+
});
|
|
2385
|
+
console.log(` ${BOLD}Value:${RESET} ${valueType}`);
|
|
2094
2386
|
if (storageItem.docs.length) {
|
|
2095
2387
|
console.log();
|
|
2096
2388
|
printDocs(storageItem.docs);
|
|
@@ -2121,9 +2413,15 @@ async function showItemHelp(category, target, opts) {
|
|
|
2121
2413
|
throw new Error(suggestMessage(`method in ${api.name}`, methodName, names));
|
|
2122
2414
|
}
|
|
2123
2415
|
printHeading(`${api.name}.${method.name} (Runtime API)`);
|
|
2124
|
-
const argStr =
|
|
2125
|
-
|
|
2126
|
-
|
|
2416
|
+
const argStr = prettyRuntimeApiArgs(meta.lookup, method.inputs, {
|
|
2417
|
+
indent: 2,
|
|
2418
|
+
prefix: 9
|
|
2419
|
+
});
|
|
2420
|
+
const retStr = prettyTypeById(meta.lookup, method.output, {
|
|
2421
|
+
indent: 2,
|
|
2422
|
+
prefix: 9
|
|
2423
|
+
});
|
|
2424
|
+
console.log(` ${BOLD}Args:${RESET} ${argStr}`);
|
|
2127
2425
|
console.log(` ${BOLD}Returns:${RESET} ${retStr}`);
|
|
2128
2426
|
if (method.docs.length) {
|
|
2129
2427
|
console.log();
|
|
@@ -2166,7 +2464,10 @@ async function showItemHelp(category, target, opts) {
|
|
|
2166
2464
|
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
2167
2465
|
}
|
|
2168
2466
|
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
2169
|
-
const args =
|
|
2467
|
+
const args = prettyCallArgs(meta, pallet.name, callItem.name, {
|
|
2468
|
+
indent: 2,
|
|
2469
|
+
prefix: 6
|
|
2470
|
+
});
|
|
2170
2471
|
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
2171
2472
|
if (callItem.docs.length) {
|
|
2172
2473
|
console.log();
|
|
@@ -2193,11 +2494,19 @@ async function showItemHelp(category, target, opts) {
|
|
|
2193
2494
|
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
2194
2495
|
}
|
|
2195
2496
|
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
2196
|
-
console.log(` ${BOLD}Type:${RESET}
|
|
2197
|
-
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
2497
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
2198
2498
|
if (storageItem.keyTypeId != null) {
|
|
2199
|
-
|
|
2499
|
+
const keyType = prettyTypeById(meta.lookup, storageItem.keyTypeId, {
|
|
2500
|
+
indent: 2,
|
|
2501
|
+
prefix: 7
|
|
2502
|
+
});
|
|
2503
|
+
console.log(` ${BOLD}Key:${RESET} ${keyType}`);
|
|
2200
2504
|
}
|
|
2505
|
+
const valueType = prettyTypeById(meta.lookup, storageItem.valueTypeId, {
|
|
2506
|
+
indent: 2,
|
|
2507
|
+
prefix: 7
|
|
2508
|
+
});
|
|
2509
|
+
console.log(` ${BOLD}Value:${RESET} ${valueType}`);
|
|
2201
2510
|
if (storageItem.docs.length) {
|
|
2202
2511
|
console.log();
|
|
2203
2512
|
printDocs(storageItem.docs);
|
|
@@ -2224,7 +2533,11 @@ async function showItemHelp(category, target, opts) {
|
|
|
2224
2533
|
throw new Error(suggestMessage(`constant in ${pallet.name}`, itemName, names));
|
|
2225
2534
|
}
|
|
2226
2535
|
printHeading(`${pallet.name}.${constItem.name} (Constant)`);
|
|
2227
|
-
|
|
2536
|
+
const constType = prettyTypeById(meta.lookup, constItem.typeId, {
|
|
2537
|
+
indent: 2,
|
|
2538
|
+
prefix: 6
|
|
2539
|
+
});
|
|
2540
|
+
console.log(` ${BOLD}Type:${RESET} ${constType}`);
|
|
2228
2541
|
if (constItem.docs.length) {
|
|
2229
2542
|
console.log();
|
|
2230
2543
|
printDocs(constItem.docs);
|
|
@@ -2242,7 +2555,10 @@ async function showItemHelp(category, target, opts) {
|
|
|
2242
2555
|
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
2243
2556
|
}
|
|
2244
2557
|
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
2245
|
-
const fields =
|
|
2558
|
+
const fields = prettyEventFields(meta, pallet.name, eventItem.name, {
|
|
2559
|
+
indent: 2,
|
|
2560
|
+
prefix: 8
|
|
2561
|
+
});
|
|
2246
2562
|
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
2247
2563
|
if (eventItem.docs.length) {
|
|
2248
2564
|
console.log();
|
|
@@ -2277,6 +2593,478 @@ var init_focused_inspect = __esm(() => {
|
|
|
2277
2593
|
init_client();
|
|
2278
2594
|
init_metadata();
|
|
2279
2595
|
init_output();
|
|
2596
|
+
init_pretty_type();
|
|
2597
|
+
});
|
|
2598
|
+
|
|
2599
|
+
// src/data/rpc-registry.ts
|
|
2600
|
+
function inferFamily(method) {
|
|
2601
|
+
const prefix = method.split("_")[0];
|
|
2602
|
+
switch (prefix) {
|
|
2603
|
+
case "system":
|
|
2604
|
+
case "chain":
|
|
2605
|
+
case "state":
|
|
2606
|
+
case "author":
|
|
2607
|
+
case "payment":
|
|
2608
|
+
case "babe":
|
|
2609
|
+
case "grandpa":
|
|
2610
|
+
case "beefy":
|
|
2611
|
+
case "mmr":
|
|
2612
|
+
case "offchain":
|
|
2613
|
+
case "dev":
|
|
2614
|
+
return prefix;
|
|
2615
|
+
case "rpc":
|
|
2616
|
+
return "spec";
|
|
2617
|
+
case "chainHead":
|
|
2618
|
+
return "chainHead";
|
|
2619
|
+
case "chainSpec":
|
|
2620
|
+
return "chainSpec";
|
|
2621
|
+
case "transaction":
|
|
2622
|
+
return "transaction";
|
|
2623
|
+
case "archive":
|
|
2624
|
+
return "archive";
|
|
2625
|
+
default:
|
|
2626
|
+
return "other";
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
var RPC_REGISTRY;
|
|
2630
|
+
var init_rpc_registry = __esm(() => {
|
|
2631
|
+
RPC_REGISTRY = {
|
|
2632
|
+
system_health: {
|
|
2633
|
+
description: "Node sync state (peers, isSyncing, shouldHavePeers).",
|
|
2634
|
+
family: "system",
|
|
2635
|
+
args: []
|
|
2636
|
+
},
|
|
2637
|
+
system_syncState: {
|
|
2638
|
+
description: "Block-level sync progress (startingBlock, currentBlock, highestBlock).",
|
|
2639
|
+
family: "system",
|
|
2640
|
+
args: []
|
|
2641
|
+
},
|
|
2642
|
+
system_version: {
|
|
2643
|
+
description: "Node software version string.",
|
|
2644
|
+
family: "system",
|
|
2645
|
+
args: []
|
|
2646
|
+
},
|
|
2647
|
+
system_name: {
|
|
2648
|
+
description: "Node implementation name.",
|
|
2649
|
+
family: "system",
|
|
2650
|
+
args: []
|
|
2651
|
+
},
|
|
2652
|
+
system_chain: {
|
|
2653
|
+
description: "Chain name as reported by the node.",
|
|
2654
|
+
family: "system",
|
|
2655
|
+
args: []
|
|
2656
|
+
},
|
|
2657
|
+
system_chainType: {
|
|
2658
|
+
description: "Chain type (Live, Development, Local).",
|
|
2659
|
+
family: "system",
|
|
2660
|
+
args: []
|
|
2661
|
+
},
|
|
2662
|
+
system_properties: {
|
|
2663
|
+
description: "Chain properties (ss58Format, tokenDecimals, tokenSymbol).",
|
|
2664
|
+
family: "system",
|
|
2665
|
+
args: []
|
|
2666
|
+
},
|
|
2667
|
+
system_peers: {
|
|
2668
|
+
description: "Connected peer details (peerId, roles, bestHash, bestNumber).",
|
|
2669
|
+
family: "system",
|
|
2670
|
+
args: []
|
|
2671
|
+
},
|
|
2672
|
+
system_localPeerId: {
|
|
2673
|
+
description: "Base58 PeerId of this node.",
|
|
2674
|
+
family: "system",
|
|
2675
|
+
args: []
|
|
2676
|
+
},
|
|
2677
|
+
system_localListenAddresses: {
|
|
2678
|
+
description: "Multiaddrs this node listens on.",
|
|
2679
|
+
family: "system",
|
|
2680
|
+
args: []
|
|
2681
|
+
},
|
|
2682
|
+
system_nodeRoles: {
|
|
2683
|
+
description: "Role(s) of the node (Authority, Full, Light, …).",
|
|
2684
|
+
family: "system",
|
|
2685
|
+
args: []
|
|
2686
|
+
},
|
|
2687
|
+
system_addLogFilter: {
|
|
2688
|
+
description: "Add a tracing/log filter directive at runtime.",
|
|
2689
|
+
family: "system",
|
|
2690
|
+
args: [{ name: "directives", type: "string" }],
|
|
2691
|
+
dangerous: true
|
|
2692
|
+
},
|
|
2693
|
+
system_resetLogFilter: {
|
|
2694
|
+
description: "Reset log filter to the default set at startup.",
|
|
2695
|
+
family: "system",
|
|
2696
|
+
args: [],
|
|
2697
|
+
dangerous: true
|
|
2698
|
+
},
|
|
2699
|
+
system_accountNextIndex: {
|
|
2700
|
+
description: "Next nonce for an account, including pending mempool extrinsics.",
|
|
2701
|
+
family: "system",
|
|
2702
|
+
args: [{ name: "address", type: "AccountId" }]
|
|
2703
|
+
},
|
|
2704
|
+
system_dryRun: {
|
|
2705
|
+
description: "Dry-run an extrinsic, returning its ApplyExtrinsicResult.",
|
|
2706
|
+
family: "system",
|
|
2707
|
+
args: [
|
|
2708
|
+
{ name: "extrinsic", type: "hex" },
|
|
2709
|
+
{ name: "at", type: "H256", optional: true }
|
|
2710
|
+
]
|
|
2711
|
+
},
|
|
2712
|
+
chain_getBlock: {
|
|
2713
|
+
description: "Full block (header + extrinsics) by hash.",
|
|
2714
|
+
family: "chain",
|
|
2715
|
+
args: [{ name: "blockHash", type: "H256", optional: true, description: "latest if omitted" }]
|
|
2716
|
+
},
|
|
2717
|
+
chain_getBlockHash: {
|
|
2718
|
+
description: "Block hash by number, or latest if omitted.",
|
|
2719
|
+
family: "chain",
|
|
2720
|
+
args: [{ name: "blockNumber", type: "u32", optional: true }]
|
|
2721
|
+
},
|
|
2722
|
+
chain_getFinalizedHead: {
|
|
2723
|
+
description: "Hash of the latest finalized head.",
|
|
2724
|
+
family: "chain",
|
|
2725
|
+
args: []
|
|
2726
|
+
},
|
|
2727
|
+
chain_getHeader: {
|
|
2728
|
+
description: "Block header by hash, or latest if omitted.",
|
|
2729
|
+
family: "chain",
|
|
2730
|
+
args: [{ name: "blockHash", type: "H256", optional: true }]
|
|
2731
|
+
},
|
|
2732
|
+
chain_subscribeAllHeads: {
|
|
2733
|
+
description: "Subscribe to all imported headers.",
|
|
2734
|
+
family: "chain",
|
|
2735
|
+
args: [],
|
|
2736
|
+
subscription: true
|
|
2737
|
+
},
|
|
2738
|
+
chain_subscribeFinalizedHeads: {
|
|
2739
|
+
description: "Subscribe to finalized-head changes.",
|
|
2740
|
+
family: "chain",
|
|
2741
|
+
args: [],
|
|
2742
|
+
subscription: true
|
|
2743
|
+
},
|
|
2744
|
+
chain_subscribeNewHeads: {
|
|
2745
|
+
description: "Subscribe to best-block-head changes.",
|
|
2746
|
+
family: "chain",
|
|
2747
|
+
args: [],
|
|
2748
|
+
subscription: true
|
|
2749
|
+
},
|
|
2750
|
+
state_call: {
|
|
2751
|
+
description: "Invoke a runtime API method by name with raw SCALE-encoded arguments.",
|
|
2752
|
+
family: "state",
|
|
2753
|
+
args: [
|
|
2754
|
+
{ name: "method", type: "string", description: "e.g. Core_version" },
|
|
2755
|
+
{ name: "data", type: "hex", description: "SCALE-encoded args (0x for none)" },
|
|
2756
|
+
{ name: "at", type: "H256", optional: true }
|
|
2757
|
+
]
|
|
2758
|
+
},
|
|
2759
|
+
state_getMetadata: {
|
|
2760
|
+
description: "Raw SCALE-encoded runtime metadata at a block.",
|
|
2761
|
+
family: "state",
|
|
2762
|
+
args: [{ name: "at", type: "H256", optional: true }]
|
|
2763
|
+
},
|
|
2764
|
+
state_getRuntimeVersion: {
|
|
2765
|
+
description: "Runtime version at a block.",
|
|
2766
|
+
family: "state",
|
|
2767
|
+
args: [{ name: "at", type: "H256", optional: true }]
|
|
2768
|
+
},
|
|
2769
|
+
state_getStorage: {
|
|
2770
|
+
description: "Raw SCALE-encoded storage value at a key.",
|
|
2771
|
+
family: "state",
|
|
2772
|
+
args: [
|
|
2773
|
+
{ name: "key", type: "StorageKey" },
|
|
2774
|
+
{ name: "at", type: "H256", optional: true }
|
|
2775
|
+
]
|
|
2776
|
+
},
|
|
2777
|
+
state_getStorageHash: {
|
|
2778
|
+
description: "Blake2 hash of the value at a storage key.",
|
|
2779
|
+
family: "state",
|
|
2780
|
+
args: [
|
|
2781
|
+
{ name: "key", type: "StorageKey" },
|
|
2782
|
+
{ name: "at", type: "H256", optional: true }
|
|
2783
|
+
]
|
|
2784
|
+
},
|
|
2785
|
+
state_getStorageSize: {
|
|
2786
|
+
description: "Byte length of the value at a storage key.",
|
|
2787
|
+
family: "state",
|
|
2788
|
+
args: [
|
|
2789
|
+
{ name: "key", type: "StorageKey" },
|
|
2790
|
+
{ name: "at", type: "H256", optional: true }
|
|
2791
|
+
]
|
|
2792
|
+
},
|
|
2793
|
+
state_getKeysPaged: {
|
|
2794
|
+
description: "Paginated key iteration under a prefix.",
|
|
2795
|
+
family: "state",
|
|
2796
|
+
args: [
|
|
2797
|
+
{ name: "prefix", type: "StorageKey" },
|
|
2798
|
+
{ name: "count", type: "u32" },
|
|
2799
|
+
{ name: "startKey", type: "StorageKey", optional: true },
|
|
2800
|
+
{ name: "at", type: "H256", optional: true }
|
|
2801
|
+
]
|
|
2802
|
+
},
|
|
2803
|
+
state_queryStorageAt: {
|
|
2804
|
+
description: "Read multiple keys at a single block.",
|
|
2805
|
+
family: "state",
|
|
2806
|
+
args: [
|
|
2807
|
+
{ name: "keys", type: "StorageKey[]" },
|
|
2808
|
+
{ name: "at", type: "H256", optional: true }
|
|
2809
|
+
]
|
|
2810
|
+
},
|
|
2811
|
+
state_traceBlock: {
|
|
2812
|
+
description: "Per-block storage access trace (heavy: archival/debug nodes only).",
|
|
2813
|
+
family: "state",
|
|
2814
|
+
args: [
|
|
2815
|
+
{ name: "blockHash", type: "H256" },
|
|
2816
|
+
{ name: "targets", type: "string", optional: true },
|
|
2817
|
+
{ name: "storageKeys", type: "string", optional: true },
|
|
2818
|
+
{ name: "methods", type: "string", optional: true }
|
|
2819
|
+
]
|
|
2820
|
+
},
|
|
2821
|
+
state_subscribeRuntimeVersion: {
|
|
2822
|
+
description: "Subscribe to runtime upgrades.",
|
|
2823
|
+
family: "state",
|
|
2824
|
+
args: [],
|
|
2825
|
+
subscription: true
|
|
2826
|
+
},
|
|
2827
|
+
state_subscribeStorage: {
|
|
2828
|
+
description: "Subscribe to changes for a set of keys.",
|
|
2829
|
+
family: "state",
|
|
2830
|
+
args: [{ name: "keys", type: "StorageKey[]" }],
|
|
2831
|
+
subscription: true
|
|
2832
|
+
},
|
|
2833
|
+
author_pendingExtrinsics: {
|
|
2834
|
+
description: "Mempool snapshot — encoded extrinsics waiting to be included.",
|
|
2835
|
+
family: "author",
|
|
2836
|
+
args: []
|
|
2837
|
+
},
|
|
2838
|
+
author_submitExtrinsic: {
|
|
2839
|
+
description: "Submit a signed extrinsic to the mempool. Returns the tx hash.",
|
|
2840
|
+
family: "author",
|
|
2841
|
+
args: [{ name: "extrinsic", type: "hex" }],
|
|
2842
|
+
dangerous: true
|
|
2843
|
+
},
|
|
2844
|
+
author_removeExtrinsic: {
|
|
2845
|
+
description: "Remove specific extrinsics from the mempool by hash.",
|
|
2846
|
+
family: "author",
|
|
2847
|
+
args: [{ name: "bytesOrHash", type: "ExtrinsicOrHash[]" }],
|
|
2848
|
+
dangerous: true
|
|
2849
|
+
},
|
|
2850
|
+
author_hasKey: {
|
|
2851
|
+
description: "Whether the keystore has the public key for a given key type.",
|
|
2852
|
+
family: "author",
|
|
2853
|
+
args: [
|
|
2854
|
+
{ name: "publicKey", type: "hex" },
|
|
2855
|
+
{ name: "keyType", type: "string", description: "e.g. babe, gran, imon" }
|
|
2856
|
+
]
|
|
2857
|
+
},
|
|
2858
|
+
author_hasSessionKeys: {
|
|
2859
|
+
description: "Whether the keystore has all keys for a session-keys blob.",
|
|
2860
|
+
family: "author",
|
|
2861
|
+
args: [{ name: "sessionKeys", type: "hex" }]
|
|
2862
|
+
},
|
|
2863
|
+
author_rotateKeys: {
|
|
2864
|
+
description: "Generate a new set of session keys and return the public-keys blob.",
|
|
2865
|
+
family: "author",
|
|
2866
|
+
args: [],
|
|
2867
|
+
dangerous: true
|
|
2868
|
+
},
|
|
2869
|
+
author_insertKey: {
|
|
2870
|
+
description: "Insert a key into the node keystore.",
|
|
2871
|
+
family: "author",
|
|
2872
|
+
args: [
|
|
2873
|
+
{ name: "keyType", type: "string" },
|
|
2874
|
+
{ name: "suri", type: "string" },
|
|
2875
|
+
{ name: "publicKey", type: "hex" }
|
|
2876
|
+
],
|
|
2877
|
+
dangerous: true
|
|
2878
|
+
},
|
|
2879
|
+
author_submitAndWatchExtrinsic: {
|
|
2880
|
+
description: "Submit an extrinsic and subscribe to its status updates.",
|
|
2881
|
+
family: "author",
|
|
2882
|
+
args: [{ name: "extrinsic", type: "hex" }],
|
|
2883
|
+
dangerous: true,
|
|
2884
|
+
subscription: true
|
|
2885
|
+
},
|
|
2886
|
+
payment_queryInfo: {
|
|
2887
|
+
description: "Pre-submission fee estimate (weight, partialFee, class).",
|
|
2888
|
+
family: "payment",
|
|
2889
|
+
args: [
|
|
2890
|
+
{ name: "extrinsic", type: "hex" },
|
|
2891
|
+
{ name: "at", type: "H256", optional: true }
|
|
2892
|
+
]
|
|
2893
|
+
},
|
|
2894
|
+
payment_queryFeeDetails: {
|
|
2895
|
+
description: "Fee breakdown (baseFee, lenFee, adjustedWeightFee, tip).",
|
|
2896
|
+
family: "payment",
|
|
2897
|
+
args: [
|
|
2898
|
+
{ name: "extrinsic", type: "hex" },
|
|
2899
|
+
{ name: "at", type: "H256", optional: true }
|
|
2900
|
+
]
|
|
2901
|
+
},
|
|
2902
|
+
babe_epochAuthorship: {
|
|
2903
|
+
description: "Slots this node is allowed to author in the current epoch.",
|
|
2904
|
+
family: "babe",
|
|
2905
|
+
args: []
|
|
2906
|
+
},
|
|
2907
|
+
grandpa_proveFinality: {
|
|
2908
|
+
description: "Finality proof up to a block (for light clients).",
|
|
2909
|
+
family: "grandpa",
|
|
2910
|
+
args: [{ name: "blockNumber", type: "u32" }]
|
|
2911
|
+
},
|
|
2912
|
+
grandpa_roundState: {
|
|
2913
|
+
description: "GRANDPA round state (best round, total weight, voters).",
|
|
2914
|
+
family: "grandpa",
|
|
2915
|
+
args: []
|
|
2916
|
+
},
|
|
2917
|
+
grandpa_subscribeJustifications: {
|
|
2918
|
+
description: "Subscribe to GRANDPA justifications.",
|
|
2919
|
+
family: "grandpa",
|
|
2920
|
+
args: [],
|
|
2921
|
+
subscription: true
|
|
2922
|
+
},
|
|
2923
|
+
beefy_getFinalizedHead: {
|
|
2924
|
+
description: "Latest BEEFY-finalized block hash.",
|
|
2925
|
+
family: "beefy",
|
|
2926
|
+
args: []
|
|
2927
|
+
},
|
|
2928
|
+
beefy_subscribeJustifications: {
|
|
2929
|
+
description: "Subscribe to BEEFY signed commitments.",
|
|
2930
|
+
family: "beefy",
|
|
2931
|
+
args: [],
|
|
2932
|
+
subscription: true
|
|
2933
|
+
},
|
|
2934
|
+
mmr_root: {
|
|
2935
|
+
description: "MMR root at a block.",
|
|
2936
|
+
family: "mmr",
|
|
2937
|
+
args: [{ name: "at", type: "H256", optional: true }]
|
|
2938
|
+
},
|
|
2939
|
+
mmr_generateProof: {
|
|
2940
|
+
description: "Generate an MMR proof for given leaf indices.",
|
|
2941
|
+
family: "mmr",
|
|
2942
|
+
args: [
|
|
2943
|
+
{ name: "blockNumbers", type: "u32[]" },
|
|
2944
|
+
{ name: "bestKnownBlockNumber", type: "u32", optional: true },
|
|
2945
|
+
{ name: "at", type: "H256", optional: true }
|
|
2946
|
+
]
|
|
2947
|
+
},
|
|
2948
|
+
mmr_verifyProof: {
|
|
2949
|
+
description: "Verify an MMR proof.",
|
|
2950
|
+
family: "mmr",
|
|
2951
|
+
args: [{ name: "proof", type: "MmrLeavesProof" }]
|
|
2952
|
+
},
|
|
2953
|
+
offchain_localStorageGet: {
|
|
2954
|
+
description: "Read from offchain-worker local storage (PERSISTENT or LOCAL kind).",
|
|
2955
|
+
family: "offchain",
|
|
2956
|
+
args: [
|
|
2957
|
+
{ name: "kind", type: "string", description: "PERSISTENT or LOCAL" },
|
|
2958
|
+
{ name: "key", type: "hex" }
|
|
2959
|
+
]
|
|
2960
|
+
},
|
|
2961
|
+
offchain_localStorageSet: {
|
|
2962
|
+
description: "Write to offchain-worker local storage.",
|
|
2963
|
+
family: "offchain",
|
|
2964
|
+
args: [
|
|
2965
|
+
{ name: "kind", type: "string" },
|
|
2966
|
+
{ name: "key", type: "hex" },
|
|
2967
|
+
{ name: "value", type: "hex" }
|
|
2968
|
+
],
|
|
2969
|
+
dangerous: true
|
|
2970
|
+
},
|
|
2971
|
+
dev_newBlock: {
|
|
2972
|
+
description: "Manually trigger block production (manual-seal dev nodes).",
|
|
2973
|
+
family: "dev",
|
|
2974
|
+
args: [
|
|
2975
|
+
{
|
|
2976
|
+
name: "params",
|
|
2977
|
+
type: "json",
|
|
2978
|
+
optional: true,
|
|
2979
|
+
description: "{ create_empty?: bool, finalize?: bool }"
|
|
2980
|
+
}
|
|
2981
|
+
],
|
|
2982
|
+
dangerous: true
|
|
2983
|
+
},
|
|
2984
|
+
dev_setHead: {
|
|
2985
|
+
description: "Set the chain head to a specific block (manual-seal dev nodes).",
|
|
2986
|
+
family: "dev",
|
|
2987
|
+
args: [{ name: "blockHash", type: "H256" }],
|
|
2988
|
+
dangerous: true
|
|
2989
|
+
},
|
|
2990
|
+
rpc_methods: {
|
|
2991
|
+
description: "List of JSON-RPC methods this node exposes.",
|
|
2992
|
+
family: "spec",
|
|
2993
|
+
args: []
|
|
2994
|
+
},
|
|
2995
|
+
chainSpec_v1_chainName: {
|
|
2996
|
+
description: "Chain name from the chain spec (no SCALE).",
|
|
2997
|
+
family: "chainSpec",
|
|
2998
|
+
args: []
|
|
2999
|
+
},
|
|
3000
|
+
chainSpec_v1_genesisHash: {
|
|
3001
|
+
description: "Genesis block hash.",
|
|
3002
|
+
family: "chainSpec",
|
|
3003
|
+
args: []
|
|
3004
|
+
},
|
|
3005
|
+
chainSpec_v1_properties: {
|
|
3006
|
+
description: "Chain properties from the chain spec.",
|
|
3007
|
+
family: "chainSpec",
|
|
3008
|
+
args: []
|
|
3009
|
+
},
|
|
3010
|
+
archive_v1_finalizedHeight: {
|
|
3011
|
+
description: "Latest finalized block number this archive node has.",
|
|
3012
|
+
family: "archive",
|
|
3013
|
+
args: []
|
|
3014
|
+
},
|
|
3015
|
+
archive_v1_genesisHash: {
|
|
3016
|
+
description: "Genesis block hash from the archive node.",
|
|
3017
|
+
family: "archive",
|
|
3018
|
+
args: []
|
|
3019
|
+
},
|
|
3020
|
+
archive_v1_hashByHeight: {
|
|
3021
|
+
description: "Block hashes at a height (canonical + forks).",
|
|
3022
|
+
family: "archive",
|
|
3023
|
+
args: [{ name: "height", type: "u32" }]
|
|
3024
|
+
},
|
|
3025
|
+
archive_v1_header: {
|
|
3026
|
+
description: "Header for an archived block.",
|
|
3027
|
+
family: "archive",
|
|
3028
|
+
args: [{ name: "blockHash", type: "H256" }]
|
|
3029
|
+
},
|
|
3030
|
+
archive_v1_body: {
|
|
3031
|
+
description: "Block body (extrinsics) for an archived block.",
|
|
3032
|
+
family: "archive",
|
|
3033
|
+
args: [{ name: "blockHash", type: "H256" }]
|
|
3034
|
+
},
|
|
3035
|
+
archive_v1_call: {
|
|
3036
|
+
description: "Invoke a runtime API at an archived block.",
|
|
3037
|
+
family: "archive",
|
|
3038
|
+
args: [
|
|
3039
|
+
{ name: "blockHash", type: "H256" },
|
|
3040
|
+
{ name: "function", type: "string" },
|
|
3041
|
+
{ name: "callParameters", type: "hex" }
|
|
3042
|
+
]
|
|
3043
|
+
},
|
|
3044
|
+
archive_v1_storage: {
|
|
3045
|
+
description: "Read storage at an archived block.",
|
|
3046
|
+
family: "archive",
|
|
3047
|
+
args: [
|
|
3048
|
+
{ name: "blockHash", type: "H256" },
|
|
3049
|
+
{ name: "items", type: "StorageItemInput[]" },
|
|
3050
|
+
{ name: "childTrie", type: "string", optional: true }
|
|
3051
|
+
],
|
|
3052
|
+
subscription: true
|
|
3053
|
+
},
|
|
3054
|
+
chainHead_v1_follow: {
|
|
3055
|
+
description: "Pin chainHead and stream block events. Requires a follow session.",
|
|
3056
|
+
family: "chainHead",
|
|
3057
|
+
args: [{ name: "withRuntime", type: "bool" }],
|
|
3058
|
+
subscription: true
|
|
3059
|
+
},
|
|
3060
|
+
transaction_v1_broadcast: {
|
|
3061
|
+
description: "Broadcast a signed extrinsic and watch its status.",
|
|
3062
|
+
family: "transaction",
|
|
3063
|
+
args: [{ name: "extrinsic", type: "hex" }],
|
|
3064
|
+
dangerous: true,
|
|
3065
|
+
subscription: true
|
|
3066
|
+
}
|
|
3067
|
+
};
|
|
2280
3068
|
});
|
|
2281
3069
|
|
|
2282
3070
|
// src/core/hash.ts
|
|
@@ -2462,11 +3250,8 @@ async function generateCompletions(currentWord, precedingWords) {
|
|
|
2462
3250
|
if (firstArg === "hash") {
|
|
2463
3251
|
return filterPrefix(getAlgorithmNames(), currentWord);
|
|
2464
3252
|
}
|
|
2465
|
-
if (firstArg === "parachain") {
|
|
2466
|
-
|
|
2467
|
-
return filterPrefix(["child", "sibling"], currentWord);
|
|
2468
|
-
}
|
|
2469
|
-
return [];
|
|
3253
|
+
if (firstArg === "account" && prevWord === "--parachain-type") {
|
|
3254
|
+
return filterPrefix(["child", "sibling"], currentWord);
|
|
2470
3255
|
}
|
|
2471
3256
|
return completeDotpath(currentWord, config, knownChains, precedingWords);
|
|
2472
3257
|
}
|
|
@@ -2509,6 +3294,9 @@ async function completeDotpath(currentWord, config, knownChains, precedingWords)
|
|
|
2509
3294
|
if (category === "extensions") {
|
|
2510
3295
|
return completeExtensionsCategory(first, numComplete, endsWithDot, currentWord, config, chainFromFlag);
|
|
2511
3296
|
}
|
|
3297
|
+
if (category === "rpc") {
|
|
3298
|
+
return completeRpcCategory(first, numComplete, endsWithDot, currentWord, chainFromFlag);
|
|
3299
|
+
}
|
|
2512
3300
|
if (numComplete === 1 && endsWithDot) {
|
|
2513
3301
|
const chainName = chainFromFlag;
|
|
2514
3302
|
if (!chainName)
|
|
@@ -2568,6 +3356,9 @@ async function completeDotpath(currentWord, config, knownChains, precedingWords)
|
|
|
2568
3356
|
if (category === "extensions") {
|
|
2569
3357
|
return completeExtensionsCategory(`${first}.${completeSegments[1]}`, numComplete - 1, endsWithDot, currentWord, config, chainName);
|
|
2570
3358
|
}
|
|
3359
|
+
if (category === "rpc") {
|
|
3360
|
+
return completeRpcCategory(`${first}.${completeSegments[1]}`, numComplete - 1, endsWithDot, currentWord, chainName);
|
|
3361
|
+
}
|
|
2571
3362
|
const pallets = await loadPallets(config, chainName);
|
|
2572
3363
|
if (!pallets)
|
|
2573
3364
|
return [];
|
|
@@ -2641,6 +3432,24 @@ async function completeExtensionsCategory(prefix, numComplete, endsWithDot, curr
|
|
|
2641
3432
|
}
|
|
2642
3433
|
return [];
|
|
2643
3434
|
}
|
|
3435
|
+
async function completeRpcCategory(prefix, numComplete, endsWithDot, currentWord, chainNameOverride) {
|
|
3436
|
+
let names;
|
|
3437
|
+
if (chainNameOverride) {
|
|
3438
|
+
const cached = await loadRpcMethods(chainNameOverride);
|
|
3439
|
+
names = cached?.methods ?? Object.keys(RPC_REGISTRY);
|
|
3440
|
+
} else {
|
|
3441
|
+
names = Object.keys(RPC_REGISTRY);
|
|
3442
|
+
}
|
|
3443
|
+
if (numComplete === 1 && endsWithDot) {
|
|
3444
|
+
const candidates = names.map((n) => `${prefix}.${n}`);
|
|
3445
|
+
return filterPrefix(candidates, currentWord.slice(0, -1));
|
|
3446
|
+
}
|
|
3447
|
+
if (numComplete === 1 && !endsWithDot) {
|
|
3448
|
+
const candidates = names.map((n) => `${prefix}.${n}`);
|
|
3449
|
+
return filterPrefix(candidates, currentWord);
|
|
3450
|
+
}
|
|
3451
|
+
return [];
|
|
3452
|
+
}
|
|
2644
3453
|
var CATEGORIES2, CATEGORY_ALIASES2, NAMED_COMMANDS, CHAIN_SUBCOMMANDS, ACCOUNT_SUBCOMMANDS, GLOBAL_OPTIONS, TX_OPTIONS, QUERY_OPTIONS;
|
|
2645
3454
|
var init_complete = __esm(() => {
|
|
2646
3455
|
init_accounts_store();
|
|
@@ -2648,7 +3457,17 @@ var init_complete = __esm(() => {
|
|
|
2648
3457
|
init_accounts();
|
|
2649
3458
|
init_hash();
|
|
2650
3459
|
init_metadata();
|
|
2651
|
-
|
|
3460
|
+
init_rpc_registry();
|
|
3461
|
+
CATEGORIES2 = [
|
|
3462
|
+
"query",
|
|
3463
|
+
"tx",
|
|
3464
|
+
"const",
|
|
3465
|
+
"events",
|
|
3466
|
+
"errors",
|
|
3467
|
+
"apis",
|
|
3468
|
+
"extensions",
|
|
3469
|
+
"rpc"
|
|
3470
|
+
];
|
|
2652
3471
|
CATEGORY_ALIASES2 = {
|
|
2653
3472
|
query: "query",
|
|
2654
3473
|
tx: "tx",
|
|
@@ -2663,10 +3482,11 @@ var init_complete = __esm(() => {
|
|
|
2663
3482
|
api: "apis",
|
|
2664
3483
|
extensions: "extensions",
|
|
2665
3484
|
extension: "extensions",
|
|
2666
|
-
ext: "extensions"
|
|
3485
|
+
ext: "extensions",
|
|
3486
|
+
rpc: "rpc"
|
|
2667
3487
|
};
|
|
2668
|
-
NAMED_COMMANDS = ["chain", "account", "inspect", "hash", "sign", "
|
|
2669
|
-
CHAIN_SUBCOMMANDS = ["add", "
|
|
3488
|
+
NAMED_COMMANDS = ["chain", "account", "inspect", "hash", "sign", "completions"];
|
|
3489
|
+
CHAIN_SUBCOMMANDS = ["add", "info", "list", "remove", "update"];
|
|
2670
3490
|
ACCOUNT_SUBCOMMANDS = [
|
|
2671
3491
|
"add",
|
|
2672
3492
|
"create",
|
|
@@ -2697,23 +3517,94 @@ var init_complete = __esm(() => {
|
|
|
2697
3517
|
// src/cli.ts
|
|
2698
3518
|
import cac from "cac";
|
|
2699
3519
|
// package.json
|
|
2700
|
-
var version = "1.
|
|
3520
|
+
var version = "1.18.0";
|
|
2701
3521
|
|
|
2702
3522
|
// src/commands/account.ts
|
|
2703
3523
|
init_accounts_store();
|
|
2704
3524
|
init_accounts();
|
|
2705
3525
|
init_output();
|
|
2706
3526
|
import { readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
3527
|
+
|
|
3528
|
+
// src/core/pallet.ts
|
|
3529
|
+
init_errors();
|
|
3530
|
+
var MODL_PREFIX = new Uint8Array([109, 111, 100, 108]);
|
|
3531
|
+
var PALLET_ID_BYTES = 8;
|
|
3532
|
+
function derivePalletAccount(palletId) {
|
|
3533
|
+
if (palletId.length !== PALLET_ID_BYTES) {
|
|
3534
|
+
throw new CliError(`PalletId must be exactly ${PALLET_ID_BYTES} bytes (got ${palletId.length}).`);
|
|
3535
|
+
}
|
|
3536
|
+
const result = new Uint8Array(32);
|
|
3537
|
+
result.set(MODL_PREFIX, 0);
|
|
3538
|
+
result.set(palletId, 4);
|
|
3539
|
+
return result;
|
|
3540
|
+
}
|
|
3541
|
+
function parsePalletId(input) {
|
|
3542
|
+
if (input.startsWith("0x") || input.startsWith("0X")) {
|
|
3543
|
+
const hex = input.slice(2);
|
|
3544
|
+
if (hex.length !== PALLET_ID_BYTES * 2) {
|
|
3545
|
+
throw new CliError(`Invalid PalletId hex "${input}". Must be 0x followed by exactly ${PALLET_ID_BYTES * 2} hex characters.`);
|
|
3546
|
+
}
|
|
3547
|
+
if (!/^[0-9a-fA-F]+$/.test(hex)) {
|
|
3548
|
+
throw new CliError(`Invalid PalletId hex "${input}". Contains non-hex characters.`);
|
|
3549
|
+
}
|
|
3550
|
+
const bytes2 = new Uint8Array(PALLET_ID_BYTES);
|
|
3551
|
+
for (let i = 0;i < PALLET_ID_BYTES; i++) {
|
|
3552
|
+
bytes2[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
3553
|
+
}
|
|
3554
|
+
return bytes2;
|
|
3555
|
+
}
|
|
3556
|
+
if (input.length !== PALLET_ID_BYTES) {
|
|
3557
|
+
throw new CliError(`Invalid PalletId "${input}". Must be ${PALLET_ID_BYTES} ASCII characters or 0x-prefixed hex.`);
|
|
3558
|
+
}
|
|
3559
|
+
const bytes = new Uint8Array(PALLET_ID_BYTES);
|
|
3560
|
+
for (let i = 0;i < PALLET_ID_BYTES; i++) {
|
|
3561
|
+
const code = input.charCodeAt(i);
|
|
3562
|
+
if (code > 127) {
|
|
3563
|
+
throw new CliError(`Invalid PalletId "${input}". ASCII form must contain only ASCII bytes.`);
|
|
3564
|
+
}
|
|
3565
|
+
bytes[i] = code;
|
|
3566
|
+
}
|
|
3567
|
+
return bytes;
|
|
3568
|
+
}
|
|
3569
|
+
function formatPalletId(palletId) {
|
|
3570
|
+
const allPrintable = palletId.every((b) => b >= 32 && b <= 126);
|
|
3571
|
+
if (allPrintable) {
|
|
3572
|
+
return Array.from(palletId, (b) => String.fromCharCode(b)).join("");
|
|
3573
|
+
}
|
|
3574
|
+
return `0x${Array.from(palletId, (b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
// src/core/parachain.ts
|
|
3578
|
+
var SOVEREIGN_ACCOUNT_TYPES = ["child", "sibling"];
|
|
3579
|
+
var PREFIXES = {
|
|
3580
|
+
child: new Uint8Array([112, 97, 114, 97]),
|
|
3581
|
+
sibling: new Uint8Array([115, 105, 98, 108])
|
|
3582
|
+
};
|
|
3583
|
+
function deriveSovereignAccount(paraId, type) {
|
|
3584
|
+
const result = new Uint8Array(32);
|
|
3585
|
+
result.set(PREFIXES[type], 0);
|
|
3586
|
+
new DataView(result.buffer).setUint32(4, paraId, true);
|
|
3587
|
+
return result;
|
|
3588
|
+
}
|
|
3589
|
+
function isValidParaId(value) {
|
|
3590
|
+
return Number.isInteger(value) && value >= 0 && value <= 4294967295;
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3593
|
+
// src/commands/account.ts
|
|
2707
3594
|
var ACCOUNT_HELP = `
|
|
2708
3595
|
${BOLD}Usage:${RESET}
|
|
2709
3596
|
$ dot account add <name> <ss58|hex> Add a watch-only address (no secret)
|
|
2710
3597
|
$ dot account add <name> --secret <s> [--path <derivation>] Import from BIP39 mnemonic
|
|
2711
3598
|
$ dot account add <name> --env <VAR> [--path <derivation>] Import account backed by env variable
|
|
3599
|
+
$ dot account add <name> --parachain <id> --parachain-type <t> Derive a parachain sovereign (t = child|sibling)
|
|
3600
|
+
$ dot account add <name> --pallet-id <8 chars or 0x hex> Derive a pallet sovereign (e.g. py/trsry)
|
|
2712
3601
|
$ dot account create|new <name> [--path <derivation>] Create a new account
|
|
2713
3602
|
$ dot account import <file> Batch-import accounts from a file
|
|
2714
3603
|
$ dot account export [names...] Export accounts to stdout
|
|
2715
3604
|
$ dot account derive <source> <new-name> --path <derivation> Derive a child account
|
|
2716
3605
|
$ dot account inspect <input> [--prefix <N>] [--show-secret] Inspect an account/address/key
|
|
3606
|
+
$ dot account inspect --pallet-id <id> [--prefix <N>] Derive a pallet sovereign (no save — script-friendly)
|
|
3607
|
+
$ dot account inspect --parachain <id> --parachain-type <t> Derive a parachain sovereign (no save — script-friendly)
|
|
2717
3608
|
$ dot account list List all accounts
|
|
2718
3609
|
$ dot account remove|delete <name> [name2] ... Remove stored account(s)
|
|
2719
3610
|
|
|
@@ -2721,6 +3612,10 @@ ${BOLD}Examples:${RESET}
|
|
|
2721
3612
|
$ dot account add treasury 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
|
|
2722
3613
|
$ dot account add treasury --secret "word1 word2 ... word12"
|
|
2723
3614
|
$ dot account add ci-signer --env MY_SECRET --path //ci
|
|
3615
|
+
$ dot account add Treasury --pallet-id py/trsry
|
|
3616
|
+
$ dot account add Bounties --pallet-id 0x70792f626f756e74
|
|
3617
|
+
$ dot account add People --parachain 1004 --parachain-type child
|
|
3618
|
+
$ dot account add People-Sibling --parachain 1004 --parachain-type sibling
|
|
2724
3619
|
$ dot account create my-validator
|
|
2725
3620
|
$ dot account create my-staking --path //staking
|
|
2726
3621
|
$ dot account create multi --path //polkadot//0/wallet
|
|
@@ -2736,6 +3631,8 @@ ${BOLD}Examples:${RESET}
|
|
|
2736
3631
|
$ dot account inspect dave --show-secret
|
|
2737
3632
|
$ dot account inspect 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
|
|
2738
3633
|
$ dot account inspect 0xd435...a27d --prefix 0
|
|
3634
|
+
$ dot account inspect --pallet-id py/trsry --prefix 0
|
|
3635
|
+
$ dot account inspect --parachain 1004 --parachain-type child
|
|
2739
3636
|
$ dot account list
|
|
2740
3637
|
$ dot account remove my-validator stale-key
|
|
2741
3638
|
|
|
@@ -2744,7 +3641,7 @@ ${YELLOW}Note: Secrets are stored unencrypted in ~/.polkadot/accounts.json.
|
|
|
2744
3641
|
Hex seed import (0x...) is not supported via CLI.${RESET}
|
|
2745
3642
|
`.trimStart();
|
|
2746
3643
|
function registerAccountCommands(cli) {
|
|
2747
|
-
cli.command("account [action] [...names]", "Manage local accounts (create, import, list, remove, export)").alias("accounts").option("--secret <value>", "Secret key (mnemonic or hex seed) for import").option("--env <varName>", "Environment variable name holding the secret").option("--path <derivation>", "Derivation path (e.g. //staking, //polkadot//0/wallet)").option("--prefix <number>", "SS58 prefix for address encoding (default: 42)").option("--file <path>", "Input/output file for batch import/export").option("--overwrite", "Overwrite existing accounts on batch import").option("--dry-run", "Preview batch import without applying changes").option("--include-secrets", "Include secrets in export (redacted by default)").option("--watch-only", "Export only watch-only accounts").option("--show-secret", "Reveal the 64-byte sr25519 expanded private key (inspect only)").action(async (action, names, opts) => {
|
|
3644
|
+
cli.command("account [action] [...names]", "Manage local accounts (create, import, list, remove, export)").alias("accounts").option("--secret <value>", "Secret key (mnemonic or hex seed) for import").option("--env <varName>", "Environment variable name holding the secret").option("--path <derivation>", "Derivation path (e.g. //staking, //polkadot//0/wallet)").option("--parachain <id>", "Derive a parachain sovereign account (requires --parachain-type)").option("--parachain-type <type>", "Parachain sovereign type: child or sibling").option("--pallet-id <id>", "Derive a pallet sovereign account from an 8-byte PalletId").option("--prefix <number>", "SS58 prefix for address encoding (default: 42)").option("--file <path>", "Input/output file for batch import/export").option("--overwrite", "Overwrite existing accounts on batch import").option("--dry-run", "Preview batch import without applying changes").option("--include-secrets", "Include secrets in export (redacted by default)").option("--watch-only", "Export only watch-only accounts").option("--show-secret", "Reveal the 64-byte sr25519 expanded private key (inspect only)").action(async (action, names, opts) => {
|
|
2748
3645
|
if (!action) {
|
|
2749
3646
|
if (process.argv[2] === "accounts")
|
|
2750
3647
|
return accountList(opts);
|
|
@@ -2756,8 +3653,13 @@ function registerAccountCommands(cli) {
|
|
|
2756
3653
|
case "create":
|
|
2757
3654
|
return accountCreate(names[0], opts);
|
|
2758
3655
|
case "add":
|
|
2759
|
-
if (opts.secret || opts.env)
|
|
3656
|
+
if (opts.secret || opts.env) {
|
|
3657
|
+
const hasDerivation = opts.parachain != null || opts.palletId != null || process.argv.includes("--parachain") || process.argv.includes("--pallet-id") || process.argv.some((a) => a.startsWith("--parachain=") || a.startsWith("--pallet-id="));
|
|
3658
|
+
if (hasDerivation) {
|
|
3659
|
+
throw new Error("Derivation flags (--parachain, --pallet-id) cannot be combined with --secret or --env. A derived sovereign account has no secret.");
|
|
3660
|
+
}
|
|
2760
3661
|
return accountImport(names[0], opts);
|
|
3662
|
+
}
|
|
2761
3663
|
return accountAddWatchOnly(names[0], names[1], opts);
|
|
2762
3664
|
case "import":
|
|
2763
3665
|
return accountBatchImport(names[0], opts);
|
|
@@ -2913,10 +3815,16 @@ async function accountAddWatchOnly(name, address, opts = {}) {
|
|
|
2913
3815
|
console.error("Usage: dot account add <name> <ss58-address|0x-public-key>");
|
|
2914
3816
|
process.exit(1);
|
|
2915
3817
|
}
|
|
2916
|
-
|
|
3818
|
+
const sovereignSource = resolveSovereignSource(opts);
|
|
3819
|
+
if (sovereignSource && address) {
|
|
3820
|
+
throw new Error("Cannot combine a positional address with --parachain or --pallet-id. Pass either an address OR a derivation flag, not both.");
|
|
3821
|
+
}
|
|
3822
|
+
if (!sovereignSource && !address) {
|
|
2917
3823
|
console.error(`Address is required.
|
|
2918
3824
|
`);
|
|
2919
3825
|
console.error("Usage: dot account add <name> <ss58-address|0x-public-key>");
|
|
3826
|
+
console.error(" dot account add <name> --parachain <id> --parachain-type <child|sibling>");
|
|
3827
|
+
console.error(" dot account add <name> --pallet-id <8 chars or 0x hex>");
|
|
2920
3828
|
process.exit(1);
|
|
2921
3829
|
}
|
|
2922
3830
|
if (isDevAccount(name)) {
|
|
@@ -2927,7 +3835,10 @@ async function accountAddWatchOnly(name, address, opts = {}) {
|
|
|
2927
3835
|
throw new Error(`Account "${name}" already exists.`);
|
|
2928
3836
|
}
|
|
2929
3837
|
let hexPub;
|
|
2930
|
-
if (
|
|
3838
|
+
if (sovereignSource) {
|
|
3839
|
+
const accountId = sovereignSource.kind === "parachain" ? deriveSovereignAccount(sovereignSource.paraId, sovereignSource.type) : derivePalletAccount(sovereignSource.palletId);
|
|
3840
|
+
hexPub = publicKeyToHex(accountId);
|
|
3841
|
+
} else if (isHexPublicKey(address)) {
|
|
2931
3842
|
hexPub = address;
|
|
2932
3843
|
} else {
|
|
2933
3844
|
try {
|
|
@@ -2937,21 +3848,99 @@ async function accountAddWatchOnly(name, address, opts = {}) {
|
|
|
2937
3848
|
throw new Error(`Invalid address "${address}". Expected an SS58 address or 0x-prefixed 32-byte hex public key.`);
|
|
2938
3849
|
}
|
|
2939
3850
|
}
|
|
3851
|
+
let persistedSource;
|
|
3852
|
+
if (sovereignSource?.kind === "pallet") {
|
|
3853
|
+
persistedSource = {
|
|
3854
|
+
kind: "pallet",
|
|
3855
|
+
palletId: `0x${Array.from(sovereignSource.palletId, (b) => b.toString(16).padStart(2, "0")).join("")}`
|
|
3856
|
+
};
|
|
3857
|
+
} else if (sovereignSource?.kind === "parachain") {
|
|
3858
|
+
persistedSource = {
|
|
3859
|
+
kind: "parachain",
|
|
3860
|
+
paraId: sovereignSource.paraId,
|
|
3861
|
+
type: sovereignSource.type
|
|
3862
|
+
};
|
|
3863
|
+
}
|
|
2940
3864
|
accountsFile.accounts.push({
|
|
2941
3865
|
name,
|
|
2942
3866
|
publicKey: hexPub,
|
|
2943
|
-
derivationPath: ""
|
|
3867
|
+
derivationPath: "",
|
|
3868
|
+
...persistedSource ? { source: persistedSource } : {}
|
|
2944
3869
|
});
|
|
2945
3870
|
await saveAccounts(accountsFile);
|
|
2946
3871
|
if (isJsonOutput(opts)) {
|
|
2947
|
-
|
|
3872
|
+
const payload = {
|
|
3873
|
+
name,
|
|
3874
|
+
address: toSs58(hexPub),
|
|
3875
|
+
watchOnly: true
|
|
3876
|
+
};
|
|
3877
|
+
if (sovereignSource?.kind === "parachain") {
|
|
3878
|
+
payload.derivation = {
|
|
3879
|
+
kind: "parachain",
|
|
3880
|
+
paraId: sovereignSource.paraId,
|
|
3881
|
+
type: sovereignSource.type
|
|
3882
|
+
};
|
|
3883
|
+
} else if (sovereignSource?.kind === "pallet") {
|
|
3884
|
+
payload.derivation = {
|
|
3885
|
+
kind: "pallet",
|
|
3886
|
+
palletId: formatPalletId(sovereignSource.palletId),
|
|
3887
|
+
palletIdHex: `0x${Array.from(sovereignSource.palletId, (b) => b.toString(16).padStart(2, "0")).join("")}`
|
|
3888
|
+
};
|
|
3889
|
+
}
|
|
3890
|
+
console.log(formatJson(payload));
|
|
2948
3891
|
return;
|
|
2949
3892
|
}
|
|
2950
3893
|
printHeading("Account Added (watch-only)");
|
|
2951
3894
|
console.log(` ${BOLD}Name:${RESET} ${name}`);
|
|
2952
3895
|
console.log(` ${BOLD}Address:${RESET} ${toSs58(hexPub)}`);
|
|
3896
|
+
if (sovereignSource?.kind === "parachain") {
|
|
3897
|
+
console.log(` ${BOLD}Source:${RESET} parachain ${sovereignSource.paraId} (${sovereignSource.type} sovereign)`);
|
|
3898
|
+
} else if (sovereignSource?.kind === "pallet") {
|
|
3899
|
+
const display = formatPalletId(sovereignSource.palletId);
|
|
3900
|
+
const hex = `0x${Array.from(sovereignSource.palletId, (b) => b.toString(16).padStart(2, "0")).join("")}`;
|
|
3901
|
+
console.log(` ${BOLD}Source:${RESET} pallet ${display} (${hex})`);
|
|
3902
|
+
}
|
|
2953
3903
|
console.log();
|
|
2954
3904
|
}
|
|
3905
|
+
function rawArgValue(flag) {
|
|
3906
|
+
const argv = process.argv;
|
|
3907
|
+
for (let i = 0;i < argv.length; i++) {
|
|
3908
|
+
if (argv[i] === flag && i + 1 < argv.length)
|
|
3909
|
+
return argv[i + 1];
|
|
3910
|
+
const prefix = `${flag}=`;
|
|
3911
|
+
if (argv[i]?.startsWith(prefix))
|
|
3912
|
+
return argv[i].slice(prefix.length);
|
|
3913
|
+
}
|
|
3914
|
+
return;
|
|
3915
|
+
}
|
|
3916
|
+
function resolveSovereignSource(opts) {
|
|
3917
|
+
const rawPalletId = rawArgValue("--pallet-id") ?? opts.palletId;
|
|
3918
|
+
const rawParachain = rawArgValue("--parachain") ?? opts.parachain;
|
|
3919
|
+
if (rawParachain != null && rawPalletId != null) {
|
|
3920
|
+
throw new Error("--parachain and --pallet-id are mutually exclusive. Pass only one derivation flag.");
|
|
3921
|
+
}
|
|
3922
|
+
if (rawParachain != null) {
|
|
3923
|
+
const paraId = Number(rawParachain);
|
|
3924
|
+
if (!isValidParaId(paraId)) {
|
|
3925
|
+
throw new Error(`Invalid parachain ID "${rawParachain}". Must be a non-negative integer (0 to 4294967295).`);
|
|
3926
|
+
}
|
|
3927
|
+
if (!opts.parachainType) {
|
|
3928
|
+
throw new Error("--parachain-type is required when --parachain is given. Use --parachain-type child or --parachain-type sibling.");
|
|
3929
|
+
}
|
|
3930
|
+
const type = opts.parachainType.toLowerCase();
|
|
3931
|
+
if (type !== "child" && type !== "sibling") {
|
|
3932
|
+
throw new Error(`Unknown parachain account type "${opts.parachainType}". Valid types: child, sibling.`);
|
|
3933
|
+
}
|
|
3934
|
+
return { kind: "parachain", paraId, type };
|
|
3935
|
+
}
|
|
3936
|
+
if (rawPalletId != null) {
|
|
3937
|
+
return { kind: "pallet", palletId: parsePalletId(String(rawPalletId)) };
|
|
3938
|
+
}
|
|
3939
|
+
if (opts.parachainType != null) {
|
|
3940
|
+
throw new Error("--parachain-type requires --parachain.");
|
|
3941
|
+
}
|
|
3942
|
+
return;
|
|
3943
|
+
}
|
|
2955
3944
|
async function accountDerive(sourceName, newName, opts) {
|
|
2956
3945
|
if (!sourceName) {
|
|
2957
3946
|
console.error(`Source account name is required.
|
|
@@ -3035,69 +4024,134 @@ async function accountDerive(sourceName, newName, opts) {
|
|
|
3035
4024
|
console.log();
|
|
3036
4025
|
}
|
|
3037
4026
|
}
|
|
4027
|
+
function resolveAddress(account) {
|
|
4028
|
+
if (isWatchOnly(account)) {
|
|
4029
|
+
return account.publicKey ? toSs58(account.publicKey) : "n/a";
|
|
4030
|
+
}
|
|
4031
|
+
if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
4032
|
+
const pubKey = account.publicKey || tryDerivePublicKey(account.secret.env, account.derivationPath) || "";
|
|
4033
|
+
return pubKey ? toSs58(pubKey) : "n/a";
|
|
4034
|
+
}
|
|
4035
|
+
return toSs58(account.publicKey);
|
|
4036
|
+
}
|
|
4037
|
+
function buildAttributes(account) {
|
|
4038
|
+
const attrs = [];
|
|
4039
|
+
if (account.derivationPath)
|
|
4040
|
+
attrs.push({ label: "path", value: account.derivationPath });
|
|
4041
|
+
if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
4042
|
+
attrs.push({ label: "env", value: `$${account.secret.env}` });
|
|
4043
|
+
}
|
|
4044
|
+
if (account.source) {
|
|
4045
|
+
if (account.source.kind === "pallet") {
|
|
4046
|
+
const bytes = parsePalletId(account.source.palletId);
|
|
4047
|
+
attrs.push({
|
|
4048
|
+
label: "pallet-id",
|
|
4049
|
+
value: `${formatPalletId(bytes)} (${account.source.palletId})`
|
|
4050
|
+
});
|
|
4051
|
+
} else {
|
|
4052
|
+
attrs.push({ label: "parachain", value: String(account.source.paraId) });
|
|
4053
|
+
attrs.push({ label: "parachain-type", value: account.source.type });
|
|
4054
|
+
}
|
|
4055
|
+
}
|
|
4056
|
+
return attrs;
|
|
4057
|
+
}
|
|
4058
|
+
function buildRow(account) {
|
|
4059
|
+
return {
|
|
4060
|
+
account,
|
|
4061
|
+
kind: classifyAccount(account),
|
|
4062
|
+
address: resolveAddress(account),
|
|
4063
|
+
attributes: buildAttributes(account)
|
|
4064
|
+
};
|
|
4065
|
+
}
|
|
4066
|
+
var SECTION_ORDER = [
|
|
4067
|
+
{ kind: "signer", title: "Signers" },
|
|
4068
|
+
{ kind: "watch-only", title: "Watch-only" },
|
|
4069
|
+
{ kind: "pallet", title: "Pallet Sovereigns" },
|
|
4070
|
+
{ kind: "parachain", title: "Parachain Sovereigns" }
|
|
4071
|
+
];
|
|
4072
|
+
function printAccountSection(title, rows) {
|
|
4073
|
+
if (rows.length === 0)
|
|
4074
|
+
return;
|
|
4075
|
+
const nameWidth = Math.max(...rows.map((r) => r.name.length));
|
|
4076
|
+
printHeading(title);
|
|
4077
|
+
for (const row of rows) {
|
|
4078
|
+
const namePad = row.name.padEnd(nameWidth);
|
|
4079
|
+
console.log(` ${CYAN}${namePad}${RESET} ${row.address}`);
|
|
4080
|
+
if (row.attributes.length === 0)
|
|
4081
|
+
continue;
|
|
4082
|
+
const labelWidth = Math.max(...row.attributes.map((a) => a.label.length)) + 1;
|
|
4083
|
+
for (let i = 0;i < row.attributes.length; i++) {
|
|
4084
|
+
const isLast = i === row.attributes.length - 1;
|
|
4085
|
+
const connector = isLast ? "└─" : "├─";
|
|
4086
|
+
const labelText = `${row.attributes[i].label}:`.padEnd(labelWidth + 1);
|
|
4087
|
+
console.log(` ${DIM}${connector}${RESET} ${DIM}${labelText}${RESET}${row.attributes[i].value}`);
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
3038
4091
|
async function accountList(opts = {}) {
|
|
3039
4092
|
const accountsFile = await loadAccounts();
|
|
3040
4093
|
if (isJsonOutput(opts)) {
|
|
3041
4094
|
const dev = DEV_NAMES.map((name) => ({
|
|
3042
4095
|
name: name.charAt(0).toUpperCase() + name.slice(1),
|
|
3043
|
-
address: getDevAddress(name)
|
|
4096
|
+
address: getDevAddress(name),
|
|
4097
|
+
kind: "dev"
|
|
3044
4098
|
}));
|
|
3045
4099
|
const stored = accountsFile.accounts.map((account) => {
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
address = account.publicKey ? toSs58(account.publicKey) : undefined;
|
|
3049
|
-
} else if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
3050
|
-
let pubKey = account.publicKey;
|
|
3051
|
-
if (!pubKey) {
|
|
3052
|
-
pubKey = tryDerivePublicKey(account.secret.env, account.derivationPath) ?? "";
|
|
3053
|
-
}
|
|
3054
|
-
address = pubKey ? toSs58(pubKey) : undefined;
|
|
3055
|
-
} else {
|
|
3056
|
-
address = toSs58(account.publicKey);
|
|
3057
|
-
}
|
|
3058
|
-
return {
|
|
4100
|
+
const kind = classifyAccount(account);
|
|
4101
|
+
const entry = {
|
|
3059
4102
|
name: account.name,
|
|
3060
|
-
address,
|
|
3061
|
-
|
|
3062
|
-
watchOnly: isWatchOnly(account)
|
|
3063
|
-
env: account.secret !== undefined && isEnvSecret(account.secret) ? account.secret.env : undefined
|
|
4103
|
+
address: resolveAddress(account),
|
|
4104
|
+
kind,
|
|
4105
|
+
watchOnly: isWatchOnly(account)
|
|
3064
4106
|
};
|
|
4107
|
+
if (account.derivationPath)
|
|
4108
|
+
entry.derivationPath = account.derivationPath;
|
|
4109
|
+
if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
4110
|
+
entry.env = account.secret.env;
|
|
4111
|
+
}
|
|
4112
|
+
if (account.source) {
|
|
4113
|
+
if (account.source.kind === "pallet") {
|
|
4114
|
+
const bytes = parsePalletId(account.source.palletId);
|
|
4115
|
+
entry.source = {
|
|
4116
|
+
kind: "pallet",
|
|
4117
|
+
palletId: formatPalletId(bytes),
|
|
4118
|
+
palletIdHex: account.source.palletId
|
|
4119
|
+
};
|
|
4120
|
+
} else {
|
|
4121
|
+
entry.source = account.source;
|
|
4122
|
+
}
|
|
4123
|
+
}
|
|
4124
|
+
return entry;
|
|
3065
4125
|
});
|
|
3066
4126
|
console.log(formatJson({ dev, stored }));
|
|
3067
4127
|
return;
|
|
3068
4128
|
}
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
4129
|
+
const devRows = DEV_NAMES.map((name) => ({
|
|
4130
|
+
name: name.charAt(0).toUpperCase() + name.slice(1),
|
|
4131
|
+
address: getDevAddress(name),
|
|
4132
|
+
attributes: []
|
|
4133
|
+
}));
|
|
4134
|
+
printAccountSection("Dev Accounts", devRows);
|
|
4135
|
+
const buckets = new Map;
|
|
4136
|
+
for (const account of accountsFile.accounts) {
|
|
4137
|
+
const row = buildRow(account);
|
|
4138
|
+
const arr = buckets.get(row.kind) ?? [];
|
|
4139
|
+
arr.push(row);
|
|
4140
|
+
buckets.set(row.kind, arr);
|
|
4141
|
+
}
|
|
4142
|
+
for (const { kind, title } of SECTION_ORDER) {
|
|
4143
|
+
const rows = buckets.get(kind);
|
|
4144
|
+
if (!rows || rows.length === 0)
|
|
4145
|
+
continue;
|
|
4146
|
+
printAccountSection(title, rows.map((r) => ({
|
|
4147
|
+
name: r.account.name,
|
|
4148
|
+
address: r.address,
|
|
4149
|
+
attributes: r.attributes
|
|
4150
|
+
})));
|
|
3074
4151
|
}
|
|
3075
|
-
if (accountsFile.accounts.length
|
|
3076
|
-
printHeading("Stored Accounts");
|
|
3077
|
-
for (const account of accountsFile.accounts) {
|
|
3078
|
-
let displayName = account.name;
|
|
3079
|
-
if (account.derivationPath) {
|
|
3080
|
-
displayName += ` (${account.derivationPath})`;
|
|
3081
|
-
}
|
|
3082
|
-
let address;
|
|
3083
|
-
if (isWatchOnly(account)) {
|
|
3084
|
-
displayName += " (watch-only)";
|
|
3085
|
-
address = account.publicKey ? toSs58(account.publicKey) : "n/a";
|
|
3086
|
-
} else if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
3087
|
-
displayName += ` (env: ${account.secret.env})`;
|
|
3088
|
-
let pubKey = account.publicKey;
|
|
3089
|
-
if (!pubKey) {
|
|
3090
|
-
pubKey = tryDerivePublicKey(account.secret.env, account.derivationPath) ?? "";
|
|
3091
|
-
}
|
|
3092
|
-
address = pubKey ? toSs58(pubKey) : "n/a";
|
|
3093
|
-
} else {
|
|
3094
|
-
address = toSs58(account.publicKey);
|
|
3095
|
-
}
|
|
3096
|
-
printItem(displayName, address);
|
|
3097
|
-
}
|
|
3098
|
-
} else {
|
|
4152
|
+
if (accountsFile.accounts.length === 0) {
|
|
3099
4153
|
printHeading("Stored Accounts");
|
|
3100
|
-
console.log(
|
|
4154
|
+
console.log(` ${DIM}(none)${RESET}`);
|
|
3101
4155
|
}
|
|
3102
4156
|
console.log();
|
|
3103
4157
|
}
|
|
@@ -3145,10 +4199,20 @@ async function accountRemove(names, opts = {}) {
|
|
|
3145
4199
|
}
|
|
3146
4200
|
}
|
|
3147
4201
|
async function accountInspect(input, opts) {
|
|
3148
|
-
|
|
4202
|
+
const sovereignSource = resolveSovereignSource({
|
|
4203
|
+
parachain: opts.parachain,
|
|
4204
|
+
parachainType: opts.parachainType,
|
|
4205
|
+
palletId: opts.palletId
|
|
4206
|
+
});
|
|
4207
|
+
if (sovereignSource && input) {
|
|
4208
|
+
throw new Error("Cannot combine a positional input with --parachain or --pallet-id. Pass either an existing-account input OR a derivation flag, not both.");
|
|
4209
|
+
}
|
|
4210
|
+
if (!sovereignSource && !input) {
|
|
3149
4211
|
console.error(`Input is required.
|
|
3150
4212
|
`);
|
|
3151
4213
|
console.error("Usage: dot account inspect <name|ss58-address|0x-public-key> [--prefix <N>]");
|
|
4214
|
+
console.error(" dot account inspect --pallet-id <id> [--prefix <N>]");
|
|
4215
|
+
console.error(" dot account inspect --parachain <id> --parachain-type <child|sibling> [--prefix <N>]");
|
|
3152
4216
|
process.exit(1);
|
|
3153
4217
|
}
|
|
3154
4218
|
const prefix = opts.prefix != null ? Number(opts.prefix) : 42;
|
|
@@ -3160,11 +4224,32 @@ async function accountInspect(input, opts) {
|
|
|
3160
4224
|
let publicKeyHex;
|
|
3161
4225
|
let bandersnatch;
|
|
3162
4226
|
let hasSecret = false;
|
|
3163
|
-
|
|
4227
|
+
let storedAccount;
|
|
4228
|
+
let isDev = false;
|
|
4229
|
+
let virtualSource;
|
|
4230
|
+
if (sovereignSource) {
|
|
4231
|
+
if (sovereignSource.kind === "pallet") {
|
|
4232
|
+
const accountId = derivePalletAccount(sovereignSource.palletId);
|
|
4233
|
+
publicKeyHex = publicKeyToHex(accountId);
|
|
4234
|
+
virtualSource = {
|
|
4235
|
+
kind: "pallet",
|
|
4236
|
+
palletIdHex: `0x${Array.from(sovereignSource.palletId, (b) => b.toString(16).padStart(2, "0")).join("")}`
|
|
4237
|
+
};
|
|
4238
|
+
} else {
|
|
4239
|
+
const accountId = deriveSovereignAccount(sovereignSource.paraId, sovereignSource.type);
|
|
4240
|
+
publicKeyHex = publicKeyToHex(accountId);
|
|
4241
|
+
virtualSource = {
|
|
4242
|
+
kind: "parachain",
|
|
4243
|
+
paraId: sovereignSource.paraId,
|
|
4244
|
+
type: sovereignSource.type
|
|
4245
|
+
};
|
|
4246
|
+
}
|
|
4247
|
+
} else if (isDevAccount(input)) {
|
|
3164
4248
|
name = input.charAt(0).toUpperCase() + input.slice(1).toLowerCase();
|
|
3165
4249
|
const devAddr = getDevAddress(input);
|
|
3166
4250
|
publicKeyHex = publicKeyToHex(fromSs58(devAddr));
|
|
3167
4251
|
hasSecret = true;
|
|
4252
|
+
isDev = true;
|
|
3168
4253
|
} else {
|
|
3169
4254
|
const accountsFile = await loadAccounts();
|
|
3170
4255
|
const account = findAccount(accountsFile, input);
|
|
@@ -3172,6 +4257,7 @@ async function accountInspect(input, opts) {
|
|
|
3172
4257
|
name = account.name;
|
|
3173
4258
|
bandersnatch = account.bandersnatch;
|
|
3174
4259
|
hasSecret = account.secret !== undefined;
|
|
4260
|
+
storedAccount = account;
|
|
3175
4261
|
if (account.publicKey) {
|
|
3176
4262
|
publicKeyHex = account.publicKey;
|
|
3177
4263
|
} else if (account.secret !== undefined && isEnvSecret(account.secret)) {
|
|
@@ -3215,10 +4301,74 @@ async function accountInspect(input, opts) {
|
|
|
3215
4301
|
process.exit(1);
|
|
3216
4302
|
}
|
|
3217
4303
|
}
|
|
4304
|
+
let kindLabel;
|
|
4305
|
+
let sourceLine;
|
|
4306
|
+
let derivationLine;
|
|
4307
|
+
let envLine;
|
|
4308
|
+
if (virtualSource?.kind === "pallet") {
|
|
4309
|
+
kindLabel = "pallet sovereign";
|
|
4310
|
+
const bytes = parsePalletId(virtualSource.palletIdHex);
|
|
4311
|
+
sourceLine = `PalletId ${formatPalletId(bytes)} (${virtualSource.palletIdHex})`;
|
|
4312
|
+
} else if (virtualSource?.kind === "parachain") {
|
|
4313
|
+
kindLabel = `parachain sovereign (${virtualSource.type})`;
|
|
4314
|
+
sourceLine = `parachain ${virtualSource.paraId}`;
|
|
4315
|
+
} else if (isDev) {
|
|
4316
|
+
kindLabel = "dev";
|
|
4317
|
+
} else if (storedAccount) {
|
|
4318
|
+
const k = classifyAccount(storedAccount);
|
|
4319
|
+
if (k === "pallet" && storedAccount.source?.kind === "pallet") {
|
|
4320
|
+
kindLabel = "pallet sovereign";
|
|
4321
|
+
const bytes = parsePalletId(storedAccount.source.palletId);
|
|
4322
|
+
sourceLine = `PalletId ${formatPalletId(bytes)} (${storedAccount.source.palletId})`;
|
|
4323
|
+
} else if (k === "parachain" && storedAccount.source?.kind === "parachain") {
|
|
4324
|
+
kindLabel = `parachain sovereign (${storedAccount.source.type})`;
|
|
4325
|
+
sourceLine = `parachain ${storedAccount.source.paraId}`;
|
|
4326
|
+
} else if (k === "signer") {
|
|
4327
|
+
kindLabel = "signer";
|
|
4328
|
+
} else {
|
|
4329
|
+
kindLabel = "watch-only";
|
|
4330
|
+
}
|
|
4331
|
+
if (storedAccount.derivationPath)
|
|
4332
|
+
derivationLine = storedAccount.derivationPath;
|
|
4333
|
+
if (storedAccount.secret !== undefined && isEnvSecret(storedAccount.secret)) {
|
|
4334
|
+
envLine = `$${storedAccount.secret.env}`;
|
|
4335
|
+
}
|
|
4336
|
+
}
|
|
3218
4337
|
if (isJsonOutput(opts)) {
|
|
3219
4338
|
const result = { publicKey: publicKeyHex, ss58, prefix };
|
|
3220
4339
|
if (name)
|
|
3221
4340
|
result.name = name;
|
|
4341
|
+
if (kindLabel)
|
|
4342
|
+
result.kind = kindLabel;
|
|
4343
|
+
if (virtualSource?.kind === "pallet") {
|
|
4344
|
+
const bytes = parsePalletId(virtualSource.palletIdHex);
|
|
4345
|
+
result.source = {
|
|
4346
|
+
kind: "pallet",
|
|
4347
|
+
palletId: formatPalletId(bytes),
|
|
4348
|
+
palletIdHex: virtualSource.palletIdHex
|
|
4349
|
+
};
|
|
4350
|
+
} else if (virtualSource?.kind === "parachain") {
|
|
4351
|
+
result.source = {
|
|
4352
|
+
kind: "parachain",
|
|
4353
|
+
paraId: virtualSource.paraId,
|
|
4354
|
+
type: virtualSource.type
|
|
4355
|
+
};
|
|
4356
|
+
} else if (storedAccount?.source) {
|
|
4357
|
+
if (storedAccount.source.kind === "pallet") {
|
|
4358
|
+
const bytes = parsePalletId(storedAccount.source.palletId);
|
|
4359
|
+
result.source = {
|
|
4360
|
+
kind: "pallet",
|
|
4361
|
+
palletId: formatPalletId(bytes),
|
|
4362
|
+
palletIdHex: storedAccount.source.palletId
|
|
4363
|
+
};
|
|
4364
|
+
} else {
|
|
4365
|
+
result.source = storedAccount.source;
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
if (derivationLine)
|
|
4369
|
+
result.derivationPath = derivationLine;
|
|
4370
|
+
if (envLine)
|
|
4371
|
+
result.env = envLine.replace(/^\$/, "");
|
|
3222
4372
|
if (bandersnatch && Object.keys(bandersnatch).length > 0)
|
|
3223
4373
|
result.bandersnatch = bandersnatch;
|
|
3224
4374
|
if (privateKeyHex)
|
|
@@ -3228,8 +4378,16 @@ async function accountInspect(input, opts) {
|
|
|
3228
4378
|
printHeading("Account Info");
|
|
3229
4379
|
if (name)
|
|
3230
4380
|
console.log(` ${BOLD}Name:${RESET} ${name}`);
|
|
4381
|
+
if (kindLabel)
|
|
4382
|
+
console.log(` ${BOLD}Kind:${RESET} ${kindLabel}`);
|
|
3231
4383
|
console.log(` ${BOLD}Public Key:${RESET} ${publicKeyHex}`);
|
|
3232
4384
|
console.log(` ${BOLD}SS58:${RESET} ${ss58}`);
|
|
4385
|
+
if (sourceLine)
|
|
4386
|
+
console.log(` ${BOLD}Source:${RESET} ${sourceLine}`);
|
|
4387
|
+
if (derivationLine)
|
|
4388
|
+
console.log(` ${BOLD}Derivation:${RESET} ${derivationLine}`);
|
|
4389
|
+
if (envLine)
|
|
4390
|
+
console.log(` ${BOLD}Env:${RESET} ${envLine}`);
|
|
3233
4391
|
if (bandersnatch && Object.keys(bandersnatch).length > 0) {
|
|
3234
4392
|
const entries = Object.entries(bandersnatch);
|
|
3235
4393
|
for (let i = 0;i < entries.length; i++) {
|
|
@@ -3533,6 +4691,53 @@ init_client();
|
|
|
3533
4691
|
init_metadata();
|
|
3534
4692
|
init_output();
|
|
3535
4693
|
import { readFile as readFile4, writeFile as writeFile4 } from "node:fs/promises";
|
|
4694
|
+
|
|
4695
|
+
// src/core/rpc.ts
|
|
4696
|
+
init_errors();
|
|
4697
|
+
import { createClient as createSubstrateClient } from "@polkadot-api/substrate-client";
|
|
4698
|
+
import { getWsProvider as getWsProvider2 } from "polkadot-api/ws";
|
|
4699
|
+
function suppressProviderNoise2() {
|
|
4700
|
+
const origError = console.error;
|
|
4701
|
+
console.error = (...args) => {
|
|
4702
|
+
if (typeof args[0] === "string" && args[0].includes("Unable to connect"))
|
|
4703
|
+
return;
|
|
4704
|
+
origError(...args);
|
|
4705
|
+
};
|
|
4706
|
+
return () => {
|
|
4707
|
+
console.error = origError;
|
|
4708
|
+
};
|
|
4709
|
+
}
|
|
4710
|
+
async function rpcRequest(rpcUrl, method, params, timeoutMs = 30000) {
|
|
4711
|
+
const restoreConsole = suppressProviderNoise2();
|
|
4712
|
+
const provider = getWsProvider2(rpcUrl, { timeout: 1e4 });
|
|
4713
|
+
const client = createSubstrateClient(provider);
|
|
4714
|
+
const controller = new AbortController;
|
|
4715
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
4716
|
+
try {
|
|
4717
|
+
return await client.request(method, params, controller.signal);
|
|
4718
|
+
} catch (err) {
|
|
4719
|
+
if (err instanceof Error && /Unable to connect/i.test(err.message)) {
|
|
4720
|
+
throw new ConnectionError(`Could not reach RPC ${Array.isArray(rpcUrl) ? rpcUrl.join(", ") : rpcUrl}: ${err.message}`);
|
|
4721
|
+
}
|
|
4722
|
+
throw err;
|
|
4723
|
+
} finally {
|
|
4724
|
+
clearTimeout(timer);
|
|
4725
|
+
try {
|
|
4726
|
+
client.destroy();
|
|
4727
|
+
} catch {}
|
|
4728
|
+
setTimeout(restoreConsole, 100);
|
|
4729
|
+
}
|
|
4730
|
+
}
|
|
4731
|
+
async function fetchRpcMethods(rpcUrl) {
|
|
4732
|
+
const result = await rpcRequest(rpcUrl, "rpc_methods", []);
|
|
4733
|
+
if (!result || !Array.isArray(result.methods)) {
|
|
4734
|
+
throw new ConnectionError("Node returned an unexpected response for rpc_methods (no methods array).");
|
|
4735
|
+
}
|
|
4736
|
+
return { methods: result.methods, version: result.version ?? 1 };
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4739
|
+
// src/commands/chain.ts
|
|
4740
|
+
init_rpc_registry();
|
|
3536
4741
|
var CHAIN_HELP = `
|
|
3537
4742
|
${BOLD}Usage:${RESET}
|
|
3538
4743
|
$ dot chain add <name> --rpc <url> Add a chain via WebSocket RPC
|
|
@@ -3540,6 +4745,8 @@ ${BOLD}Usage:${RESET}
|
|
|
3540
4745
|
$ dot chain update <name> Re-fetch metadata for a chain
|
|
3541
4746
|
$ dot chain update --all Re-fetch metadata for all configured chains
|
|
3542
4747
|
$ dot chain list List configured chains
|
|
4748
|
+
$ dot chain info <name> Show details for a single chain
|
|
4749
|
+
$ dot chain <name> Shortcut for \`chain info <name>\`
|
|
3543
4750
|
$ dot chain export [names...] Export chain configuration to stdout
|
|
3544
4751
|
$ dot chain import <file> Import chain configuration from a file
|
|
3545
4752
|
|
|
@@ -3549,6 +4756,9 @@ ${BOLD}Examples:${RESET}
|
|
|
3549
4756
|
$ dot chain add my-para --rpc wss://rpc.example.com --relay polkadot
|
|
3550
4757
|
$ dot chain add my-para --rpc wss://rpc.example.com --relay polkadot --parachain-id 2000
|
|
3551
4758
|
$ dot chain list
|
|
4759
|
+
$ dot chains -v
|
|
4760
|
+
$ dot chain info polkadot
|
|
4761
|
+
$ dot chain polkadot
|
|
3552
4762
|
$ dot chain update kusama
|
|
3553
4763
|
$ dot chain update --all
|
|
3554
4764
|
$ dot chain remove kusama
|
|
@@ -3561,7 +4771,7 @@ ${BOLD}Examples:${RESET}
|
|
|
3561
4771
|
$ dot chain import my-chains.json --no-metadata
|
|
3562
4772
|
`.trimStart();
|
|
3563
4773
|
function registerChainCommands(cli) {
|
|
3564
|
-
cli.command("chain [action] [...names]", "Manage chains (add, remove, update, list, export, import)").alias("chains").option("--all", "Update/export all configured chains").option("--relay <name>", "Parent relay chain for this parachain").option("--parachain-id <id>", "Parachain ID (auto-detected if omitted with --relay)").option("--file <path>", "Output/input file for export/import").option("--overwrite", "Overwrite existing chains on import").option("--dry-run", "Preview import without applying changes").option("--no-metadata", "Skip automatic metadata fetch after import").action(async (action, names, opts) => {
|
|
4774
|
+
cli.command("chain [action] [...names]", "Manage chains (add, remove, update, list, export, import)").alias("chains").option("--all", "Update/export all configured chains").option("--relay <name>", "Parent relay chain for this parachain").option("--parachain-id <id>", "Parachain ID (auto-detected if omitted with --relay)").option("--file <path>", "Output/input file for export/import").option("--overwrite", "Overwrite existing chains on import").option("--dry-run", "Preview import without applying changes").option("--no-metadata", "Skip automatic metadata fetch after import").option("-v, --verbose", "Show RPC endpoints in `chains` list output").action(async (action, names, opts) => {
|
|
3565
4775
|
if (!action) {
|
|
3566
4776
|
if (process.argv[2] === "chains")
|
|
3567
4777
|
return chainList(opts);
|
|
@@ -3575,20 +4785,39 @@ function registerChainCommands(cli) {
|
|
|
3575
4785
|
return chainRemove(names[0], opts);
|
|
3576
4786
|
case "list":
|
|
3577
4787
|
return chainList(opts);
|
|
4788
|
+
case "info":
|
|
4789
|
+
return chainInfo(names[0], opts);
|
|
3578
4790
|
case "update":
|
|
3579
4791
|
return chainUpdate(names[0], opts);
|
|
3580
4792
|
case "export":
|
|
3581
4793
|
return chainExport(names, opts);
|
|
3582
4794
|
case "import":
|
|
3583
4795
|
return chainImport(names[0], opts);
|
|
3584
|
-
default:
|
|
4796
|
+
default: {
|
|
4797
|
+
const config = await loadConfig();
|
|
4798
|
+
if (findChainName(config, action)) {
|
|
4799
|
+
return chainInfo(action, opts);
|
|
4800
|
+
}
|
|
3585
4801
|
console.error(`Unknown action "${action}".
|
|
3586
4802
|
`);
|
|
3587
4803
|
console.log(CHAIN_HELP);
|
|
3588
4804
|
process.exit(1);
|
|
4805
|
+
}
|
|
3589
4806
|
}
|
|
3590
4807
|
});
|
|
3591
4808
|
}
|
|
4809
|
+
async function refreshRpcMethods(chainName, rpcUrl, silent = false) {
|
|
4810
|
+
try {
|
|
4811
|
+
const { methods, version: version2 } = await fetchRpcMethods(rpcUrl);
|
|
4812
|
+
await saveRpcMethods(chainName, methods, version2);
|
|
4813
|
+
} catch (err) {
|
|
4814
|
+
if (!silent) {
|
|
4815
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
4816
|
+
process.stderr.write(`${YELLOW}Warning:${RESET} could not fetch rpc_methods — ${msg}
|
|
4817
|
+
`);
|
|
4818
|
+
}
|
|
4819
|
+
}
|
|
4820
|
+
}
|
|
3592
4821
|
async function chainAdd(name, opts) {
|
|
3593
4822
|
if (!name) {
|
|
3594
4823
|
console.error(`Chain name is required.
|
|
@@ -3617,6 +4846,7 @@ async function chainAdd(name, opts) {
|
|
|
3617
4846
|
process.stderr.write(`Fetching metadata...
|
|
3618
4847
|
`);
|
|
3619
4848
|
await fetchMetadataFromChain(clientHandle, name);
|
|
4849
|
+
await refreshRpcMethods(name, opts.rpc);
|
|
3620
4850
|
if (opts.relay) {
|
|
3621
4851
|
const config2 = await loadConfig();
|
|
3622
4852
|
const relayResolved = findChainName(config2, opts.relay);
|
|
@@ -3695,6 +4925,7 @@ async function chainList(opts = {}) {
|
|
|
3695
4925
|
console.log(formatJson({ chains }));
|
|
3696
4926
|
return;
|
|
3697
4927
|
}
|
|
4928
|
+
const verbose = opts.verbose === true;
|
|
3698
4929
|
printHeading("Configured Chains");
|
|
3699
4930
|
const parachainsByRelay = new Map;
|
|
3700
4931
|
const standalone = [];
|
|
@@ -3716,7 +4947,7 @@ async function chainList(opts = {}) {
|
|
|
3716
4947
|
for (const relayName of relayNames) {
|
|
3717
4948
|
const relayConfig = config.chains[relayName];
|
|
3718
4949
|
if (relayConfig) {
|
|
3719
|
-
printChainLine(" ", relayName, relayConfig);
|
|
4950
|
+
printChainLine(" ", relayName, relayConfig, "", verbose);
|
|
3720
4951
|
}
|
|
3721
4952
|
const paras = parachainsByRelay.get(relayName) ?? [];
|
|
3722
4953
|
for (let i = 0;i < paras.length; i++) {
|
|
@@ -3724,17 +4955,21 @@ async function chainList(opts = {}) {
|
|
|
3724
4955
|
const isLast = i === paras.length - 1;
|
|
3725
4956
|
const prefix = isLast ? " └─ " : " ├─ ";
|
|
3726
4957
|
const idSuffix = chainConfig.parachainId != null ? ` ${DIM}[${chainConfig.parachainId}]${RESET}` : "";
|
|
3727
|
-
printChainLine(prefix, name, chainConfig, idSuffix);
|
|
4958
|
+
printChainLine(prefix, name, chainConfig, idSuffix, verbose);
|
|
3728
4959
|
}
|
|
3729
4960
|
console.log();
|
|
3730
4961
|
}
|
|
3731
4962
|
for (const [name, chainConfig] of standalone) {
|
|
3732
|
-
printChainLine(" ", name, chainConfig);
|
|
4963
|
+
printChainLine(" ", name, chainConfig, "", verbose);
|
|
3733
4964
|
}
|
|
3734
4965
|
if (standalone.length > 0)
|
|
3735
4966
|
console.log();
|
|
3736
4967
|
}
|
|
3737
|
-
function printChainLine(prefix, name, chainConfig, suffix = "") {
|
|
4968
|
+
function printChainLine(prefix, name, chainConfig, suffix = "", verbose = false) {
|
|
4969
|
+
if (!verbose) {
|
|
4970
|
+
console.log(`${prefix}${CYAN}${name}${RESET}${suffix}`);
|
|
4971
|
+
return;
|
|
4972
|
+
}
|
|
3738
4973
|
const rpcs = Array.isArray(chainConfig.rpc) ? chainConfig.rpc : [chainConfig.rpc];
|
|
3739
4974
|
console.log(`${prefix}${CYAN}${name}${RESET}${suffix} ${DIM}${rpcs[0]}${RESET}`);
|
|
3740
4975
|
const indent = prefix.replace(/[^\s]/g, " ");
|
|
@@ -3742,6 +4977,79 @@ function printChainLine(prefix, name, chainConfig, suffix = "") {
|
|
|
3742
4977
|
console.log(`${indent} ${DIM}${rpcs[i]}${RESET}`);
|
|
3743
4978
|
}
|
|
3744
4979
|
}
|
|
4980
|
+
async function chainInfo(name, opts = {}) {
|
|
4981
|
+
if (!name) {
|
|
4982
|
+
console.error("Usage: dot chain info <name>");
|
|
4983
|
+
process.exit(1);
|
|
4984
|
+
}
|
|
4985
|
+
const config = await loadConfig();
|
|
4986
|
+
const { name: resolved, chain } = resolveChain(config, name);
|
|
4987
|
+
const rpcs = Array.isArray(chain.rpc) ? chain.rpc : [chain.rpc];
|
|
4988
|
+
const parachains = Object.entries(config.chains).filter(([, c]) => c.relay === resolved).map(([n, c]) => ({ name: n, parachainId: c.parachainId }));
|
|
4989
|
+
const fingerprint = await loadMetadataFingerprint(resolved);
|
|
4990
|
+
const rpcCache = await loadRpcMethods(resolved);
|
|
4991
|
+
const rpcSummary = rpcCache ? {
|
|
4992
|
+
count: rpcCache.methods.length,
|
|
4993
|
+
fetchedAt: rpcCache.fetchedAt,
|
|
4994
|
+
byFamily: countByFamily(rpcCache.methods)
|
|
4995
|
+
} : null;
|
|
4996
|
+
if (isJsonOutput(opts)) {
|
|
4997
|
+
console.log(formatJson({
|
|
4998
|
+
name: resolved,
|
|
4999
|
+
rpc: rpcs,
|
|
5000
|
+
...chain.relay && { relay: chain.relay },
|
|
5001
|
+
...chain.parachainId != null && { parachainId: chain.parachainId },
|
|
5002
|
+
...parachains.length > 0 && { parachains },
|
|
5003
|
+
metadata: fingerprint ? {
|
|
5004
|
+
specName: fingerprint.specName,
|
|
5005
|
+
specVersion: fingerprint.specVersion,
|
|
5006
|
+
fetchedAt: fingerprint.fetchedAt
|
|
5007
|
+
} : null,
|
|
5008
|
+
rpcMethods: rpcSummary
|
|
5009
|
+
}));
|
|
5010
|
+
return;
|
|
5011
|
+
}
|
|
5012
|
+
printHeading(resolved);
|
|
5013
|
+
console.log(` ${CYAN}rpc:${RESET}`);
|
|
5014
|
+
for (const rpc of rpcs) {
|
|
5015
|
+
console.log(` ${DIM}${rpc}${RESET}`);
|
|
5016
|
+
}
|
|
5017
|
+
if (chain.relay) {
|
|
5018
|
+
console.log(` ${CYAN}relay:${RESET} ${chain.relay}`);
|
|
5019
|
+
}
|
|
5020
|
+
if (chain.parachainId != null) {
|
|
5021
|
+
console.log(` ${CYAN}parachain id:${RESET} ${chain.parachainId}`);
|
|
5022
|
+
}
|
|
5023
|
+
if (parachains.length > 0) {
|
|
5024
|
+
console.log(` ${CYAN}parachains:${RESET}`);
|
|
5025
|
+
for (const p of parachains) {
|
|
5026
|
+
const idSuffix = p.parachainId != null ? ` ${DIM}[${p.parachainId}]${RESET}` : "";
|
|
5027
|
+
console.log(` ${p.name}${idSuffix}`);
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
console.log(` ${CYAN}metadata:${RESET}`);
|
|
5031
|
+
if (fingerprint) {
|
|
5032
|
+
console.log(` ${fingerprint.specName} v${fingerprint.specVersion} ${DIM}(cached ${fingerprint.fetchedAt})${RESET}`);
|
|
5033
|
+
} else {
|
|
5034
|
+
console.log(` ${DIM}not cached — run \`dot chain update ${resolved}\`${RESET}`);
|
|
5035
|
+
}
|
|
5036
|
+
console.log(` ${CYAN}rpc methods:${RESET}`);
|
|
5037
|
+
if (rpcSummary) {
|
|
5038
|
+
const families = Object.entries(rpcSummary.byFamily).map(([f, n]) => `${f}: ${n}`).join(", ");
|
|
5039
|
+
console.log(` ${rpcSummary.count} ${DIM}(${families})${RESET}`);
|
|
5040
|
+
console.log(` ${DIM}cached ${rpcSummary.fetchedAt}${RESET}`);
|
|
5041
|
+
} else {
|
|
5042
|
+
console.log(` ${DIM}not cached — run \`dot chain update ${resolved}\`${RESET}`);
|
|
5043
|
+
}
|
|
5044
|
+
}
|
|
5045
|
+
function countByFamily(methods) {
|
|
5046
|
+
const counts = {};
|
|
5047
|
+
for (const m of methods) {
|
|
5048
|
+
const family = RPC_REGISTRY[m]?.family ?? inferFamily(m);
|
|
5049
|
+
counts[family] = (counts[family] ?? 0) + 1;
|
|
5050
|
+
}
|
|
5051
|
+
return counts;
|
|
5052
|
+
}
|
|
3745
5053
|
async function chainUpdate(name, opts) {
|
|
3746
5054
|
const config = await loadConfig();
|
|
3747
5055
|
if (opts.all) {
|
|
@@ -3760,6 +5068,7 @@ async function chainUpdate(name, opts) {
|
|
|
3760
5068
|
process.stderr.write(`Fetching metadata...
|
|
3761
5069
|
`);
|
|
3762
5070
|
await fetchMetadataFromChain(clientHandle, chainName);
|
|
5071
|
+
await refreshRpcMethods(chainName, opts.rpc ?? chainConfig.rpc);
|
|
3763
5072
|
if (isJsonOutput(opts)) {
|
|
3764
5073
|
console.log(formatJson({ action: "updated", chain: chainName }));
|
|
3765
5074
|
} else {
|
|
@@ -3789,6 +5098,7 @@ async function updateChainsMetadata(config, chainNames) {
|
|
|
3789
5098
|
const clientHandle = await createChainClient(chainName, chainConfig);
|
|
3790
5099
|
try {
|
|
3791
5100
|
await fetchMetadataFromChain(clientHandle, chainName);
|
|
5101
|
+
await refreshRpcMethods(chainName, chainConfig.rpc, true);
|
|
3792
5102
|
} finally {
|
|
3793
5103
|
clientHandle.destroy();
|
|
3794
5104
|
}
|
|
@@ -4118,6 +5428,7 @@ init_store();
|
|
|
4118
5428
|
init_client();
|
|
4119
5429
|
init_metadata();
|
|
4120
5430
|
init_output();
|
|
5431
|
+
init_pretty_type();
|
|
4121
5432
|
async function loadMeta2(chainName, chainConfig, rpcOverride) {
|
|
4122
5433
|
if (rpcOverride) {
|
|
4123
5434
|
process.stderr.write(`Fetching metadata from ${chainName}...
|
|
@@ -4202,8 +5513,11 @@ async function handleCalls2(target, opts) {
|
|
|
4202
5513
|
}
|
|
4203
5514
|
printHeading(`${pallet.name} Calls`);
|
|
4204
5515
|
for (const c of pallet.calls) {
|
|
4205
|
-
const args2 =
|
|
4206
|
-
|
|
5516
|
+
const args2 = prettyCallArgs(meta, pallet.name, c.name, {
|
|
5517
|
+
indent: 2,
|
|
5518
|
+
prefix: c.name.length
|
|
5519
|
+
});
|
|
5520
|
+
console.log(` ${CYAN}${c.name}${RESET}${args2}`);
|
|
4207
5521
|
const summary = firstSentence(c.docs);
|
|
4208
5522
|
if (summary) {
|
|
4209
5523
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -4229,7 +5543,10 @@ async function handleCalls2(target, opts) {
|
|
|
4229
5543
|
return;
|
|
4230
5544
|
}
|
|
4231
5545
|
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
4232
|
-
const args =
|
|
5546
|
+
const args = prettyCallArgs(meta, pallet.name, callItem.name, {
|
|
5547
|
+
indent: 2,
|
|
5548
|
+
prefix: 6
|
|
5549
|
+
});
|
|
4233
5550
|
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
4234
5551
|
if (callItem.docs.length) {
|
|
4235
5552
|
console.log();
|
|
@@ -4288,8 +5605,11 @@ async function handleEvents2(target, opts) {
|
|
|
4288
5605
|
}
|
|
4289
5606
|
printHeading(`${pallet.name} Events`);
|
|
4290
5607
|
for (const e of pallet.events) {
|
|
4291
|
-
const fields2 =
|
|
4292
|
-
|
|
5608
|
+
const fields2 = prettyEventFields(meta, pallet.name, e.name, {
|
|
5609
|
+
indent: 2,
|
|
5610
|
+
prefix: e.name.length
|
|
5611
|
+
});
|
|
5612
|
+
console.log(` ${CYAN}${e.name}${RESET}${fields2}`);
|
|
4293
5613
|
const summary = firstSentence(e.docs);
|
|
4294
5614
|
if (summary) {
|
|
4295
5615
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -4315,7 +5635,10 @@ async function handleEvents2(target, opts) {
|
|
|
4315
5635
|
return;
|
|
4316
5636
|
}
|
|
4317
5637
|
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
4318
|
-
const fields =
|
|
5638
|
+
const fields = prettyEventFields(meta, pallet.name, eventItem.name, {
|
|
5639
|
+
indent: 2,
|
|
5640
|
+
prefix: 8
|
|
5641
|
+
});
|
|
4319
5642
|
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
4320
5643
|
if (eventItem.docs.length) {
|
|
4321
5644
|
console.log();
|
|
@@ -4442,24 +5765,30 @@ async function handleStorage2(target, opts) {
|
|
|
4442
5765
|
chain: chainName,
|
|
4443
5766
|
pallet: pallet.name,
|
|
4444
5767
|
storage: pallet.storage.map((s) => {
|
|
4445
|
-
const
|
|
5768
|
+
const valueType2 = describeType(meta.lookup, s.valueTypeId);
|
|
4446
5769
|
const keyType = s.keyTypeId != null ? describeType(meta.lookup, s.keyTypeId) : undefined;
|
|
4447
|
-
return { name: s.name, type: s.type, valueType, keyType, docs: firstSentence(s.docs) };
|
|
5770
|
+
return { name: s.name, type: s.type, valueType: valueType2, keyType, docs: firstSentence(s.docs) };
|
|
4448
5771
|
})
|
|
4449
5772
|
}));
|
|
4450
5773
|
return;
|
|
4451
5774
|
}
|
|
4452
5775
|
printHeading(`${pallet.name} Storage`);
|
|
4453
5776
|
for (const s of pallet.storage) {
|
|
4454
|
-
const
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
5777
|
+
const isMap = s.keyTypeId != null;
|
|
5778
|
+
const tag = isMap ? `${DIM} [map]${RESET}` : "";
|
|
5779
|
+
console.log(` ${CYAN}${s.name}${RESET}${tag}`);
|
|
5780
|
+
if (isMap) {
|
|
5781
|
+
const keyType = prettyTypeById(meta.lookup, s.keyTypeId, {
|
|
5782
|
+
indent: 4,
|
|
5783
|
+
prefix: 5
|
|
5784
|
+
});
|
|
5785
|
+
console.log(` ${DIM}Key:${RESET} ${keyType}`);
|
|
4461
5786
|
}
|
|
4462
|
-
|
|
5787
|
+
const valueType2 = prettyTypeById(meta.lookup, s.valueTypeId, {
|
|
5788
|
+
indent: 4,
|
|
5789
|
+
prefix: 7
|
|
5790
|
+
});
|
|
5791
|
+
console.log(` ${DIM}Value:${RESET} ${valueType2}`);
|
|
4463
5792
|
const summary = firstSentence(s.docs);
|
|
4464
5793
|
if (summary) {
|
|
4465
5794
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -4474,7 +5803,7 @@ async function handleStorage2(target, opts) {
|
|
|
4474
5803
|
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
4475
5804
|
}
|
|
4476
5805
|
if (isJsonOutput(opts)) {
|
|
4477
|
-
const
|
|
5806
|
+
const valueType2 = describeType(meta.lookup, storageItem.valueTypeId);
|
|
4478
5807
|
const keyType = storageItem.keyTypeId != null ? describeType(meta.lookup, storageItem.keyTypeId) : undefined;
|
|
4479
5808
|
console.log(formatJson({
|
|
4480
5809
|
chain: chainName,
|
|
@@ -4482,18 +5811,26 @@ async function handleStorage2(target, opts) {
|
|
|
4482
5811
|
item: storageItem.name,
|
|
4483
5812
|
category: "storage",
|
|
4484
5813
|
type: storageItem.type,
|
|
4485
|
-
valueType,
|
|
5814
|
+
valueType: valueType2,
|
|
4486
5815
|
keyType,
|
|
4487
5816
|
docs: storageItem.docs
|
|
4488
5817
|
}));
|
|
4489
5818
|
return;
|
|
4490
5819
|
}
|
|
4491
5820
|
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
4492
|
-
console.log(` ${BOLD}Type:${RESET}
|
|
4493
|
-
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
5821
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
4494
5822
|
if (storageItem.keyTypeId != null) {
|
|
4495
|
-
|
|
5823
|
+
const keyType = prettyTypeById(meta.lookup, storageItem.keyTypeId, {
|
|
5824
|
+
indent: 2,
|
|
5825
|
+
prefix: 7
|
|
5826
|
+
});
|
|
5827
|
+
console.log(` ${BOLD}Key:${RESET} ${keyType}`);
|
|
4496
5828
|
}
|
|
5829
|
+
const valueType = prettyTypeById(meta.lookup, storageItem.valueTypeId, {
|
|
5830
|
+
indent: 2,
|
|
5831
|
+
prefix: 7
|
|
5832
|
+
});
|
|
5833
|
+
console.log(` ${BOLD}Value:${RESET} ${valueType}`);
|
|
4497
5834
|
if (storageItem.docs.length) {
|
|
4498
5835
|
console.log();
|
|
4499
5836
|
printDocs(storageItem.docs);
|
|
@@ -4524,9 +5861,15 @@ async function showItemHelp2(category, target, opts) {
|
|
|
4524
5861
|
throw new Error(suggestMessage(`method in ${api.name}`, methodName, names));
|
|
4525
5862
|
}
|
|
4526
5863
|
printHeading(`${api.name}.${method.name} (Runtime API)`);
|
|
4527
|
-
const argStr =
|
|
4528
|
-
|
|
4529
|
-
|
|
5864
|
+
const argStr = prettyRuntimeApiArgs(meta.lookup, method.inputs, {
|
|
5865
|
+
indent: 2,
|
|
5866
|
+
prefix: 9
|
|
5867
|
+
});
|
|
5868
|
+
const retStr = prettyTypeById(meta.lookup, method.output, {
|
|
5869
|
+
indent: 2,
|
|
5870
|
+
prefix: 9
|
|
5871
|
+
});
|
|
5872
|
+
console.log(` ${BOLD}Args:${RESET} ${argStr}`);
|
|
4530
5873
|
console.log(` ${BOLD}Returns:${RESET} ${retStr}`);
|
|
4531
5874
|
if (method.docs.length) {
|
|
4532
5875
|
console.log();
|
|
@@ -4569,7 +5912,10 @@ async function showItemHelp2(category, target, opts) {
|
|
|
4569
5912
|
throw new Error(suggestMessage(`call in ${pallet.name}`, itemName, names));
|
|
4570
5913
|
}
|
|
4571
5914
|
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
4572
|
-
const args =
|
|
5915
|
+
const args = prettyCallArgs(meta, pallet.name, callItem.name, {
|
|
5916
|
+
indent: 2,
|
|
5917
|
+
prefix: 6
|
|
5918
|
+
});
|
|
4573
5919
|
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
4574
5920
|
if (callItem.docs.length) {
|
|
4575
5921
|
console.log();
|
|
@@ -4596,11 +5942,19 @@ async function showItemHelp2(category, target, opts) {
|
|
|
4596
5942
|
throw new Error(suggestMessage(`storage item in ${pallet.name}`, itemName, names));
|
|
4597
5943
|
}
|
|
4598
5944
|
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
4599
|
-
console.log(` ${BOLD}Type:${RESET}
|
|
4600
|
-
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
5945
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
4601
5946
|
if (storageItem.keyTypeId != null) {
|
|
4602
|
-
|
|
5947
|
+
const keyType = prettyTypeById(meta.lookup, storageItem.keyTypeId, {
|
|
5948
|
+
indent: 2,
|
|
5949
|
+
prefix: 7
|
|
5950
|
+
});
|
|
5951
|
+
console.log(` ${BOLD}Key:${RESET} ${keyType}`);
|
|
4603
5952
|
}
|
|
5953
|
+
const valueType = prettyTypeById(meta.lookup, storageItem.valueTypeId, {
|
|
5954
|
+
indent: 2,
|
|
5955
|
+
prefix: 7
|
|
5956
|
+
});
|
|
5957
|
+
console.log(` ${BOLD}Value:${RESET} ${valueType}`);
|
|
4604
5958
|
if (storageItem.docs.length) {
|
|
4605
5959
|
console.log();
|
|
4606
5960
|
printDocs(storageItem.docs);
|
|
@@ -4627,7 +5981,11 @@ async function showItemHelp2(category, target, opts) {
|
|
|
4627
5981
|
throw new Error(suggestMessage(`constant in ${pallet.name}`, itemName, names));
|
|
4628
5982
|
}
|
|
4629
5983
|
printHeading(`${pallet.name}.${constItem.name} (Constant)`);
|
|
4630
|
-
|
|
5984
|
+
const constType = prettyTypeById(meta.lookup, constItem.typeId, {
|
|
5985
|
+
indent: 2,
|
|
5986
|
+
prefix: 6
|
|
5987
|
+
});
|
|
5988
|
+
console.log(` ${BOLD}Type:${RESET} ${constType}`);
|
|
4631
5989
|
if (constItem.docs.length) {
|
|
4632
5990
|
console.log();
|
|
4633
5991
|
printDocs(constItem.docs);
|
|
@@ -4645,7 +6003,10 @@ async function showItemHelp2(category, target, opts) {
|
|
|
4645
6003
|
throw new Error(suggestMessage(`event in ${pallet.name}`, itemName, names));
|
|
4646
6004
|
}
|
|
4647
6005
|
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
4648
|
-
const fields =
|
|
6006
|
+
const fields = prettyEventFields(meta, pallet.name, eventItem.name, {
|
|
6007
|
+
indent: 2,
|
|
6008
|
+
prefix: 8
|
|
6009
|
+
});
|
|
4649
6010
|
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
4650
6011
|
if (eventItem.docs.length) {
|
|
4651
6012
|
console.log();
|
|
@@ -4720,8 +6081,16 @@ async function handleExtensions(target, opts) {
|
|
|
4720
6081
|
return;
|
|
4721
6082
|
}
|
|
4722
6083
|
printHeading(`${described.identifier} (Transaction Extension)`);
|
|
4723
|
-
|
|
4724
|
-
|
|
6084
|
+
const valueType = prettyTypeById(meta.lookup, described.valueTypeId, {
|
|
6085
|
+
indent: 2,
|
|
6086
|
+
prefix: 18
|
|
6087
|
+
});
|
|
6088
|
+
const addSigType = prettyTypeById(meta.lookup, described.additionalSignedTypeId, {
|
|
6089
|
+
indent: 2,
|
|
6090
|
+
prefix: 18
|
|
6091
|
+
});
|
|
6092
|
+
console.log(` ${BOLD}Value type:${RESET} ${valueType}`);
|
|
6093
|
+
console.log(` ${BOLD}AdditionalSigned:${RESET} ${addSigType}`);
|
|
4725
6094
|
console.log(` ${BOLD}Handled by:${RESET} ${described.isBuiltin ? "polkadot-api (builtin)" : "user (custom — provide via --ext)"}`);
|
|
4726
6095
|
if (!described.isBuiltin) {
|
|
4727
6096
|
console.log();
|
|
@@ -4805,6 +6174,7 @@ init_store();
|
|
|
4805
6174
|
init_client();
|
|
4806
6175
|
init_metadata();
|
|
4807
6176
|
init_output();
|
|
6177
|
+
init_pretty_type();
|
|
4808
6178
|
|
|
4809
6179
|
// src/utils/parse-target.ts
|
|
4810
6180
|
function parseTarget(input, options) {
|
|
@@ -4981,15 +6351,21 @@ function registerInspectCommand(cli) {
|
|
|
4981
6351
|
if (pallet2.storage.length) {
|
|
4982
6352
|
console.log(` ${BOLD}Storage Items:${RESET}`);
|
|
4983
6353
|
for (const s of pallet2.storage) {
|
|
4984
|
-
const
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
6354
|
+
const isMap = s.keyTypeId != null;
|
|
6355
|
+
const tag = isMap ? `${DIM} [map]${RESET}` : "";
|
|
6356
|
+
console.log(` ${CYAN}${s.name}${RESET}${tag}`);
|
|
6357
|
+
if (isMap) {
|
|
6358
|
+
const keyType = prettyTypeById(meta.lookup, s.keyTypeId, {
|
|
6359
|
+
indent: 6,
|
|
6360
|
+
prefix: 7
|
|
6361
|
+
});
|
|
6362
|
+
console.log(` ${DIM}Key:${RESET} ${keyType}`);
|
|
4991
6363
|
}
|
|
4992
|
-
|
|
6364
|
+
const valueType = prettyTypeById(meta.lookup, s.valueTypeId, {
|
|
6365
|
+
indent: 6,
|
|
6366
|
+
prefix: 7
|
|
6367
|
+
});
|
|
6368
|
+
console.log(` ${DIM}Value:${RESET} ${valueType}`);
|
|
4993
6369
|
const summary = firstSentence(s.docs);
|
|
4994
6370
|
if (summary) {
|
|
4995
6371
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5000,8 +6376,11 @@ function registerInspectCommand(cli) {
|
|
|
5000
6376
|
if (pallet2.constants.length) {
|
|
5001
6377
|
console.log(` ${BOLD}Constants:${RESET}`);
|
|
5002
6378
|
for (const c of pallet2.constants) {
|
|
5003
|
-
const typeStr =
|
|
5004
|
-
|
|
6379
|
+
const typeStr = prettyTypeById(meta.lookup, c.typeId, {
|
|
6380
|
+
indent: 4,
|
|
6381
|
+
prefix: c.name.length + 2
|
|
6382
|
+
});
|
|
6383
|
+
console.log(` ${CYAN}${c.name}${RESET}: ${typeStr}`);
|
|
5005
6384
|
const summary = firstSentence(c.docs);
|
|
5006
6385
|
if (summary) {
|
|
5007
6386
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5012,8 +6391,11 @@ function registerInspectCommand(cli) {
|
|
|
5012
6391
|
if (pallet2.calls.length) {
|
|
5013
6392
|
console.log(` ${BOLD}Calls:${RESET}`);
|
|
5014
6393
|
for (const c of pallet2.calls) {
|
|
5015
|
-
const args =
|
|
5016
|
-
|
|
6394
|
+
const args = prettyCallArgs(meta, pallet2.name, c.name, {
|
|
6395
|
+
indent: 4,
|
|
6396
|
+
prefix: c.name.length
|
|
6397
|
+
});
|
|
6398
|
+
console.log(` ${CYAN}${c.name}${RESET}${args}`);
|
|
5017
6399
|
const summary = firstSentence(c.docs);
|
|
5018
6400
|
if (summary) {
|
|
5019
6401
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5024,8 +6406,11 @@ function registerInspectCommand(cli) {
|
|
|
5024
6406
|
if (pallet2.events.length) {
|
|
5025
6407
|
console.log(` ${BOLD}Events:${RESET}`);
|
|
5026
6408
|
for (const e of pallet2.events) {
|
|
5027
|
-
const fields =
|
|
5028
|
-
|
|
6409
|
+
const fields = prettyEventFields(meta, pallet2.name, e.name, {
|
|
6410
|
+
indent: 4,
|
|
6411
|
+
prefix: e.name.length
|
|
6412
|
+
});
|
|
6413
|
+
console.log(` ${CYAN}${e.name}${RESET}${fields}`);
|
|
5029
6414
|
const summary = firstSentence(e.docs);
|
|
5030
6415
|
if (summary) {
|
|
5031
6416
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5127,11 +6512,19 @@ function registerInspectCommand(cli) {
|
|
|
5127
6512
|
const storageItem = pallet.storage.find((s) => s.name.toLowerCase() === itemName.toLowerCase());
|
|
5128
6513
|
if (storageItem) {
|
|
5129
6514
|
printHeading(`${pallet.name}.${storageItem.name} (Storage)`);
|
|
5130
|
-
console.log(` ${BOLD}Type:${RESET}
|
|
5131
|
-
console.log(` ${BOLD}Value:${RESET} ${describeType(meta.lookup, storageItem.valueTypeId)}`);
|
|
6515
|
+
console.log(` ${BOLD}Type:${RESET} ${storageItem.type}`);
|
|
5132
6516
|
if (storageItem.keyTypeId != null) {
|
|
5133
|
-
|
|
6517
|
+
const keyType = prettyTypeById(meta.lookup, storageItem.keyTypeId, {
|
|
6518
|
+
indent: 2,
|
|
6519
|
+
prefix: 7
|
|
6520
|
+
});
|
|
6521
|
+
console.log(` ${BOLD}Key:${RESET} ${keyType}`);
|
|
5134
6522
|
}
|
|
6523
|
+
const valueType = prettyTypeById(meta.lookup, storageItem.valueTypeId, {
|
|
6524
|
+
indent: 2,
|
|
6525
|
+
prefix: 7
|
|
6526
|
+
});
|
|
6527
|
+
console.log(` ${BOLD}Value:${RESET} ${valueType}`);
|
|
5135
6528
|
if (storageItem.docs.length) {
|
|
5136
6529
|
console.log();
|
|
5137
6530
|
printDocs(storageItem.docs);
|
|
@@ -5142,7 +6535,11 @@ function registerInspectCommand(cli) {
|
|
|
5142
6535
|
const constantItem = pallet.constants.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
5143
6536
|
if (constantItem) {
|
|
5144
6537
|
printHeading(`${pallet.name}.${constantItem.name} (Constant)`);
|
|
5145
|
-
|
|
6538
|
+
const typeStr = prettyTypeById(meta.lookup, constantItem.typeId, {
|
|
6539
|
+
indent: 2,
|
|
6540
|
+
prefix: 6
|
|
6541
|
+
});
|
|
6542
|
+
console.log(` ${BOLD}Type:${RESET} ${typeStr}`);
|
|
5146
6543
|
if (constantItem.docs.length) {
|
|
5147
6544
|
console.log();
|
|
5148
6545
|
printDocs(constantItem.docs);
|
|
@@ -5153,7 +6550,10 @@ function registerInspectCommand(cli) {
|
|
|
5153
6550
|
const callItem = pallet.calls.find((c) => c.name.toLowerCase() === itemName.toLowerCase());
|
|
5154
6551
|
if (callItem) {
|
|
5155
6552
|
printHeading(`${pallet.name}.${callItem.name} (Call)`);
|
|
5156
|
-
const args =
|
|
6553
|
+
const args = prettyCallArgs(meta, pallet.name, callItem.name, {
|
|
6554
|
+
indent: 2,
|
|
6555
|
+
prefix: 6
|
|
6556
|
+
});
|
|
5157
6557
|
console.log(` ${BOLD}Args:${RESET} ${args}`);
|
|
5158
6558
|
if (callItem.docs.length) {
|
|
5159
6559
|
console.log();
|
|
@@ -5165,7 +6565,10 @@ function registerInspectCommand(cli) {
|
|
|
5165
6565
|
const eventItem = pallet.events.find((e) => e.name.toLowerCase() === itemName.toLowerCase());
|
|
5166
6566
|
if (eventItem) {
|
|
5167
6567
|
printHeading(`${pallet.name}.${eventItem.name} (Event)`);
|
|
5168
|
-
const fields =
|
|
6568
|
+
const fields = prettyEventFields(meta, pallet.name, eventItem.name, {
|
|
6569
|
+
indent: 2,
|
|
6570
|
+
prefix: 8
|
|
6571
|
+
});
|
|
5169
6572
|
console.log(` ${BOLD}Fields:${RESET} ${fields}`);
|
|
5170
6573
|
if (eventItem.docs.length) {
|
|
5171
6574
|
console.log();
|
|
@@ -5240,11 +6643,6 @@ async function handleMetadata(chain, opts) {
|
|
|
5240
6643
|
await writeStdout(`${formatJson(buildMetadataPayload(chainName, meta, fingerprint))}
|
|
5241
6644
|
`);
|
|
5242
6645
|
}
|
|
5243
|
-
function writeStdout(text) {
|
|
5244
|
-
return new Promise((resolve) => {
|
|
5245
|
-
process.stdout.write(text, () => resolve());
|
|
5246
|
-
});
|
|
5247
|
-
}
|
|
5248
6646
|
function registerMetadataCommand(cli) {
|
|
5249
6647
|
cli.command("metadata <chain>", "Fetch chain metadata (decoded JSON; --raw for SCALE hex)").option("--raw", "Print SCALE-encoded metadata bytes as hex instead of decoded JSON").option("--cached", "Use cached metadata instead of fetching fresh from the chain").option("--rpc <url>", "Override RPC endpoint(s)").action((chain, opts) => handleMetadata(chain, opts));
|
|
5250
6648
|
}
|
|
@@ -5252,24 +6650,6 @@ function registerMetadataCommand(cli) {
|
|
|
5252
6650
|
// src/commands/parachain.ts
|
|
5253
6651
|
init_accounts();
|
|
5254
6652
|
init_output();
|
|
5255
|
-
|
|
5256
|
-
// src/core/parachain.ts
|
|
5257
|
-
var SOVEREIGN_ACCOUNT_TYPES = ["child", "sibling"];
|
|
5258
|
-
var PREFIXES = {
|
|
5259
|
-
child: new Uint8Array([112, 97, 114, 97]),
|
|
5260
|
-
sibling: new Uint8Array([115, 105, 98, 108])
|
|
5261
|
-
};
|
|
5262
|
-
function deriveSovereignAccount(paraId, type) {
|
|
5263
|
-
const result = new Uint8Array(32);
|
|
5264
|
-
result.set(PREFIXES[type], 0);
|
|
5265
|
-
new DataView(result.buffer).setUint32(4, paraId, true);
|
|
5266
|
-
return result;
|
|
5267
|
-
}
|
|
5268
|
-
function isValidParaId(value) {
|
|
5269
|
-
return Number.isInteger(value) && value >= 0 && value <= 4294967295;
|
|
5270
|
-
}
|
|
5271
|
-
|
|
5272
|
-
// src/commands/parachain.ts
|
|
5273
6653
|
init_errors();
|
|
5274
6654
|
function printParachainHelp() {
|
|
5275
6655
|
console.log(`${BOLD}Usage:${RESET} dot parachain <paraId> [options]
|
|
@@ -5299,6 +6679,7 @@ function validateType(type) {
|
|
|
5299
6679
|
}
|
|
5300
6680
|
function registerParachainCommand(cli) {
|
|
5301
6681
|
cli.command("parachain [paraId]", "Derive parachain sovereign accounts").option("--type <type>", "Account type: child, sibling (default: both)").option("--prefix <number>", "SS58 prefix for address encoding (default: 42)").action(async (paraIdStr, opts) => {
|
|
6682
|
+
console.error("Warning: `dot parachain` is deprecated; use `dot account inspect --parachain <id> --parachain-type <child|sibling>` instead. Will be removed in a future release.");
|
|
5302
6683
|
if (!paraIdStr) {
|
|
5303
6684
|
printParachainHelp();
|
|
5304
6685
|
return;
|
|
@@ -5344,6 +6725,7 @@ init_store();
|
|
|
5344
6725
|
init_client();
|
|
5345
6726
|
init_metadata();
|
|
5346
6727
|
init_output();
|
|
6728
|
+
init_pretty_type();
|
|
5347
6729
|
init_focused_inspect();
|
|
5348
6730
|
init_tx();
|
|
5349
6731
|
async function handleQuery(target, keys, opts) {
|
|
@@ -5354,10 +6736,11 @@ async function handleQuery(target, keys, opts) {
|
|
|
5354
6736
|
const pallets = listPallets(meta);
|
|
5355
6737
|
const withStorage = pallets.filter((p) => p.storage.length > 0);
|
|
5356
6738
|
if (isJsonOutput(opts)) {
|
|
5357
|
-
|
|
6739
|
+
await writeStdout(`${formatJson({
|
|
5358
6740
|
chain: chainName2,
|
|
5359
6741
|
pallets: withStorage.map((p) => ({ name: p.name, storage: p.storage.length }))
|
|
5360
|
-
})
|
|
6742
|
+
})}
|
|
6743
|
+
`);
|
|
5361
6744
|
return;
|
|
5362
6745
|
}
|
|
5363
6746
|
printHeading(`Pallets with storage on ${chainName2} (${withStorage.length})`);
|
|
@@ -5375,14 +6758,15 @@ async function handleQuery(target, keys, opts) {
|
|
|
5375
6758
|
const pallet2 = resolvePallet(meta, palletName(target));
|
|
5376
6759
|
if (pallet2.storage.length === 0) {
|
|
5377
6760
|
if (isJsonOutput(opts)) {
|
|
5378
|
-
|
|
6761
|
+
await writeStdout(`${formatJson({ chain: chainName2, pallet: pallet2.name, storage: [] })}
|
|
6762
|
+
`);
|
|
5379
6763
|
} else {
|
|
5380
6764
|
console.log(`No storage items in ${pallet2.name}.`);
|
|
5381
6765
|
}
|
|
5382
6766
|
return;
|
|
5383
6767
|
}
|
|
5384
6768
|
if (isJsonOutput(opts)) {
|
|
5385
|
-
|
|
6769
|
+
await writeStdout(`${formatJson({
|
|
5386
6770
|
chain: chainName2,
|
|
5387
6771
|
pallet: pallet2.name,
|
|
5388
6772
|
storage: pallet2.storage.map((s) => {
|
|
@@ -5390,20 +6774,27 @@ async function handleQuery(target, keys, opts) {
|
|
|
5390
6774
|
const keyType = s.keyTypeId != null ? describeType(meta.lookup, s.keyTypeId) : undefined;
|
|
5391
6775
|
return { name: s.name, type: s.type, valueType, keyType, docs: firstSentence(s.docs) };
|
|
5392
6776
|
})
|
|
5393
|
-
})
|
|
6777
|
+
})}
|
|
6778
|
+
`);
|
|
5394
6779
|
return;
|
|
5395
6780
|
}
|
|
5396
6781
|
printHeading(`${pallet2.name} Storage`);
|
|
5397
6782
|
for (const s of pallet2.storage) {
|
|
5398
|
-
const
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
6783
|
+
const isMap = s.keyTypeId != null;
|
|
6784
|
+
const tag = isMap ? `${DIM} [map]${RESET}` : "";
|
|
6785
|
+
console.log(` ${CYAN}${s.name}${RESET}${tag}`);
|
|
6786
|
+
if (isMap) {
|
|
6787
|
+
const keyType = prettyTypeById(meta.lookup, s.keyTypeId, {
|
|
6788
|
+
indent: 4,
|
|
6789
|
+
prefix: 5
|
|
6790
|
+
});
|
|
6791
|
+
console.log(` ${DIM}Key:${RESET} ${keyType}`);
|
|
5405
6792
|
}
|
|
5406
|
-
|
|
6793
|
+
const valueType = prettyTypeById(meta.lookup, s.valueTypeId, {
|
|
6794
|
+
indent: 4,
|
|
6795
|
+
prefix: 7
|
|
6796
|
+
});
|
|
6797
|
+
console.log(` ${DIM}Value:${RESET} ${valueType}`);
|
|
5407
6798
|
const summary = firstSentence(s.docs);
|
|
5408
6799
|
if (summary) {
|
|
5409
6800
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5445,13 +6836,18 @@ async function handleQuery(target, keys, opts) {
|
|
|
5445
6836
|
return;
|
|
5446
6837
|
}
|
|
5447
6838
|
const entries = await withStalenessSuggestion(chainName, clientHandle, () => storageApi.getEntries(...parsedKeys));
|
|
5448
|
-
|
|
6839
|
+
const rows = entries.map((e) => ({
|
|
5449
6840
|
keys: e.keyArgs,
|
|
5450
6841
|
value: e.value
|
|
5451
|
-
}))
|
|
6842
|
+
}));
|
|
6843
|
+
const text = format === "json" ? formatJson(rows) : formatPretty(rows);
|
|
6844
|
+
await writeStdout(`${text}
|
|
6845
|
+
`);
|
|
5452
6846
|
} else {
|
|
5453
6847
|
const result = await withStalenessSuggestion(chainName, clientHandle, () => storageApi.getValue(...parsedKeys));
|
|
5454
|
-
|
|
6848
|
+
const text = format === "json" ? formatJson(result) : formatPretty(result);
|
|
6849
|
+
await writeStdout(`${text}
|
|
6850
|
+
`);
|
|
5455
6851
|
}
|
|
5456
6852
|
} finally {
|
|
5457
6853
|
clientHandle.destroy();
|
|
@@ -5497,6 +6893,168 @@ async function parseStorageKeys(meta, palletName2, storageItem, args) {
|
|
|
5497
6893
|
return Promise.all(args.map((arg) => parseTypedArg(meta, keyEntry, arg)));
|
|
5498
6894
|
}
|
|
5499
6895
|
|
|
6896
|
+
// src/commands/rpc.ts
|
|
6897
|
+
init_store();
|
|
6898
|
+
init_output();
|
|
6899
|
+
init_rpc_registry();
|
|
6900
|
+
init_errors();
|
|
6901
|
+
var FAMILY_ORDER = [
|
|
6902
|
+
"system",
|
|
6903
|
+
"chain",
|
|
6904
|
+
"state",
|
|
6905
|
+
"author",
|
|
6906
|
+
"payment",
|
|
6907
|
+
"babe",
|
|
6908
|
+
"grandpa",
|
|
6909
|
+
"beefy",
|
|
6910
|
+
"mmr",
|
|
6911
|
+
"offchain",
|
|
6912
|
+
"dev",
|
|
6913
|
+
"spec",
|
|
6914
|
+
"chainHead",
|
|
6915
|
+
"chainSpec",
|
|
6916
|
+
"transaction",
|
|
6917
|
+
"archive",
|
|
6918
|
+
"other"
|
|
6919
|
+
];
|
|
6920
|
+
async function getMethodList(chainName, rpcUrl, refresh) {
|
|
6921
|
+
if (!refresh) {
|
|
6922
|
+
const cached = await loadRpcMethods(chainName);
|
|
6923
|
+
if (cached) {
|
|
6924
|
+
return { methods: cached.methods, version: cached.version, fromCache: true };
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
const fresh = await fetchRpcMethods(rpcUrl);
|
|
6928
|
+
await saveRpcMethods(chainName, fresh.methods, fresh.version);
|
|
6929
|
+
return { methods: fresh.methods, version: fresh.version, fromCache: false };
|
|
6930
|
+
}
|
|
6931
|
+
function groupByFamily(methods) {
|
|
6932
|
+
const groups = new Map;
|
|
6933
|
+
for (const m of methods) {
|
|
6934
|
+
const family = RPC_REGISTRY[m]?.family ?? inferFamily(m);
|
|
6935
|
+
const list = groups.get(family) ?? [];
|
|
6936
|
+
list.push(m);
|
|
6937
|
+
groups.set(family, list);
|
|
6938
|
+
}
|
|
6939
|
+
for (const list of groups.values())
|
|
6940
|
+
list.sort();
|
|
6941
|
+
return groups;
|
|
6942
|
+
}
|
|
6943
|
+
function formatArgs(info) {
|
|
6944
|
+
if (info.args.length === 0)
|
|
6945
|
+
return "(no args)";
|
|
6946
|
+
return info.args.map((a) => `<${a.name}: ${a.type}${a.optional ? "?" : ""}>`).join(" ");
|
|
6947
|
+
}
|
|
6948
|
+
function printMethodHelp(method, info) {
|
|
6949
|
+
console.log();
|
|
6950
|
+
console.log(`${BOLD}${method}${RESET}`);
|
|
6951
|
+
if (info) {
|
|
6952
|
+
if (info.dangerous) {
|
|
6953
|
+
console.log(` ${YELLOW}⚠️ WRITE / state-changing${RESET}`);
|
|
6954
|
+
}
|
|
6955
|
+
if (info.subscription) {
|
|
6956
|
+
console.log(` ${DIM}subscription — not callable as a one-shot${RESET}`);
|
|
6957
|
+
}
|
|
6958
|
+
console.log(` ${info.description}`);
|
|
6959
|
+
console.log();
|
|
6960
|
+
console.log(` ${DIM}Family:${RESET} ${info.family}`);
|
|
6961
|
+
console.log(` ${DIM}Args:${RESET} ${formatArgs(info)}`);
|
|
6962
|
+
if (info.args.some((a) => a.description)) {
|
|
6963
|
+
console.log();
|
|
6964
|
+
for (const a of info.args) {
|
|
6965
|
+
if (a.description) {
|
|
6966
|
+
console.log(` ${CYAN}${a.name}${RESET} ${DIM}${a.description}${RESET}`);
|
|
6967
|
+
}
|
|
6968
|
+
}
|
|
6969
|
+
}
|
|
6970
|
+
} else {
|
|
6971
|
+
console.log(` ${DIM}No curated metadata. Args are passed through as raw JSON-RPC params.${RESET}`);
|
|
6972
|
+
console.log(` ${DIM}Family:${RESET} ${inferFamily(method)} (inferred)`);
|
|
6973
|
+
}
|
|
6974
|
+
console.log();
|
|
6975
|
+
}
|
|
6976
|
+
async function listMethods(chainName, rpcUrl, opts) {
|
|
6977
|
+
const { methods, version: version2, fromCache } = await getMethodList(chainName, rpcUrl, opts.refresh ?? false);
|
|
6978
|
+
if (isJsonOutput(opts)) {
|
|
6979
|
+
console.log(formatJson({
|
|
6980
|
+
chain: chainName,
|
|
6981
|
+
version: version2,
|
|
6982
|
+
fromCache,
|
|
6983
|
+
methods: methods.map((m) => {
|
|
6984
|
+
const info = RPC_REGISTRY[m];
|
|
6985
|
+
return {
|
|
6986
|
+
method: m,
|
|
6987
|
+
family: info?.family ?? inferFamily(m),
|
|
6988
|
+
description: info?.description,
|
|
6989
|
+
dangerous: info?.dangerous ?? false,
|
|
6990
|
+
subscription: info?.subscription ?? false
|
|
6991
|
+
};
|
|
6992
|
+
})
|
|
6993
|
+
}));
|
|
6994
|
+
return;
|
|
6995
|
+
}
|
|
6996
|
+
printHeading(`RPC methods on ${chainName} (${methods.length})`);
|
|
6997
|
+
const groups = groupByFamily(methods);
|
|
6998
|
+
for (const family of FAMILY_ORDER) {
|
|
6999
|
+
const list = groups.get(family);
|
|
7000
|
+
if (!list || list.length === 0)
|
|
7001
|
+
continue;
|
|
7002
|
+
console.log(`${BOLD}${family}${RESET} ${DIM}(${list.length})${RESET}`);
|
|
7003
|
+
for (const m of list) {
|
|
7004
|
+
const info = RPC_REGISTRY[m];
|
|
7005
|
+
const tags = [];
|
|
7006
|
+
if (info?.dangerous)
|
|
7007
|
+
tags.push(`${YELLOW}⚠ write${RESET}`);
|
|
7008
|
+
if (info?.subscription)
|
|
7009
|
+
tags.push(`${DIM}sub${RESET}`);
|
|
7010
|
+
const suffix = tags.length > 0 ? ` ${tags.join(" ")}` : "";
|
|
7011
|
+
const desc = info?.description ? ` ${DIM}${info.description}${RESET}` : "";
|
|
7012
|
+
console.log(` ${CYAN}${m}${RESET}${suffix}${desc}`);
|
|
7013
|
+
}
|
|
7014
|
+
console.log();
|
|
7015
|
+
}
|
|
7016
|
+
if (!fromCache) {
|
|
7017
|
+
console.log(`${DIM}(fetched from node — cached for next run)${RESET}`);
|
|
7018
|
+
}
|
|
7019
|
+
}
|
|
7020
|
+
async function handleRpc(method, args, opts) {
|
|
7021
|
+
const config = await loadConfig();
|
|
7022
|
+
const { name: chainName, chain: chainConfig } = resolveChain(config, opts.chain);
|
|
7023
|
+
const rpcUrl = opts.rpc ?? chainConfig.rpc;
|
|
7024
|
+
if (!rpcUrl) {
|
|
7025
|
+
throw new CliError(`No RPC endpoint for chain "${chainName}". Pass --rpc or run \`dot chain add ${chainName} --rpc <url>\`.`);
|
|
7026
|
+
}
|
|
7027
|
+
if (!method) {
|
|
7028
|
+
await listMethods(chainName, rpcUrl, opts);
|
|
7029
|
+
return;
|
|
7030
|
+
}
|
|
7031
|
+
const info = RPC_REGISTRY[method];
|
|
7032
|
+
if (opts.help) {
|
|
7033
|
+
printMethodHelp(method, info);
|
|
7034
|
+
return;
|
|
7035
|
+
}
|
|
7036
|
+
const { methods: knownMethods } = await getMethodList(chainName, rpcUrl, opts.refresh ?? false);
|
|
7037
|
+
if (!knownMethods.includes(method)) {
|
|
7038
|
+
const hint = suggestMessage("method", method, knownMethods);
|
|
7039
|
+
throw new CliError(`Method "${method}" is not exposed by the node for "${chainName}".${hint ? ` ${hint}` : ""} ` + `Run \`dot ${chainName}.rpc --refresh\` if the node has been upgraded.`);
|
|
7040
|
+
}
|
|
7041
|
+
if (info?.subscription) {
|
|
7042
|
+
throw new CliError(`"${method}" is a subscription method (requires a follow session) and is not callable as a one-shot. ` + `Use a long-running client for streaming RPC.`);
|
|
7043
|
+
}
|
|
7044
|
+
if (!info && /(_subscribe|_unsubscribe)/.test(method)) {
|
|
7045
|
+
throw new CliError(`"${method}" looks like a subscription/unsubscription method and isn't supported as a one-shot. ` + `Pass --help to see what we know about it.`);
|
|
7046
|
+
}
|
|
7047
|
+
if (info) {
|
|
7048
|
+
const required = info.args.filter((a) => !a.optional).length;
|
|
7049
|
+
if (args.length < required) {
|
|
7050
|
+
throw new CliError(`"${method}" expects at least ${required} argument(s) (${formatArgs(info)}); got ${args.length}.`);
|
|
7051
|
+
}
|
|
7052
|
+
}
|
|
7053
|
+
const params = args.map(parseValue);
|
|
7054
|
+
const result = await rpcRequest(rpcUrl, method, params);
|
|
7055
|
+
printResult(result, isJsonOutput(opts) ? "json" : opts.output);
|
|
7056
|
+
}
|
|
7057
|
+
|
|
5500
7058
|
// src/commands/sign.ts
|
|
5501
7059
|
init_accounts();
|
|
5502
7060
|
init_hash();
|
|
@@ -5598,6 +7156,7 @@ init_accounts();
|
|
|
5598
7156
|
init_client();
|
|
5599
7157
|
init_metadata();
|
|
5600
7158
|
init_output();
|
|
7159
|
+
init_pretty_type();
|
|
5601
7160
|
init_resolve_address();
|
|
5602
7161
|
init_binary_display();
|
|
5603
7162
|
init_errors();
|
|
@@ -5730,8 +7289,11 @@ async function handleTx(target, args, opts) {
|
|
|
5730
7289
|
}
|
|
5731
7290
|
printHeading(`${pallet2.name} Calls`);
|
|
5732
7291
|
for (const c of pallet2.calls) {
|
|
5733
|
-
const callArgs =
|
|
5734
|
-
|
|
7292
|
+
const callArgs = prettyCallArgs(meta, pallet2.name, c.name, {
|
|
7293
|
+
indent: 2,
|
|
7294
|
+
prefix: c.name.length
|
|
7295
|
+
});
|
|
7296
|
+
console.log(` ${CYAN}${c.name}${RESET}${callArgs}`);
|
|
5735
7297
|
const summary = firstSentence(c.docs);
|
|
5736
7298
|
if (summary) {
|
|
5737
7299
|
console.log(` ${DIM}${summary}${RESET}`);
|
|
@@ -5882,6 +7444,7 @@ async function handleTx(target, args, opts) {
|
|
|
5882
7444
|
callHex = Binary3.toHex(encodedCall);
|
|
5883
7445
|
}
|
|
5884
7446
|
const decodedStr = decodeCall(meta, callHex);
|
|
7447
|
+
const decodedObj = decodeCallObject(meta, callHex);
|
|
5885
7448
|
if (opts.dryRun && opts.unsigned) {
|
|
5886
7449
|
if (isJsonOutput(opts)) {
|
|
5887
7450
|
console.log(formatJson({
|
|
@@ -5896,7 +7459,7 @@ async function handleTx(target, args, opts) {
|
|
|
5896
7459
|
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
5897
7460
|
console.log(` ${BOLD}Type:${RESET} unsigned (bare)`);
|
|
5898
7461
|
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
5899
|
-
|
|
7462
|
+
printDecodedCall(decodedObj, decodedStr);
|
|
5900
7463
|
console.log(` ${BOLD}Fees:${RESET} ${DIM}N/A (unsigned transaction)${RESET}`);
|
|
5901
7464
|
return;
|
|
5902
7465
|
}
|
|
@@ -5935,7 +7498,7 @@ async function handleTx(target, args, opts) {
|
|
|
5935
7498
|
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
5936
7499
|
console.log(` ${BOLD}From:${RESET} ${opts.from} (${signerAddress})`);
|
|
5937
7500
|
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
5938
|
-
|
|
7501
|
+
printDecodedCall(decodedObj, decodedStr);
|
|
5939
7502
|
if (nonce !== undefined)
|
|
5940
7503
|
console.log(` ${BOLD}Nonce:${RESET} ${nonce}`);
|
|
5941
7504
|
if (tip !== undefined)
|
|
@@ -6012,7 +7575,7 @@ async function handleTx(target, args, opts) {
|
|
|
6012
7575
|
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
6013
7576
|
console.log(` ${BOLD}Type:${RESET} unsigned (bare)`);
|
|
6014
7577
|
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
6015
|
-
|
|
7578
|
+
printDecodedCall(decodedObj, decodedStr);
|
|
6016
7579
|
console.log(` ${BOLD}Tx:${RESET} ${result2.txHash}`);
|
|
6017
7580
|
if (result2.type === "broadcasted") {
|
|
6018
7581
|
console.log(` ${BOLD}Status:${RESET} ${GREEN}broadcasted${RESET}`);
|
|
@@ -6091,7 +7654,7 @@ async function handleTx(target, args, opts) {
|
|
|
6091
7654
|
console.log();
|
|
6092
7655
|
console.log(` ${BOLD}Chain:${RESET} ${chainName}`);
|
|
6093
7656
|
console.log(` ${BOLD}Call:${RESET} ${callHex}`);
|
|
6094
|
-
|
|
7657
|
+
printDecodedCall(decodedObj, decodedStr);
|
|
6095
7658
|
if (nonce !== undefined)
|
|
6096
7659
|
console.log(` ${BOLD}Nonce:${RESET} ${nonce}`);
|
|
6097
7660
|
if (tip !== undefined)
|
|
@@ -6178,6 +7741,39 @@ function decodeCall(meta, callHex) {
|
|
|
6178
7741
|
return "(unable to decode)";
|
|
6179
7742
|
}
|
|
6180
7743
|
}
|
|
7744
|
+
function decodeCallObject(meta, callHex) {
|
|
7745
|
+
try {
|
|
7746
|
+
const callTypeId = meta.lookup.call;
|
|
7747
|
+
if (callTypeId == null)
|
|
7748
|
+
return null;
|
|
7749
|
+
const codec = meta.builder.buildDefinition(callTypeId);
|
|
7750
|
+
const decoded = codec.dec(Binary3.fromHex(callHex));
|
|
7751
|
+
return {
|
|
7752
|
+
palletName: decoded.type,
|
|
7753
|
+
callName: decoded.value.type,
|
|
7754
|
+
args: sanitizeForSerialization(decoded.value.value)
|
|
7755
|
+
};
|
|
7756
|
+
} catch {
|
|
7757
|
+
return null;
|
|
7758
|
+
}
|
|
7759
|
+
}
|
|
7760
|
+
function printDecodedCall(obj, fallback) {
|
|
7761
|
+
if (!obj) {
|
|
7762
|
+
console.log(` ${BOLD}Decode:${RESET} ${fallback}`);
|
|
7763
|
+
return;
|
|
7764
|
+
}
|
|
7765
|
+
const header = `${CYAN}${obj.palletName}${RESET}.${CYAN}${obj.callName}${RESET}`;
|
|
7766
|
+
const hasArgs = obj.args !== null && obj.args !== undefined && !(typeof obj.args === "object" && Object.keys(obj.args).length === 0);
|
|
7767
|
+
if (!hasArgs) {
|
|
7768
|
+
console.log(` ${BOLD}Decode:${RESET} ${header}`);
|
|
7769
|
+
return;
|
|
7770
|
+
}
|
|
7771
|
+
console.log(` ${BOLD}Decode:${RESET} ${header}`);
|
|
7772
|
+
const indented = formatPretty(obj.args).split(`
|
|
7773
|
+
`).map((l) => ` ${l}`).join(`
|
|
7774
|
+
`);
|
|
7775
|
+
console.log(indented);
|
|
7776
|
+
}
|
|
6181
7777
|
function decodeCallFallback(meta, callHex) {
|
|
6182
7778
|
const callTypeId = meta.lookup.call;
|
|
6183
7779
|
if (callTypeId == null)
|
|
@@ -7321,13 +8917,13 @@ function isNewerVersion(current, latest) {
|
|
|
7321
8917
|
return compareSemver(current, latest) < 0;
|
|
7322
8918
|
}
|
|
7323
8919
|
function buildNotificationBox(current, latest) {
|
|
7324
|
-
const
|
|
7325
|
-
const
|
|
7326
|
-
const
|
|
7327
|
-
const
|
|
8920
|
+
const YELLOW3 = "\x1B[33m";
|
|
8921
|
+
const GREEN3 = "\x1B[32m";
|
|
8922
|
+
const CYAN3 = "\x1B[36m";
|
|
8923
|
+
const RESET3 = "\x1B[0m";
|
|
7328
8924
|
const BOLD2 = "\x1B[1m";
|
|
7329
|
-
const line1 = `Update available! ${
|
|
7330
|
-
const line2 = `Run ${
|
|
8925
|
+
const line1 = `Update available! ${YELLOW3}${current}${RESET3} → ${GREEN3}${BOLD2}${latest}${RESET3}`;
|
|
8926
|
+
const line2 = `Run ${CYAN3}npm i -g polkadot-cli${RESET3} to update`;
|
|
7331
8927
|
const visibleLine1 = `Update available! ${current} → ${latest}`;
|
|
7332
8928
|
const visibleLine2 = `Run npm i -g polkadot-cli to update`;
|
|
7333
8929
|
const innerWidth = Math.max(visibleLine1.length, visibleLine2.length) + 4;
|
|
@@ -7458,7 +9054,8 @@ var CATEGORY_ALIASES = {
|
|
|
7458
9054
|
api: "apis",
|
|
7459
9055
|
extensions: "extensions",
|
|
7460
9056
|
extension: "extensions",
|
|
7461
|
-
ext: "extensions"
|
|
9057
|
+
ext: "extensions",
|
|
9058
|
+
rpc: "rpc"
|
|
7462
9059
|
};
|
|
7463
9060
|
function matchCategory(segment) {
|
|
7464
9061
|
return CATEGORY_ALIASES[segment.toLowerCase()];
|
|
@@ -7473,7 +9070,7 @@ function parseDotPath(input, knownChains = []) {
|
|
|
7473
9070
|
const cat = matchCategory(parts[0]);
|
|
7474
9071
|
if (cat)
|
|
7475
9072
|
return { category: cat };
|
|
7476
|
-
throw new Error(`Unknown command "${parts[0]}". Expected a category (query, tx, const, events, errors, apis, extensions) or a named command.`);
|
|
9073
|
+
throw new Error(`Unknown command "${parts[0]}". Expected a category (query, tx, const, events, errors, apis, extensions, rpc) or a named command.`);
|
|
7477
9074
|
}
|
|
7478
9075
|
case 2: {
|
|
7479
9076
|
const cat = matchCategory(parts[0]);
|
|
@@ -7555,6 +9152,7 @@ if (process.argv[2] === "__complete") {
|
|
|
7555
9152
|
console.log(" errors List or inspect pallet errors");
|
|
7556
9153
|
console.log(" apis Browse and call runtime APIs");
|
|
7557
9154
|
console.log(" extensions List transaction extensions on a chain");
|
|
9155
|
+
console.log(" rpc Call raw JSON-RPC methods on a node");
|
|
7558
9156
|
console.log();
|
|
7559
9157
|
console.log("Examples:");
|
|
7560
9158
|
console.log(" dot polkadot.query.System.Account <addr> Query a storage item");
|
|
@@ -7567,6 +9165,8 @@ if (process.argv[2] === "__complete") {
|
|
|
7567
9165
|
console.log(" dot metadata polkadot Dump runtime metadata as JSON");
|
|
7568
9166
|
console.log(" dot polkadot.extensions List transaction extensions");
|
|
7569
9167
|
console.log(" dot polkadot.extensions.CheckMortality Inspect one extension");
|
|
9168
|
+
console.log(" dot polkadot.rpc List RPC methods on the node");
|
|
9169
|
+
console.log(" dot polkadot.rpc.system_health Call a JSON-RPC method");
|
|
7570
9170
|
console.log(" dot query.System.Number --chain polkadot --chain flag form");
|
|
7571
9171
|
console.log(" dot ./transfer.yaml --from alice Run from file (chain in YAML)");
|
|
7572
9172
|
console.log(" dot tx.0x1f0003... --to-yaml --chain polkadot Decode hex call to YAML");
|
|
@@ -7580,7 +9180,7 @@ if (process.argv[2] === "__complete") {
|
|
|
7580
9180
|
console.log(" account Manage accounts");
|
|
7581
9181
|
console.log(" hash Hash utilities");
|
|
7582
9182
|
console.log(" sign Sign a message with an account keypair");
|
|
7583
|
-
console.log(" parachain Derive parachain sovereign accounts");
|
|
9183
|
+
console.log(" parachain Derive parachain sovereign accounts (deprecated \u2014 use `account inspect --parachain`)");
|
|
7584
9184
|
console.log(" verifiable Derive Bandersnatch member key from mnemonic");
|
|
7585
9185
|
console.log(" completions <sh> Generate shell completions (zsh, bash, fish)");
|
|
7586
9186
|
console.log();
|
|
@@ -7611,7 +9211,7 @@ if (process.argv[2] === "__complete") {
|
|
|
7611
9211
|
registerVerifiableCommands(cli);
|
|
7612
9212
|
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("--to-yaml", "Decode call to YAML file format (for tx)").option("--to-json", "Decode call to JSON file format (for tx)").option("--ext <json>", "Custom signed extension values as JSON (for tx)").option("--asset <json>", "Pay fees in an alternative asset (XCM location JSON, for tx)").option("-w, --wait <level>", "Resolve at: broadcast, best-block (or best), finalized (for tx)", {
|
|
7613
9213
|
default: "finalized"
|
|
7614
|
-
}).option("--dump", "Dump all entries of a storage map (without specifying a key)").option("--var <kv>", "Template variable for file input (KEY=VALUE, repeatable)").option("--nonce <n>", "Custom nonce for manual tx sequencing (for tx)").option("--tip <amount>", "Tip to prioritize transaction (for tx)").option("--mortality <spec>", '"immortal" or period number (for tx)').option("--at <block>", 'Block hash, "best", or "finalized" to validate against (for tx)').option("--unsigned", "Submit as unsigned/bare transaction (no signer required, for tx)").action(async (dotpath, args, opts) => {
|
|
9214
|
+
}).option("--dump", "Dump all entries of a storage map (without specifying a key)").option("--var <kv>", "Template variable for file input (KEY=VALUE, repeatable)").option("--nonce <n>", "Custom nonce for manual tx sequencing (for tx)").option("--tip <amount>", "Tip to prioritize transaction (for tx)").option("--mortality <spec>", '"immortal" or period number (for tx)').option("--at <block>", 'Block hash, "best", or "finalized" to validate against (for tx)').option("--unsigned", "Submit as unsigned/bare transaction (no signer required, for tx)").option("--refresh", "Refresh the cached RPC method list from the node (for rpc)").action(async (dotpath, args, opts) => {
|
|
7615
9215
|
if (!dotpath) {
|
|
7616
9216
|
printHelp();
|
|
7617
9217
|
return;
|
|
@@ -7674,9 +9274,10 @@ if (process.argv[2] === "__complete") {
|
|
|
7674
9274
|
} catch {
|
|
7675
9275
|
throw new CliError2(`Unknown command "${dotpath}". Run "dot --help" for available commands.`);
|
|
7676
9276
|
}
|
|
9277
|
+
const isFlatCategory = parsed.category === "rpc" || parsed.category === "extensions";
|
|
7677
9278
|
if (!parsed.pallet && args.length > 0) {
|
|
7678
9279
|
parsed.pallet = args.shift();
|
|
7679
|
-
if (!parsed.item && args.length > 0) {
|
|
9280
|
+
if (!isFlatCategory && !parsed.item && args.length > 0) {
|
|
7680
9281
|
parsed.item = args.shift();
|
|
7681
9282
|
}
|
|
7682
9283
|
}
|
|
@@ -7743,6 +9344,18 @@ if (process.argv[2] === "__complete") {
|
|
|
7743
9344
|
await handleExtensions(parsed.pallet, handlerOpts);
|
|
7744
9345
|
break;
|
|
7745
9346
|
}
|
|
9347
|
+
case "rpc": {
|
|
9348
|
+
if (parsed.item) {
|
|
9349
|
+
const suggestion = parsed.chain ? `dot ${parsed.chain}.rpc.${parsed.pallet}` : opts.chain ? `dot rpc.${parsed.pallet} --chain ${opts.chain}` : `dot rpc.${parsed.pallet} --chain <chain>`;
|
|
9350
|
+
throw new CliError2(`RPC methods have no sub-items. Try "${suggestion}".`);
|
|
9351
|
+
}
|
|
9352
|
+
await handleRpc(parsed.pallet, args, {
|
|
9353
|
+
...handlerOpts,
|
|
9354
|
+
help: cli.options.help,
|
|
9355
|
+
refresh: opts.refresh
|
|
9356
|
+
});
|
|
9357
|
+
break;
|
|
9358
|
+
}
|
|
7746
9359
|
}
|
|
7747
9360
|
});
|
|
7748
9361
|
cli.option("--help, -h", "Display this message");
|