polkadot-cli 1.2.0 → 1.3.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 +29 -0
- package/dist/cli.mjs +1067 -648
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,141 +1,145 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __returnValue = (v) => v;
|
|
5
|
+
function __exportSetter(name, newValue) {
|
|
6
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
7
|
+
}
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true,
|
|
13
|
+
configurable: true,
|
|
14
|
+
set: __exportSetter.bind(all, name)
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
3
18
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
4
19
|
|
|
5
|
-
// src/cli.ts
|
|
6
|
-
import cac from "cac";
|
|
7
|
-
// package.json
|
|
8
|
-
var version = "1.2.0";
|
|
9
|
-
|
|
10
|
-
// src/config/accounts-store.ts
|
|
11
|
-
import { access as access2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
12
|
-
import { join as join2 } from "node:path";
|
|
13
|
-
|
|
14
|
-
// src/config/store.ts
|
|
15
|
-
import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
16
|
-
import { homedir } from "node:os";
|
|
17
|
-
import { join } from "node:path";
|
|
18
|
-
|
|
19
20
|
// src/config/types.ts
|
|
20
21
|
function primaryRpc(rpc) {
|
|
21
22
|
return Array.isArray(rpc) ? rpc[0] : rpc;
|
|
22
23
|
}
|
|
23
|
-
var DEFAULT_CONFIG
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
24
|
+
var DEFAULT_CONFIG, BUILTIN_CHAIN_NAMES;
|
|
25
|
+
var init_types = __esm(() => {
|
|
26
|
+
DEFAULT_CONFIG = {
|
|
27
|
+
defaultChain: "polkadot",
|
|
28
|
+
chains: {
|
|
29
|
+
polkadot: {
|
|
30
|
+
rpc: [
|
|
31
|
+
"wss://polkadot.ibp.network",
|
|
32
|
+
"wss://polkadot.dotters.network",
|
|
33
|
+
"wss://polkadot-rpc.n.dwellir.com",
|
|
34
|
+
"wss://polkadot-rpc.publicnode.com",
|
|
35
|
+
"wss://rpc-polkadot.luckyfriday.io",
|
|
36
|
+
"wss://polkadot.api.onfinality.io/public-ws",
|
|
37
|
+
"wss://rpc-polkadot.helixstreet.io",
|
|
38
|
+
"wss://polkadot-rpc-tn.dwellir.com",
|
|
39
|
+
"wss://polkadot.public.curie.radiumblock.co/ws",
|
|
40
|
+
"wss://rpc-polkadot.stakeworld.io",
|
|
41
|
+
"wss://polkadot.rpc.subquery.network/public/ws",
|
|
42
|
+
"wss://rpc.polkadot.io"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
"polkadot-asset-hub": {
|
|
46
|
+
rpc: [
|
|
47
|
+
"wss://polkadot-asset-hub-rpc.polkadot.io",
|
|
48
|
+
"wss://asset-hub-polkadot.ibp.network",
|
|
49
|
+
"wss://asset-hub-polkadot.dotters.network",
|
|
50
|
+
"wss://asset-hub-polkadot-rpc.n.dwellir.com",
|
|
51
|
+
"wss://rpc-asset-hub-polkadot.luckyfriday.io",
|
|
52
|
+
"wss://statemint.api.onfinality.io/public-ws",
|
|
53
|
+
"wss://statemint-rpc-tn.dwellir.com",
|
|
54
|
+
"wss://statemint.public.curie.radiumblock.co/ws",
|
|
55
|
+
"wss://asset-hub-polkadot.rpc.permanence.io"
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
"polkadot-bridge-hub": {
|
|
59
|
+
rpc: [
|
|
60
|
+
"wss://polkadot-bridge-hub-rpc.polkadot.io",
|
|
61
|
+
"wss://bridge-hub-polkadot.ibp.network",
|
|
62
|
+
"wss://bridge-hub-polkadot.dotters.network",
|
|
63
|
+
"wss://bridge-hub-polkadot-rpc.n.dwellir.com",
|
|
64
|
+
"wss://rpc-bridge-hub-polkadot.luckyfriday.io",
|
|
65
|
+
"wss://bridgehub-polkadot.api.onfinality.io/public-ws",
|
|
66
|
+
"wss://polkadot-bridge-hub-rpc-tn.dwellir.com",
|
|
67
|
+
"wss://bridgehub-polkadot.public.curie.radiumblock.co/ws"
|
|
68
|
+
]
|
|
69
|
+
},
|
|
70
|
+
"polkadot-collectives": {
|
|
71
|
+
rpc: [
|
|
72
|
+
"wss://polkadot-collectives-rpc.polkadot.io",
|
|
73
|
+
"wss://collectives-polkadot.ibp.network",
|
|
74
|
+
"wss://collectives-polkadot.dotters.network",
|
|
75
|
+
"wss://collectives-polkadot-rpc.n.dwellir.com",
|
|
76
|
+
"wss://rpc-collectives-polkadot.luckyfriday.io",
|
|
77
|
+
"wss://collectives.api.onfinality.io/public-ws",
|
|
78
|
+
"wss://polkadot-collectives-rpc-tn.dwellir.com",
|
|
79
|
+
"wss://collectives.public.curie.radiumblock.co/ws"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"polkadot-coretime": {
|
|
83
|
+
rpc: [
|
|
84
|
+
"wss://polkadot-coretime-rpc.polkadot.io",
|
|
85
|
+
"wss://coretime-polkadot.ibp.network",
|
|
86
|
+
"wss://coretime-polkadot.dotters.network",
|
|
87
|
+
"wss://coretime-polkadot-rpc.n.dwellir.com",
|
|
88
|
+
"wss://rpc-coretime-polkadot.luckyfriday.io",
|
|
89
|
+
"wss://coretime-polkadot.api.onfinality.io/public-ws"
|
|
90
|
+
]
|
|
91
|
+
},
|
|
92
|
+
"polkadot-people": {
|
|
93
|
+
rpc: [
|
|
94
|
+
"wss://polkadot-people-rpc.polkadot.io",
|
|
95
|
+
"wss://people-polkadot.ibp.network",
|
|
96
|
+
"wss://people-polkadot.dotters.network",
|
|
97
|
+
"wss://people-polkadot-rpc.n.dwellir.com",
|
|
98
|
+
"wss://rpc-people-polkadot.luckyfriday.io",
|
|
99
|
+
"wss://people-polkadot.api.onfinality.io/public-ws"
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
paseo: {
|
|
103
|
+
rpc: [
|
|
104
|
+
"wss://paseo.ibp.network",
|
|
105
|
+
"wss://paseo.dotters.network",
|
|
106
|
+
"wss://paseo-rpc.n.dwellir.com",
|
|
107
|
+
"wss://paseo.rpc.amforc.com"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
"paseo-asset-hub": {
|
|
111
|
+
rpc: [
|
|
112
|
+
"wss://asset-hub-paseo.ibp.network",
|
|
113
|
+
"wss://asset-hub-paseo.dotters.network",
|
|
114
|
+
"wss://asset-hub-paseo-rpc.n.dwellir.com",
|
|
115
|
+
"wss://sys.turboflakes.io/asset-hub-paseo"
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"paseo-bridge-hub": {
|
|
119
|
+
rpc: ["wss://bridge-hub-paseo.ibp.network", "wss://bridge-hub-paseo.dotters.network"]
|
|
120
|
+
},
|
|
121
|
+
"paseo-collectives": {
|
|
122
|
+
rpc: ["wss://collectives-paseo.ibp.network", "wss://collectives-paseo.dotters.network"]
|
|
123
|
+
},
|
|
124
|
+
"paseo-coretime": {
|
|
125
|
+
rpc: ["wss://coretime-paseo.ibp.network", "wss://coretime-paseo.dotters.network"]
|
|
126
|
+
},
|
|
127
|
+
"paseo-people": {
|
|
128
|
+
rpc: [
|
|
129
|
+
"wss://people-paseo.ibp.network",
|
|
130
|
+
"wss://people-paseo.dotters.network",
|
|
131
|
+
"wss://people-paseo.rpc.amforc.com"
|
|
132
|
+
]
|
|
133
|
+
}
|
|
130
134
|
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
135
|
+
};
|
|
136
|
+
BUILTIN_CHAIN_NAMES = new Set(Object.keys(DEFAULT_CONFIG.chains));
|
|
137
|
+
});
|
|
134
138
|
|
|
135
139
|
// src/config/store.ts
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
141
|
+
import { homedir } from "node:os";
|
|
142
|
+
import { join } from "node:path";
|
|
139
143
|
function getConfigDir() {
|
|
140
144
|
return DOT_DIR;
|
|
141
145
|
}
|
|
@@ -203,9 +207,17 @@ function resolveChain(config, chainFlag) {
|
|
|
203
207
|
}
|
|
204
208
|
return { name, chain: config.chains[name] };
|
|
205
209
|
}
|
|
210
|
+
var DOT_DIR, CONFIG_PATH, CHAINS_DIR;
|
|
211
|
+
var init_store = __esm(() => {
|
|
212
|
+
init_types();
|
|
213
|
+
DOT_DIR = join(homedir(), ".polkadot");
|
|
214
|
+
CONFIG_PATH = join(DOT_DIR, "config.json");
|
|
215
|
+
CHAINS_DIR = join(DOT_DIR, "chains");
|
|
216
|
+
});
|
|
206
217
|
|
|
207
218
|
// src/config/accounts-store.ts
|
|
208
|
-
|
|
219
|
+
import { access as access2, mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
220
|
+
import { join as join2 } from "node:path";
|
|
209
221
|
async function ensureDir2(dir) {
|
|
210
222
|
await mkdir2(dir, { recursive: true });
|
|
211
223
|
}
|
|
@@ -233,6 +245,11 @@ async function saveAccounts(file) {
|
|
|
233
245
|
function findAccount(file, name) {
|
|
234
246
|
return file.accounts.find((a) => a.name.toLowerCase() === name.toLowerCase());
|
|
235
247
|
}
|
|
248
|
+
var ACCOUNTS_PATH;
|
|
249
|
+
var init_accounts_store = __esm(() => {
|
|
250
|
+
init_store();
|
|
251
|
+
ACCOUNTS_PATH = join2(getConfigDir(), "accounts.json");
|
|
252
|
+
});
|
|
236
253
|
|
|
237
254
|
// src/config/accounts-types.ts
|
|
238
255
|
function isEnvSecret(secret) {
|
|
@@ -254,7 +271,6 @@ import {
|
|
|
254
271
|
validateMnemonic
|
|
255
272
|
} from "@polkadot-labs/hdkd-helpers";
|
|
256
273
|
import { getPolkadotSigner } from "polkadot-api/signer";
|
|
257
|
-
var DEV_NAMES = ["alice", "bob", "charlie", "dave", "eve", "ferdie"];
|
|
258
274
|
function isDevAccount(name) {
|
|
259
275
|
return DEV_NAMES.includes(name.toLowerCase());
|
|
260
276
|
}
|
|
@@ -316,55 +332,610 @@ function toSs58(publicKey, prefix = 42) {
|
|
|
316
332
|
}
|
|
317
333
|
return ss58Address(bytes, prefix);
|
|
318
334
|
}
|
|
319
|
-
return ss58Address(publicKey, prefix);
|
|
320
|
-
}
|
|
321
|
-
function fromSs58(address) {
|
|
322
|
-
const [payload] = ss58Decode(address);
|
|
323
|
-
return payload;
|
|
324
|
-
}
|
|
325
|
-
function isHexPublicKey(input) {
|
|
326
|
-
return /^0x[0-9a-fA-F]{64}$/.test(input);
|
|
335
|
+
return ss58Address(publicKey, prefix);
|
|
336
|
+
}
|
|
337
|
+
function fromSs58(address) {
|
|
338
|
+
const [payload] = ss58Decode(address);
|
|
339
|
+
return payload;
|
|
340
|
+
}
|
|
341
|
+
function isHexPublicKey(input) {
|
|
342
|
+
return /^0x[0-9a-fA-F]{64}$/.test(input);
|
|
343
|
+
}
|
|
344
|
+
function resolveSecret(secret) {
|
|
345
|
+
if (isEnvSecret(secret)) {
|
|
346
|
+
const value = process.env[secret.env];
|
|
347
|
+
if (!value) {
|
|
348
|
+
throw new Error(`Environment variable "${secret.env}" is not set. Set it before signing.`);
|
|
349
|
+
}
|
|
350
|
+
return value;
|
|
351
|
+
}
|
|
352
|
+
return secret;
|
|
353
|
+
}
|
|
354
|
+
function tryDerivePublicKey(envVarName, path = "") {
|
|
355
|
+
const value = process.env[envVarName];
|
|
356
|
+
if (!value)
|
|
357
|
+
return null;
|
|
358
|
+
try {
|
|
359
|
+
const { publicKey } = importAccount(value, path);
|
|
360
|
+
return publicKeyToHex(publicKey);
|
|
361
|
+
} catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
async function resolveAccountSigner(name) {
|
|
366
|
+
if (isDevAccount(name)) {
|
|
367
|
+
const keypair2 = getDevKeypair(name);
|
|
368
|
+
return getPolkadotSigner(keypair2.publicKey, "Sr25519", keypair2.sign);
|
|
369
|
+
}
|
|
370
|
+
const accountsFile = await loadAccounts();
|
|
371
|
+
const account = findAccount(accountsFile, name);
|
|
372
|
+
if (!account) {
|
|
373
|
+
const available = [...DEV_NAMES, ...accountsFile.accounts.map((a) => a.name)];
|
|
374
|
+
throw new Error(`Unknown account "${name}". Available accounts: ${available.join(", ")}`);
|
|
375
|
+
}
|
|
376
|
+
if (account.secret === undefined) {
|
|
377
|
+
throw new Error(`Account "${name}" is watch-only (no secret). Cannot sign. Import with --secret or --env.`);
|
|
378
|
+
}
|
|
379
|
+
const secret = resolveSecret(account.secret);
|
|
380
|
+
const isHexSeed = /^0x[0-9a-fA-F]{64}$/.test(secret);
|
|
381
|
+
const keypair = isHexSeed ? deriveFromHexSeed(secret, account.derivationPath) : deriveFromMnemonic(secret, account.derivationPath);
|
|
382
|
+
return getPolkadotSigner(keypair.publicKey, "Sr25519", keypair.sign);
|
|
383
|
+
}
|
|
384
|
+
var DEV_NAMES;
|
|
385
|
+
var init_accounts = __esm(() => {
|
|
386
|
+
init_accounts_store();
|
|
387
|
+
DEV_NAMES = ["alice", "bob", "charlie", "dave", "eve", "ferdie"];
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// src/utils/errors.ts
|
|
391
|
+
var CliError, ConnectionError, MetadataError;
|
|
392
|
+
var init_errors = __esm(() => {
|
|
393
|
+
CliError = class CliError extends Error {
|
|
394
|
+
constructor(message) {
|
|
395
|
+
super(message);
|
|
396
|
+
this.name = "CliError";
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
ConnectionError = class ConnectionError extends CliError {
|
|
400
|
+
constructor(message) {
|
|
401
|
+
super(message);
|
|
402
|
+
this.name = "ConnectionError";
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
MetadataError = class MetadataError extends CliError {
|
|
406
|
+
constructor(message) {
|
|
407
|
+
super(message);
|
|
408
|
+
this.name = "MetadataError";
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// src/core/metadata.ts
|
|
414
|
+
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders";
|
|
415
|
+
import { decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
|
|
416
|
+
function parseMetadata(raw) {
|
|
417
|
+
const decoded = decAnyMetadata(raw);
|
|
418
|
+
const unified = unifyMetadata(decoded);
|
|
419
|
+
const lookup = getLookupFn(unified);
|
|
420
|
+
const builder = getDynamicBuilder(lookup);
|
|
421
|
+
return { unified, lookup, builder };
|
|
422
|
+
}
|
|
423
|
+
async function fetchMetadataFromChain(clientHandle, chainName) {
|
|
424
|
+
const { client } = clientHandle;
|
|
425
|
+
try {
|
|
426
|
+
const hex = await Promise.race([
|
|
427
|
+
client._request("state_getMetadata", []),
|
|
428
|
+
new Promise((_, reject) => setTimeout(() => reject(new ConnectionError(`Timed out fetching metadata for "${chainName}" after ${METADATA_TIMEOUT_MS / 1000}s. ` + "Check that the RPC endpoint is correct and reachable.")), METADATA_TIMEOUT_MS))
|
|
429
|
+
]);
|
|
430
|
+
const bytes = hexToBytes(hex);
|
|
431
|
+
await saveMetadata(chainName, bytes);
|
|
432
|
+
return bytes;
|
|
433
|
+
} catch (err) {
|
|
434
|
+
if (err instanceof ConnectionError)
|
|
435
|
+
throw err;
|
|
436
|
+
throw new ConnectionError(`Failed to fetch metadata for "${chainName}": ${err instanceof Error ? err.message : err}. ` + "Check that the RPC endpoint is correct and reachable.");
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async function getOrFetchMetadata(chainName, clientHandle) {
|
|
440
|
+
let raw = await loadMetadata(chainName);
|
|
441
|
+
if (!raw) {
|
|
442
|
+
if (!clientHandle) {
|
|
443
|
+
throw new MetadataError(`No cached metadata for chain "${chainName}". Run a command that connects to the chain first, ` + `e.g.: dot chain add ${chainName} --rpc <url>`);
|
|
444
|
+
}
|
|
445
|
+
raw = await fetchMetadataFromChain(clientHandle, chainName);
|
|
446
|
+
}
|
|
447
|
+
return parseMetadata(raw);
|
|
448
|
+
}
|
|
449
|
+
function listPallets(meta) {
|
|
450
|
+
return meta.unified.pallets.map((p) => ({
|
|
451
|
+
name: p.name,
|
|
452
|
+
index: p.index,
|
|
453
|
+
docs: p.docs ?? [],
|
|
454
|
+
storage: (p.storage?.items ?? []).map((s) => ({
|
|
455
|
+
name: s.name,
|
|
456
|
+
docs: s.docs ?? [],
|
|
457
|
+
type: s.type.tag,
|
|
458
|
+
keyTypeId: s.type.tag === "map" ? s.type.value.key : null,
|
|
459
|
+
valueTypeId: s.type.tag === "plain" ? s.type.value : s.type.value.value
|
|
460
|
+
})),
|
|
461
|
+
constants: (p.constants ?? []).map((c) => ({
|
|
462
|
+
name: c.name,
|
|
463
|
+
docs: c.docs ?? [],
|
|
464
|
+
typeId: c.type
|
|
465
|
+
})),
|
|
466
|
+
calls: extractEnumVariants(meta, p.calls),
|
|
467
|
+
events: extractEnumVariants(meta, p.events),
|
|
468
|
+
errors: extractEnumVariants(meta, p.errors).map(({ name, docs }) => ({ name, docs }))
|
|
469
|
+
}));
|
|
470
|
+
}
|
|
471
|
+
function extractEnumVariants(meta, ref) {
|
|
472
|
+
if (!ref)
|
|
473
|
+
return [];
|
|
474
|
+
try {
|
|
475
|
+
const entry = meta.lookup(ref.type);
|
|
476
|
+
if (entry.type !== "enum")
|
|
477
|
+
return [];
|
|
478
|
+
return Object.entries(entry.value).map(([name, variant]) => ({
|
|
479
|
+
name,
|
|
480
|
+
docs: entry.innerDocs?.[name] ?? [],
|
|
481
|
+
typeId: resolveVariantTypeId(variant)
|
|
482
|
+
}));
|
|
483
|
+
} catch {
|
|
484
|
+
return [];
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function resolveVariantTypeId(variant) {
|
|
488
|
+
if (variant.type === "lookupEntry")
|
|
489
|
+
return variant.value?.id ?? null;
|
|
490
|
+
if (variant.type === "struct")
|
|
491
|
+
return null;
|
|
492
|
+
if (variant.type === "void" || variant.type === "empty")
|
|
493
|
+
return null;
|
|
494
|
+
return null;
|
|
495
|
+
}
|
|
496
|
+
function findPallet(meta, palletName) {
|
|
497
|
+
const pallets = listPallets(meta);
|
|
498
|
+
return pallets.find((p) => p.name.toLowerCase() === palletName.toLowerCase());
|
|
499
|
+
}
|
|
500
|
+
function getSignedExtensions(meta) {
|
|
501
|
+
const byVersion = meta.unified.extrinsic.signedExtensions;
|
|
502
|
+
const versionKeys = Object.keys(byVersion);
|
|
503
|
+
if (versionKeys.length === 0)
|
|
504
|
+
return [];
|
|
505
|
+
return byVersion[Number(versionKeys[0])] ?? [];
|
|
506
|
+
}
|
|
507
|
+
function getPalletNames(meta) {
|
|
508
|
+
return meta.unified.pallets.map((p) => p.name);
|
|
509
|
+
}
|
|
510
|
+
function describeType(lookup, typeId) {
|
|
511
|
+
try {
|
|
512
|
+
const entry = lookup(typeId);
|
|
513
|
+
return formatLookupEntry(entry);
|
|
514
|
+
} catch {
|
|
515
|
+
return `type(${typeId})`;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
function formatLookupEntry(entry) {
|
|
519
|
+
switch (entry.type) {
|
|
520
|
+
case "primitive":
|
|
521
|
+
return entry.value;
|
|
522
|
+
case "compact":
|
|
523
|
+
return `Compact<${formatLookupEntry(entry.isBig ? { type: "primitive", value: "u128" } : { type: "primitive", value: "u64" })}>`;
|
|
524
|
+
case "AccountId32":
|
|
525
|
+
return "AccountId32";
|
|
526
|
+
case "bitSequence":
|
|
527
|
+
return "BitSequence";
|
|
528
|
+
case "sequence":
|
|
529
|
+
return `Vec<${formatLookupEntry(entry.value)}>`;
|
|
530
|
+
case "array":
|
|
531
|
+
return `[${formatLookupEntry(entry.value)}; ${entry.len}]`;
|
|
532
|
+
case "tuple":
|
|
533
|
+
return `(${entry.value.map(formatLookupEntry).join(", ")})`;
|
|
534
|
+
case "struct":
|
|
535
|
+
return `{ ${Object.entries(entry.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ")} }`;
|
|
536
|
+
case "option":
|
|
537
|
+
return `Option<${formatLookupEntry(entry.value)}>`;
|
|
538
|
+
case "result":
|
|
539
|
+
return `Result<${formatLookupEntry(entry.value.ok)}, ${formatLookupEntry(entry.value.ko)}>`;
|
|
540
|
+
case "enum": {
|
|
541
|
+
const variants = Object.keys(entry.value);
|
|
542
|
+
if (variants.length <= 4)
|
|
543
|
+
return variants.join(" | ");
|
|
544
|
+
return `enum(${variants.length} variants)`;
|
|
545
|
+
}
|
|
546
|
+
default:
|
|
547
|
+
return "unknown";
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
function describeCallArgs(meta, palletName, callName) {
|
|
551
|
+
try {
|
|
552
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
553
|
+
if (!palletMeta?.calls)
|
|
554
|
+
return "";
|
|
555
|
+
const callsEntry = meta.lookup(palletMeta.calls.type);
|
|
556
|
+
if (callsEntry.type !== "enum")
|
|
557
|
+
return "";
|
|
558
|
+
const variant = callsEntry.value[callName];
|
|
559
|
+
if (!variant)
|
|
560
|
+
return "";
|
|
561
|
+
if (variant.type === "void")
|
|
562
|
+
return "()";
|
|
563
|
+
if (variant.type === "struct") {
|
|
564
|
+
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
565
|
+
return `(${fields})`;
|
|
566
|
+
}
|
|
567
|
+
if (variant.type === "lookupEntry") {
|
|
568
|
+
const inner = variant.value;
|
|
569
|
+
if (inner.type === "void")
|
|
570
|
+
return "()";
|
|
571
|
+
if (inner.type === "struct") {
|
|
572
|
+
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
573
|
+
return `(${fields})`;
|
|
574
|
+
}
|
|
575
|
+
return `(${formatLookupEntry(inner)})`;
|
|
576
|
+
}
|
|
577
|
+
if (variant.type === "tuple") {
|
|
578
|
+
const types = variant.value.map(formatLookupEntry).join(", ");
|
|
579
|
+
return `(${types})`;
|
|
580
|
+
}
|
|
581
|
+
return "";
|
|
582
|
+
} catch {
|
|
583
|
+
return "";
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
function describeEventFields(meta, palletName, eventName) {
|
|
587
|
+
try {
|
|
588
|
+
const palletMeta = meta.unified.pallets.find((p) => p.name === palletName);
|
|
589
|
+
if (!palletMeta?.events)
|
|
590
|
+
return "";
|
|
591
|
+
const eventsEntry = meta.lookup(palletMeta.events.type);
|
|
592
|
+
if (eventsEntry.type !== "enum")
|
|
593
|
+
return "";
|
|
594
|
+
const variant = eventsEntry.value[eventName];
|
|
595
|
+
if (!variant)
|
|
596
|
+
return "";
|
|
597
|
+
if (variant.type === "void")
|
|
598
|
+
return "()";
|
|
599
|
+
if (variant.type === "struct") {
|
|
600
|
+
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
601
|
+
return `(${fields})`;
|
|
602
|
+
}
|
|
603
|
+
if (variant.type === "lookupEntry") {
|
|
604
|
+
const inner = variant.value;
|
|
605
|
+
if (inner.type === "void")
|
|
606
|
+
return "()";
|
|
607
|
+
if (inner.type === "struct") {
|
|
608
|
+
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
609
|
+
return `(${fields})`;
|
|
610
|
+
}
|
|
611
|
+
return `(${formatLookupEntry(inner)})`;
|
|
612
|
+
}
|
|
613
|
+
if (variant.type === "tuple") {
|
|
614
|
+
const types = variant.value.map(formatLookupEntry).join(", ");
|
|
615
|
+
return `(${types})`;
|
|
616
|
+
}
|
|
617
|
+
return "";
|
|
618
|
+
} catch {
|
|
619
|
+
return "";
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function hexToBytes(hex) {
|
|
623
|
+
const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
|
|
624
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
625
|
+
for (let i = 0;i < clean.length; i += 2) {
|
|
626
|
+
bytes[i / 2] = parseInt(clean.substring(i, i + 2), 16);
|
|
627
|
+
}
|
|
628
|
+
return bytes;
|
|
629
|
+
}
|
|
630
|
+
var METADATA_TIMEOUT_MS = 15000;
|
|
631
|
+
var init_metadata = __esm(() => {
|
|
632
|
+
init_store();
|
|
633
|
+
init_errors();
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
// src/core/hash.ts
|
|
637
|
+
import { blake2b } from "@noble/hashes/blake2.js";
|
|
638
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
639
|
+
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
640
|
+
import { bytesToHex, hexToBytes as hexToBytes2 } from "@noble/hashes/utils.js";
|
|
641
|
+
function computeHash(algorithm, data) {
|
|
642
|
+
const algo = ALGORITHMS[algorithm];
|
|
643
|
+
if (!algo) {
|
|
644
|
+
throw new Error(`Unknown algorithm: ${algorithm}`);
|
|
645
|
+
}
|
|
646
|
+
return algo.compute(data);
|
|
647
|
+
}
|
|
648
|
+
function parseInputData(input) {
|
|
649
|
+
if (input.startsWith("0x")) {
|
|
650
|
+
const hex = input.slice(2);
|
|
651
|
+
if (hex.length % 2 !== 0) {
|
|
652
|
+
throw new Error(`Invalid hex input: odd number of characters`);
|
|
653
|
+
}
|
|
654
|
+
return hexToBytes2(hex);
|
|
655
|
+
}
|
|
656
|
+
return new TextEncoder().encode(input);
|
|
657
|
+
}
|
|
658
|
+
function toHex(bytes) {
|
|
659
|
+
return `0x${bytesToHex(bytes)}`;
|
|
660
|
+
}
|
|
661
|
+
function isValidAlgorithm(name) {
|
|
662
|
+
return name in ALGORITHMS;
|
|
663
|
+
}
|
|
664
|
+
function getAlgorithmNames() {
|
|
665
|
+
return Object.keys(ALGORITHMS);
|
|
666
|
+
}
|
|
667
|
+
var ALGORITHMS;
|
|
668
|
+
var init_hash = __esm(() => {
|
|
669
|
+
ALGORITHMS = {
|
|
670
|
+
blake2b256: {
|
|
671
|
+
compute: (data) => blake2b(data, { dkLen: 32 }),
|
|
672
|
+
outputLen: 32,
|
|
673
|
+
description: "BLAKE2b with 256-bit output"
|
|
674
|
+
},
|
|
675
|
+
blake2b128: {
|
|
676
|
+
compute: (data) => blake2b(data, { dkLen: 16 }),
|
|
677
|
+
outputLen: 16,
|
|
678
|
+
description: "BLAKE2b with 128-bit output"
|
|
679
|
+
},
|
|
680
|
+
keccak256: {
|
|
681
|
+
compute: (data) => keccak_256(data),
|
|
682
|
+
outputLen: 32,
|
|
683
|
+
description: "Keccak-256 (Ethereum-compatible)"
|
|
684
|
+
},
|
|
685
|
+
sha256: {
|
|
686
|
+
compute: (data) => sha256(data),
|
|
687
|
+
outputLen: 32,
|
|
688
|
+
description: "SHA-256"
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
// src/completions/complete.ts
|
|
694
|
+
var exports_complete = {};
|
|
695
|
+
__export(exports_complete, {
|
|
696
|
+
generateCompletions: () => generateCompletions
|
|
697
|
+
});
|
|
698
|
+
function matchCategory2(s) {
|
|
699
|
+
return CATEGORY_ALIASES2[s.toLowerCase()];
|
|
700
|
+
}
|
|
701
|
+
async function loadPallets(_config, chainName) {
|
|
702
|
+
const raw = await loadMetadata(chainName);
|
|
703
|
+
if (!raw)
|
|
704
|
+
return null;
|
|
705
|
+
const meta = parseMetadata(raw);
|
|
706
|
+
return listPallets(meta);
|
|
707
|
+
}
|
|
708
|
+
function filterPallets(pallets, category) {
|
|
709
|
+
switch (category) {
|
|
710
|
+
case "query":
|
|
711
|
+
return pallets.filter((p) => p.storage.length > 0);
|
|
712
|
+
case "tx":
|
|
713
|
+
return pallets.filter((p) => p.calls.length > 0);
|
|
714
|
+
case "const":
|
|
715
|
+
return pallets.filter((p) => p.constants.length > 0);
|
|
716
|
+
case "events":
|
|
717
|
+
return pallets.filter((p) => p.events.length > 0);
|
|
718
|
+
case "errors":
|
|
719
|
+
return pallets.filter((p) => p.errors.length > 0);
|
|
720
|
+
default:
|
|
721
|
+
return pallets;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
function getItemNames(pallet, category) {
|
|
725
|
+
switch (category) {
|
|
726
|
+
case "query":
|
|
727
|
+
return pallet.storage.map((s) => s.name);
|
|
728
|
+
case "tx":
|
|
729
|
+
return pallet.calls.map((c) => c.name);
|
|
730
|
+
case "const":
|
|
731
|
+
return pallet.constants.map((c) => c.name);
|
|
732
|
+
case "events":
|
|
733
|
+
return pallet.events.map((e) => e.name);
|
|
734
|
+
case "errors":
|
|
735
|
+
return pallet.errors.map((e) => e.name);
|
|
736
|
+
default:
|
|
737
|
+
return [];
|
|
738
|
+
}
|
|
327
739
|
}
|
|
328
|
-
function
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
throw new Error(`Environment variable "${secret.env}" is not set. Set it before signing.`);
|
|
740
|
+
function resolveChainFromArgs(precedingWords, _config) {
|
|
741
|
+
for (let i = 0;i < precedingWords.length - 1; i++) {
|
|
742
|
+
if (precedingWords[i] === "--chain") {
|
|
743
|
+
return precedingWords[i + 1];
|
|
333
744
|
}
|
|
334
|
-
return value;
|
|
335
745
|
}
|
|
336
|
-
return
|
|
746
|
+
return;
|
|
337
747
|
}
|
|
338
|
-
function
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
const { publicKey } = importAccount(value, path);
|
|
344
|
-
return publicKeyToHex(publicKey);
|
|
345
|
-
} catch {
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
748
|
+
function filterPrefix(candidates, prefix) {
|
|
749
|
+
if (!prefix)
|
|
750
|
+
return candidates;
|
|
751
|
+
const lower = prefix.toLowerCase();
|
|
752
|
+
return candidates.filter((c) => c.toLowerCase().startsWith(lower));
|
|
348
753
|
}
|
|
349
|
-
async function
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
754
|
+
async function generateCompletions(currentWord, precedingWords) {
|
|
755
|
+
const config = await loadConfig();
|
|
756
|
+
const knownChains = Object.keys(config.chains);
|
|
757
|
+
const prevWord = precedingWords[precedingWords.length - 1];
|
|
758
|
+
if (prevWord === "--chain") {
|
|
759
|
+
return filterPrefix(knownChains, currentWord);
|
|
760
|
+
}
|
|
761
|
+
if (prevWord === "--output") {
|
|
762
|
+
return filterPrefix(["pretty", "json"], currentWord);
|
|
763
|
+
}
|
|
764
|
+
if (prevWord === "--from") {
|
|
765
|
+
const accounts = await loadAccounts();
|
|
766
|
+
const names = [...DEV_NAMES, ...accounts.accounts.map((a) => a.name)];
|
|
767
|
+
return filterPrefix(names, currentWord);
|
|
768
|
+
}
|
|
769
|
+
if (currentWord.startsWith("--")) {
|
|
770
|
+
const activeCategory = detectCategory(precedingWords, knownChains);
|
|
771
|
+
const options = [...GLOBAL_OPTIONS];
|
|
772
|
+
if (activeCategory === "tx")
|
|
773
|
+
options.push(...TX_OPTIONS);
|
|
774
|
+
if (activeCategory === "query")
|
|
775
|
+
options.push(...QUERY_OPTIONS);
|
|
776
|
+
return filterPrefix(options, currentWord);
|
|
777
|
+
}
|
|
778
|
+
const firstArg = precedingWords.find((w) => !w.startsWith("-"));
|
|
779
|
+
if (firstArg === "chain") {
|
|
780
|
+
return filterPrefix(CHAIN_SUBCOMMANDS, currentWord);
|
|
781
|
+
}
|
|
782
|
+
if (firstArg === "account") {
|
|
783
|
+
return filterPrefix(ACCOUNT_SUBCOMMANDS, currentWord);
|
|
784
|
+
}
|
|
785
|
+
if (firstArg === "hash") {
|
|
786
|
+
return filterPrefix(getAlgorithmNames(), currentWord);
|
|
787
|
+
}
|
|
788
|
+
return completeDotpath(currentWord, config, knownChains, precedingWords);
|
|
789
|
+
}
|
|
790
|
+
function detectCategory(words, _knownChains) {
|
|
791
|
+
for (const w of words) {
|
|
792
|
+
if (w.startsWith("-"))
|
|
793
|
+
continue;
|
|
794
|
+
const parts = w.split(".");
|
|
795
|
+
for (const part of parts) {
|
|
796
|
+
const cat = matchCategory2(part);
|
|
797
|
+
if (cat)
|
|
798
|
+
return cat;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
async function completeDotpath(currentWord, config, knownChains, precedingWords) {
|
|
804
|
+
const endsWithDot = currentWord.endsWith(".");
|
|
805
|
+
const parts = currentWord.split(".");
|
|
806
|
+
const completeSegments = parts.slice(0, -1);
|
|
807
|
+
const partial = endsWithDot ? "" : parts[parts.length - 1] ?? "";
|
|
808
|
+
const numComplete = completeSegments.length;
|
|
809
|
+
if (numComplete === 0 && !endsWithDot) {
|
|
810
|
+
const candidates = [...CATEGORIES.map(String), ...knownChains, ...NAMED_COMMANDS];
|
|
811
|
+
return filterPrefix(candidates, partial);
|
|
812
|
+
}
|
|
813
|
+
const first = completeSegments[0] ?? "";
|
|
814
|
+
const firstIsCategory = matchCategory2(first) !== undefined;
|
|
815
|
+
const firstIsChain = knownChains.some((c) => c.toLowerCase() === first.toLowerCase());
|
|
816
|
+
const chainFromFlag = resolveChainFromArgs(precedingWords, config);
|
|
817
|
+
if (firstIsCategory) {
|
|
818
|
+
const category = matchCategory2(first);
|
|
819
|
+
if (numComplete === 1 && endsWithDot) {
|
|
820
|
+
const chainName = chainFromFlag ?? config.defaultChain;
|
|
821
|
+
const pallets = await loadPallets(config, chainName);
|
|
822
|
+
if (!pallets)
|
|
823
|
+
return [];
|
|
824
|
+
const filtered = filterPallets(pallets, category);
|
|
825
|
+
const candidates = filtered.map((p) => `${first}.${p.name}`);
|
|
826
|
+
return filterPrefix(candidates, currentWord.slice(0, -1));
|
|
827
|
+
}
|
|
828
|
+
if (numComplete === 1 && !endsWithDot) {
|
|
829
|
+
const chainName = chainFromFlag ?? config.defaultChain;
|
|
830
|
+
const pallets = await loadPallets(config, chainName);
|
|
831
|
+
if (!pallets)
|
|
832
|
+
return [];
|
|
833
|
+
const filtered = filterPallets(pallets, category);
|
|
834
|
+
const candidates = filtered.map((p) => `${first}.${p.name}`);
|
|
835
|
+
return filterPrefix(candidates, currentWord);
|
|
836
|
+
}
|
|
837
|
+
if (numComplete === 2) {
|
|
838
|
+
const palletName2 = completeSegments[1];
|
|
839
|
+
const chainName = chainFromFlag ?? config.defaultChain;
|
|
840
|
+
const pallets = await loadPallets(config, chainName);
|
|
841
|
+
if (!pallets)
|
|
842
|
+
return [];
|
|
843
|
+
const pallet = pallets.find((p) => p.name.toLowerCase() === palletName2.toLowerCase());
|
|
844
|
+
if (!pallet)
|
|
845
|
+
return [];
|
|
846
|
+
const items = getItemNames(pallet, category);
|
|
847
|
+
const candidates = items.map((i) => `${first}.${palletName2}.${i}`);
|
|
848
|
+
return filterPrefix(candidates, endsWithDot ? currentWord.slice(0, -1) : currentWord);
|
|
849
|
+
}
|
|
850
|
+
return [];
|
|
359
851
|
}
|
|
360
|
-
if (
|
|
361
|
-
|
|
852
|
+
if (firstIsChain) {
|
|
853
|
+
const chainName = first;
|
|
854
|
+
if (numComplete === 1 && endsWithDot) {
|
|
855
|
+
const candidates = CATEGORIES.map((c) => `${first}.${c}`);
|
|
856
|
+
return filterPrefix(candidates, currentWord.slice(0, -1));
|
|
857
|
+
}
|
|
858
|
+
if (numComplete === 1 && !endsWithDot) {
|
|
859
|
+
const candidates = CATEGORIES.map((c) => `${first}.${c}`);
|
|
860
|
+
return filterPrefix(candidates, currentWord);
|
|
861
|
+
}
|
|
862
|
+
if (numComplete === 2) {
|
|
863
|
+
const category = matchCategory2(completeSegments[1]);
|
|
864
|
+
if (!category)
|
|
865
|
+
return [];
|
|
866
|
+
const pallets = await loadPallets(config, chainName);
|
|
867
|
+
if (!pallets)
|
|
868
|
+
return [];
|
|
869
|
+
const filtered = filterPallets(pallets, category);
|
|
870
|
+
const prefix = `${first}.${completeSegments[1]}`;
|
|
871
|
+
const candidates = filtered.map((p) => `${prefix}.${p.name}`);
|
|
872
|
+
return filterPrefix(candidates, endsWithDot ? currentWord.slice(0, -1) : currentWord);
|
|
873
|
+
}
|
|
874
|
+
if (numComplete === 3) {
|
|
875
|
+
const category = matchCategory2(completeSegments[1]);
|
|
876
|
+
if (!category)
|
|
877
|
+
return [];
|
|
878
|
+
const palletName2 = completeSegments[2];
|
|
879
|
+
const pallets = await loadPallets(config, chainName);
|
|
880
|
+
if (!pallets)
|
|
881
|
+
return [];
|
|
882
|
+
const pallet = pallets.find((p) => p.name.toLowerCase() === palletName2.toLowerCase());
|
|
883
|
+
if (!pallet)
|
|
884
|
+
return [];
|
|
885
|
+
const items = getItemNames(pallet, category);
|
|
886
|
+
const prefix = `${first}.${completeSegments[1]}.${palletName2}`;
|
|
887
|
+
const candidates = items.map((i) => `${prefix}.${i}`);
|
|
888
|
+
return filterPrefix(candidates, endsWithDot ? currentWord.slice(0, -1) : currentWord);
|
|
889
|
+
}
|
|
890
|
+
return [];
|
|
362
891
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
892
|
+
return [];
|
|
893
|
+
}
|
|
894
|
+
var CATEGORIES, CATEGORY_ALIASES2, NAMED_COMMANDS, CHAIN_SUBCOMMANDS, ACCOUNT_SUBCOMMANDS, GLOBAL_OPTIONS, TX_OPTIONS, QUERY_OPTIONS;
|
|
895
|
+
var init_complete = __esm(() => {
|
|
896
|
+
init_accounts_store();
|
|
897
|
+
init_store();
|
|
898
|
+
init_accounts();
|
|
899
|
+
init_hash();
|
|
900
|
+
init_metadata();
|
|
901
|
+
CATEGORIES = ["query", "tx", "const", "events", "errors"];
|
|
902
|
+
CATEGORY_ALIASES2 = {
|
|
903
|
+
query: "query",
|
|
904
|
+
tx: "tx",
|
|
905
|
+
const: "const",
|
|
906
|
+
consts: "const",
|
|
907
|
+
constants: "const",
|
|
908
|
+
events: "events",
|
|
909
|
+
event: "events",
|
|
910
|
+
errors: "errors",
|
|
911
|
+
error: "errors"
|
|
912
|
+
};
|
|
913
|
+
NAMED_COMMANDS = ["chain", "account", "inspect", "hash", "completions"];
|
|
914
|
+
CHAIN_SUBCOMMANDS = ["add", "remove", "update", "list", "default"];
|
|
915
|
+
ACCOUNT_SUBCOMMANDS = [
|
|
916
|
+
"add",
|
|
917
|
+
"create",
|
|
918
|
+
"new",
|
|
919
|
+
"import",
|
|
920
|
+
"derive",
|
|
921
|
+
"list",
|
|
922
|
+
"remove",
|
|
923
|
+
"delete",
|
|
924
|
+
"inspect"
|
|
925
|
+
];
|
|
926
|
+
GLOBAL_OPTIONS = ["--chain", "--rpc", "--light-client", "--output", "--help", "--version"];
|
|
927
|
+
TX_OPTIONS = ["--from", "--dry-run", "--encode", "--ext"];
|
|
928
|
+
QUERY_OPTIONS = ["--limit"];
|
|
929
|
+
});
|
|
930
|
+
|
|
931
|
+
// src/cli.ts
|
|
932
|
+
import cac from "cac";
|
|
933
|
+
// package.json
|
|
934
|
+
var version = "1.3.0";
|
|
935
|
+
|
|
936
|
+
// src/commands/account.ts
|
|
937
|
+
init_accounts_store();
|
|
938
|
+
init_accounts();
|
|
368
939
|
|
|
369
940
|
// src/core/output.ts
|
|
370
941
|
import { Binary } from "polkadot-api";
|
|
@@ -888,35 +1459,17 @@ async function accountInspect(input, opts) {
|
|
|
888
1459
|
}
|
|
889
1460
|
}
|
|
890
1461
|
|
|
1462
|
+
// src/commands/chain.ts
|
|
1463
|
+
init_store();
|
|
1464
|
+
init_types();
|
|
1465
|
+
|
|
891
1466
|
// src/core/client.ts
|
|
1467
|
+
init_store();
|
|
1468
|
+
init_errors();
|
|
892
1469
|
import { createClient } from "polkadot-api";
|
|
893
1470
|
import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat";
|
|
894
1471
|
import { getWsProvider } from "polkadot-api/ws-provider";
|
|
895
1472
|
import { WebSocket } from "ws";
|
|
896
|
-
|
|
897
|
-
// src/utils/errors.ts
|
|
898
|
-
class CliError extends Error {
|
|
899
|
-
constructor(message) {
|
|
900
|
-
super(message);
|
|
901
|
-
this.name = "CliError";
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
class ConnectionError extends CliError {
|
|
906
|
-
constructor(message) {
|
|
907
|
-
super(message);
|
|
908
|
-
this.name = "ConnectionError";
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
class MetadataError extends CliError {
|
|
913
|
-
constructor(message) {
|
|
914
|
-
super(message);
|
|
915
|
-
this.name = "MetadataError";
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
// src/core/client.ts
|
|
920
1473
|
var KNOWN_CHAIN_SPECS = {
|
|
921
1474
|
polkadot: { spec: "polkadot-api/chains/polkadot" },
|
|
922
1475
|
kusama: { spec: "polkadot-api/chains/ksmcc3" },
|
|
@@ -952,270 +1505,52 @@ async function createChainClient(chainName, chainConfig, rpcOverride) {
|
|
|
952
1505
|
const rpc = rpcOverride ?? chainConfig.rpc;
|
|
953
1506
|
if (!rpc) {
|
|
954
1507
|
restoreConsole();
|
|
955
|
-
throw new ConnectionError(`No RPC endpoint configured for chain "${chainName}". Use --rpc or configure one with: dot chain add ${chainName} --rpc <url>`);
|
|
956
|
-
}
|
|
957
|
-
provider = withPolkadotSdkCompat(getWsProvider(rpc, {
|
|
958
|
-
timeout: 1e4,
|
|
959
|
-
websocketClass: WebSocket
|
|
960
|
-
}));
|
|
961
|
-
}
|
|
962
|
-
const client = createClient(provider, {
|
|
963
|
-
getMetadata: async () => loadMetadata(chainName),
|
|
964
|
-
setMetadata: async (_codeHash, metadata) => {
|
|
965
|
-
await saveMetadata(chainName, metadata);
|
|
966
|
-
}
|
|
967
|
-
});
|
|
968
|
-
return {
|
|
969
|
-
client,
|
|
970
|
-
destroy: () => {
|
|
971
|
-
client.destroy();
|
|
972
|
-
restoreConsole();
|
|
973
|
-
}
|
|
974
|
-
};
|
|
975
|
-
}
|
|
976
|
-
async function createSmoldotProvider(chainName) {
|
|
977
|
-
const { start } = await import("polkadot-api/smoldot");
|
|
978
|
-
const { getSmProvider } = await import("polkadot-api/sm-provider");
|
|
979
|
-
const entry = KNOWN_CHAIN_SPECS[chainName];
|
|
980
|
-
if (!entry) {
|
|
981
|
-
throw new ConnectionError(`Light client is only supported for known chains: ${Object.keys(KNOWN_CHAIN_SPECS).join(", ")}. Use --rpc to connect to "${chainName}" instead.`);
|
|
982
|
-
}
|
|
983
|
-
const { chainSpec } = await import(entry.spec);
|
|
984
|
-
const smoldot = start();
|
|
985
|
-
if (entry.relay) {
|
|
986
|
-
const relayEntry = KNOWN_CHAIN_SPECS[entry.relay];
|
|
987
|
-
if (!relayEntry) {
|
|
988
|
-
throw new ConnectionError(`Relay chain "${entry.relay}" not found in known chain specs.`);
|
|
989
|
-
}
|
|
990
|
-
const { chainSpec: relaySpec } = await import(relayEntry.spec);
|
|
991
|
-
const relayChain = await smoldot.addChain({ chainSpec: relaySpec, disableJsonRpc: true });
|
|
992
|
-
const chain2 = await smoldot.addChain({ chainSpec, potentialRelayChains: [relayChain] });
|
|
993
|
-
return getSmProvider(chain2);
|
|
994
|
-
}
|
|
995
|
-
const chain = await smoldot.addChain({ chainSpec });
|
|
996
|
-
return getSmProvider(chain);
|
|
997
|
-
}
|
|
998
|
-
|
|
999
|
-
// src/core/metadata.ts
|
|
1000
|
-
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders";
|
|
1001
|
-
import { decAnyMetadata, unifyMetadata } from "@polkadot-api/substrate-bindings";
|
|
1002
|
-
var METADATA_TIMEOUT_MS = 15000;
|
|
1003
|
-
function parseMetadata(raw) {
|
|
1004
|
-
const decoded = decAnyMetadata(raw);
|
|
1005
|
-
const unified = unifyMetadata(decoded);
|
|
1006
|
-
const lookup = getLookupFn(unified);
|
|
1007
|
-
const builder = getDynamicBuilder(lookup);
|
|
1008
|
-
return { unified, lookup, builder };
|
|
1009
|
-
}
|
|
1010
|
-
async function fetchMetadataFromChain(clientHandle, chainName) {
|
|
1011
|
-
const { client } = clientHandle;
|
|
1012
|
-
try {
|
|
1013
|
-
const hex = await Promise.race([
|
|
1014
|
-
client._request("state_getMetadata", []),
|
|
1015
|
-
new Promise((_, reject) => setTimeout(() => reject(new ConnectionError(`Timed out fetching metadata for "${chainName}" after ${METADATA_TIMEOUT_MS / 1000}s. ` + "Check that the RPC endpoint is correct and reachable.")), METADATA_TIMEOUT_MS))
|
|
1016
|
-
]);
|
|
1017
|
-
const bytes = hexToBytes(hex);
|
|
1018
|
-
await saveMetadata(chainName, bytes);
|
|
1019
|
-
return bytes;
|
|
1020
|
-
} catch (err) {
|
|
1021
|
-
if (err instanceof ConnectionError)
|
|
1022
|
-
throw err;
|
|
1023
|
-
throw new ConnectionError(`Failed to fetch metadata for "${chainName}": ${err instanceof Error ? err.message : err}. ` + "Check that the RPC endpoint is correct and reachable.");
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
async function getOrFetchMetadata(chainName, clientHandle) {
|
|
1027
|
-
let raw = await loadMetadata(chainName);
|
|
1028
|
-
if (!raw) {
|
|
1029
|
-
if (!clientHandle) {
|
|
1030
|
-
throw new MetadataError(`No cached metadata for chain "${chainName}". Run a command that connects to the chain first, ` + `e.g.: dot chain add ${chainName} --rpc <url>`);
|
|
1031
|
-
}
|
|
1032
|
-
raw = await fetchMetadataFromChain(clientHandle, chainName);
|
|
1033
|
-
}
|
|
1034
|
-
return parseMetadata(raw);
|
|
1035
|
-
}
|
|
1036
|
-
function listPallets(meta) {
|
|
1037
|
-
return meta.unified.pallets.map((p) => ({
|
|
1038
|
-
name: p.name,
|
|
1039
|
-
index: p.index,
|
|
1040
|
-
docs: p.docs ?? [],
|
|
1041
|
-
storage: (p.storage?.items ?? []).map((s) => ({
|
|
1042
|
-
name: s.name,
|
|
1043
|
-
docs: s.docs ?? [],
|
|
1044
|
-
type: s.type.tag,
|
|
1045
|
-
keyTypeId: s.type.tag === "map" ? s.type.value.key : null,
|
|
1046
|
-
valueTypeId: s.type.tag === "plain" ? s.type.value : s.type.value.value
|
|
1047
|
-
})),
|
|
1048
|
-
constants: (p.constants ?? []).map((c) => ({
|
|
1049
|
-
name: c.name,
|
|
1050
|
-
docs: c.docs ?? [],
|
|
1051
|
-
typeId: c.type
|
|
1052
|
-
})),
|
|
1053
|
-
calls: extractEnumVariants(meta, p.calls),
|
|
1054
|
-
events: extractEnumVariants(meta, p.events),
|
|
1055
|
-
errors: extractEnumVariants(meta, p.errors).map(({ name, docs }) => ({ name, docs }))
|
|
1056
|
-
}));
|
|
1057
|
-
}
|
|
1058
|
-
function extractEnumVariants(meta, ref) {
|
|
1059
|
-
if (!ref)
|
|
1060
|
-
return [];
|
|
1061
|
-
try {
|
|
1062
|
-
const entry = meta.lookup(ref.type);
|
|
1063
|
-
if (entry.type !== "enum")
|
|
1064
|
-
return [];
|
|
1065
|
-
return Object.entries(entry.value).map(([name, variant]) => ({
|
|
1066
|
-
name,
|
|
1067
|
-
docs: entry.innerDocs?.[name] ?? [],
|
|
1068
|
-
typeId: resolveVariantTypeId(variant)
|
|
1069
|
-
}));
|
|
1070
|
-
} catch {
|
|
1071
|
-
return [];
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
function resolveVariantTypeId(variant) {
|
|
1075
|
-
if (variant.type === "lookupEntry")
|
|
1076
|
-
return variant.value?.id ?? null;
|
|
1077
|
-
if (variant.type === "struct")
|
|
1078
|
-
return null;
|
|
1079
|
-
if (variant.type === "void" || variant.type === "empty")
|
|
1080
|
-
return null;
|
|
1081
|
-
return null;
|
|
1082
|
-
}
|
|
1083
|
-
function findPallet(meta, palletName) {
|
|
1084
|
-
const pallets = listPallets(meta);
|
|
1085
|
-
return pallets.find((p) => p.name.toLowerCase() === palletName.toLowerCase());
|
|
1086
|
-
}
|
|
1087
|
-
function getSignedExtensions(meta) {
|
|
1088
|
-
const byVersion = meta.unified.extrinsic.signedExtensions;
|
|
1089
|
-
const versionKeys = Object.keys(byVersion);
|
|
1090
|
-
if (versionKeys.length === 0)
|
|
1091
|
-
return [];
|
|
1092
|
-
return byVersion[Number(versionKeys[0])] ?? [];
|
|
1093
|
-
}
|
|
1094
|
-
function getPalletNames(meta) {
|
|
1095
|
-
return meta.unified.pallets.map((p) => p.name);
|
|
1096
|
-
}
|
|
1097
|
-
function describeType(lookup, typeId) {
|
|
1098
|
-
try {
|
|
1099
|
-
const entry = lookup(typeId);
|
|
1100
|
-
return formatLookupEntry(entry);
|
|
1101
|
-
} catch {
|
|
1102
|
-
return `type(${typeId})`;
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
function formatLookupEntry(entry) {
|
|
1106
|
-
switch (entry.type) {
|
|
1107
|
-
case "primitive":
|
|
1108
|
-
return entry.value;
|
|
1109
|
-
case "compact":
|
|
1110
|
-
return `Compact<${formatLookupEntry(entry.isBig ? { type: "primitive", value: "u128" } : { type: "primitive", value: "u64" })}>`;
|
|
1111
|
-
case "AccountId32":
|
|
1112
|
-
return "AccountId32";
|
|
1113
|
-
case "bitSequence":
|
|
1114
|
-
return "BitSequence";
|
|
1115
|
-
case "sequence":
|
|
1116
|
-
return `Vec<${formatLookupEntry(entry.value)}>`;
|
|
1117
|
-
case "array":
|
|
1118
|
-
return `[${formatLookupEntry(entry.value)}; ${entry.len}]`;
|
|
1119
|
-
case "tuple":
|
|
1120
|
-
return `(${entry.value.map(formatLookupEntry).join(", ")})`;
|
|
1121
|
-
case "struct":
|
|
1122
|
-
return `{ ${Object.entries(entry.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ")} }`;
|
|
1123
|
-
case "option":
|
|
1124
|
-
return `Option<${formatLookupEntry(entry.value)}>`;
|
|
1125
|
-
case "result":
|
|
1126
|
-
return `Result<${formatLookupEntry(entry.value.ok)}, ${formatLookupEntry(entry.value.ko)}>`;
|
|
1127
|
-
case "enum": {
|
|
1128
|
-
const variants = Object.keys(entry.value);
|
|
1129
|
-
if (variants.length <= 4)
|
|
1130
|
-
return variants.join(" | ");
|
|
1131
|
-
return `enum(${variants.length} variants)`;
|
|
1508
|
+
throw new ConnectionError(`No RPC endpoint configured for chain "${chainName}". Use --rpc or configure one with: dot chain add ${chainName} --rpc <url>`);
|
|
1132
1509
|
}
|
|
1133
|
-
|
|
1134
|
-
|
|
1510
|
+
provider = withPolkadotSdkCompat(getWsProvider(rpc, {
|
|
1511
|
+
timeout: 1e4,
|
|
1512
|
+
websocketClass: WebSocket
|
|
1513
|
+
}));
|
|
1135
1514
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
if (!palletMeta?.calls)
|
|
1141
|
-
return "";
|
|
1142
|
-
const callsEntry = meta.lookup(palletMeta.calls.type);
|
|
1143
|
-
if (callsEntry.type !== "enum")
|
|
1144
|
-
return "";
|
|
1145
|
-
const variant = callsEntry.value[callName];
|
|
1146
|
-
if (!variant)
|
|
1147
|
-
return "";
|
|
1148
|
-
if (variant.type === "void")
|
|
1149
|
-
return "()";
|
|
1150
|
-
if (variant.type === "struct") {
|
|
1151
|
-
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1152
|
-
return `(${fields})`;
|
|
1153
|
-
}
|
|
1154
|
-
if (variant.type === "lookupEntry") {
|
|
1155
|
-
const inner = variant.value;
|
|
1156
|
-
if (inner.type === "void")
|
|
1157
|
-
return "()";
|
|
1158
|
-
if (inner.type === "struct") {
|
|
1159
|
-
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1160
|
-
return `(${fields})`;
|
|
1161
|
-
}
|
|
1162
|
-
return `(${formatLookupEntry(inner)})`;
|
|
1515
|
+
const client = createClient(provider, {
|
|
1516
|
+
getMetadata: async () => loadMetadata(chainName),
|
|
1517
|
+
setMetadata: async (_codeHash, metadata) => {
|
|
1518
|
+
await saveMetadata(chainName, metadata);
|
|
1163
1519
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1520
|
+
});
|
|
1521
|
+
return {
|
|
1522
|
+
client,
|
|
1523
|
+
destroy: () => {
|
|
1524
|
+
client.destroy();
|
|
1525
|
+
restoreConsole();
|
|
1167
1526
|
}
|
|
1168
|
-
|
|
1169
|
-
} catch {
|
|
1170
|
-
return "";
|
|
1171
|
-
}
|
|
1527
|
+
};
|
|
1172
1528
|
}
|
|
1173
|
-
function
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
if (eventsEntry.type !== "enum")
|
|
1180
|
-
return "";
|
|
1181
|
-
const variant = eventsEntry.value[eventName];
|
|
1182
|
-
if (!variant)
|
|
1183
|
-
return "";
|
|
1184
|
-
if (variant.type === "void")
|
|
1185
|
-
return "()";
|
|
1186
|
-
if (variant.type === "struct") {
|
|
1187
|
-
const fields = Object.entries(variant.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1188
|
-
return `(${fields})`;
|
|
1189
|
-
}
|
|
1190
|
-
if (variant.type === "lookupEntry") {
|
|
1191
|
-
const inner = variant.value;
|
|
1192
|
-
if (inner.type === "void")
|
|
1193
|
-
return "()";
|
|
1194
|
-
if (inner.type === "struct") {
|
|
1195
|
-
const fields = Object.entries(inner.value).map(([k, v]) => `${k}: ${formatLookupEntry(v)}`).join(", ");
|
|
1196
|
-
return `(${fields})`;
|
|
1197
|
-
}
|
|
1198
|
-
return `(${formatLookupEntry(inner)})`;
|
|
1199
|
-
}
|
|
1200
|
-
if (variant.type === "tuple") {
|
|
1201
|
-
const types = variant.value.map(formatLookupEntry).join(", ");
|
|
1202
|
-
return `(${types})`;
|
|
1203
|
-
}
|
|
1204
|
-
return "";
|
|
1205
|
-
} catch {
|
|
1206
|
-
return "";
|
|
1529
|
+
async function createSmoldotProvider(chainName) {
|
|
1530
|
+
const { start } = await import("polkadot-api/smoldot");
|
|
1531
|
+
const { getSmProvider } = await import("polkadot-api/sm-provider");
|
|
1532
|
+
const entry = KNOWN_CHAIN_SPECS[chainName];
|
|
1533
|
+
if (!entry) {
|
|
1534
|
+
throw new ConnectionError(`Light client is only supported for known chains: ${Object.keys(KNOWN_CHAIN_SPECS).join(", ")}. Use --rpc to connect to "${chainName}" instead.`);
|
|
1207
1535
|
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1536
|
+
const { chainSpec } = await import(entry.spec);
|
|
1537
|
+
const smoldot = start();
|
|
1538
|
+
if (entry.relay) {
|
|
1539
|
+
const relayEntry = KNOWN_CHAIN_SPECS[entry.relay];
|
|
1540
|
+
if (!relayEntry) {
|
|
1541
|
+
throw new ConnectionError(`Relay chain "${entry.relay}" not found in known chain specs.`);
|
|
1542
|
+
}
|
|
1543
|
+
const { chainSpec: relaySpec } = await import(relayEntry.spec);
|
|
1544
|
+
const relayChain = await smoldot.addChain({ chainSpec: relaySpec, disableJsonRpc: true });
|
|
1545
|
+
const chain2 = await smoldot.addChain({ chainSpec, potentialRelayChains: [relayChain] });
|
|
1546
|
+
return getSmProvider(chain2);
|
|
1214
1547
|
}
|
|
1215
|
-
|
|
1548
|
+
const chain = await smoldot.addChain({ chainSpec });
|
|
1549
|
+
return getSmProvider(chain);
|
|
1216
1550
|
}
|
|
1217
1551
|
|
|
1218
1552
|
// src/commands/chain.ts
|
|
1553
|
+
init_metadata();
|
|
1219
1554
|
var CHAIN_HELP = `
|
|
1220
1555
|
${BOLD}Usage:${RESET}
|
|
1221
1556
|
$ dot chain add <name> --rpc <url> Add a chain via WebSocket RPC
|
|
@@ -1363,6 +1698,93 @@ async function chainDefault(name) {
|
|
|
1363
1698
|
console.log(`Default chain set to "${resolved}".`);
|
|
1364
1699
|
}
|
|
1365
1700
|
|
|
1701
|
+
// src/commands/completions.ts
|
|
1702
|
+
var ZSH_SCRIPT = `_dot_completions() {
|
|
1703
|
+
local -a completions
|
|
1704
|
+
local current_word="\${words[CURRENT]}"
|
|
1705
|
+
local preceding=("\${words[@]:1:CURRENT-2}")
|
|
1706
|
+
|
|
1707
|
+
# Build args: -- <current_word> <preceding_words...>
|
|
1708
|
+
local args=("__complete" "--" "\${current_word}")
|
|
1709
|
+
args+=("\${preceding[@]}")
|
|
1710
|
+
|
|
1711
|
+
local output
|
|
1712
|
+
output="$(dot "\${args[@]}" 2>/dev/null)"
|
|
1713
|
+
[[ -z "$output" ]] && return
|
|
1714
|
+
|
|
1715
|
+
completions=("\${(@f)output}")
|
|
1716
|
+
|
|
1717
|
+
compadd -S '' -- "\${completions[@]}"
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
compdef _dot_completions dot`;
|
|
1721
|
+
var BASH_SCRIPT = `_dot_completions() {
|
|
1722
|
+
local current_word="\${COMP_WORDS[COMP_CWORD]}"
|
|
1723
|
+
local preceding=("\${COMP_WORDS[@]:1:COMP_CWORD-1}")
|
|
1724
|
+
|
|
1725
|
+
# Build args: -- <current_word> <preceding_words...>
|
|
1726
|
+
local args=("__complete" "--" "\${current_word}")
|
|
1727
|
+
args+=("\${preceding[@]}")
|
|
1728
|
+
|
|
1729
|
+
local IFS=$'\\n'
|
|
1730
|
+
local completions
|
|
1731
|
+
completions=($(dot "\${args[@]}" 2>/dev/null))
|
|
1732
|
+
|
|
1733
|
+
[[ \${#completions[@]} -eq 0 ]] && return
|
|
1734
|
+
|
|
1735
|
+
compopt -o nospace
|
|
1736
|
+
COMPREPLY=("\${completions[@]}")
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
complete -F _dot_completions dot`;
|
|
1740
|
+
var FISH_SCRIPT = `function __dot_complete
|
|
1741
|
+
set -l tokens (commandline -opc)
|
|
1742
|
+
set -l current (commandline -ct)
|
|
1743
|
+
|
|
1744
|
+
set -l args "__complete" "--" "$current"
|
|
1745
|
+
for t in $tokens[2..-1]
|
|
1746
|
+
set -a args "$t"
|
|
1747
|
+
end
|
|
1748
|
+
|
|
1749
|
+
dot $args 2>/dev/null
|
|
1750
|
+
end
|
|
1751
|
+
|
|
1752
|
+
complete -c dot -f -a '(__dot_complete)'`;
|
|
1753
|
+
var SETUP_INSTRUCTIONS = {
|
|
1754
|
+
zsh: `# Add this to your ~/.zshrc:
|
|
1755
|
+
# eval "$(dot completions zsh)"
|
|
1756
|
+
# Then restart your shell or run: source ~/.zshrc`,
|
|
1757
|
+
bash: `# Add this to your ~/.bashrc:
|
|
1758
|
+
# eval "$(dot completions bash)"
|
|
1759
|
+
# Then restart your shell or run: source ~/.bashrc`,
|
|
1760
|
+
fish: `# Save this to ~/.config/fish/completions/dot.fish:
|
|
1761
|
+
# dot completions fish > ~/.config/fish/completions/dot.fish`
|
|
1762
|
+
};
|
|
1763
|
+
var SCRIPTS = {
|
|
1764
|
+
zsh: ZSH_SCRIPT,
|
|
1765
|
+
bash: BASH_SCRIPT,
|
|
1766
|
+
fish: FISH_SCRIPT
|
|
1767
|
+
};
|
|
1768
|
+
function registerCompletionsCommand(cli) {
|
|
1769
|
+
cli.command("completions <shell>", "Generate shell completion script (zsh, bash, fish)").action((shell) => {
|
|
1770
|
+
const script = SCRIPTS[shell];
|
|
1771
|
+
if (!script) {
|
|
1772
|
+
console.error(`Unsupported shell "${shell}". Supported: ${Object.keys(SCRIPTS).join(", ")}`);
|
|
1773
|
+
process.exit(1);
|
|
1774
|
+
}
|
|
1775
|
+
const instructions = SETUP_INSTRUCTIONS[shell];
|
|
1776
|
+
if (instructions) {
|
|
1777
|
+
process.stderr.write(`${instructions}
|
|
1778
|
+
`);
|
|
1779
|
+
}
|
|
1780
|
+
console.log(script);
|
|
1781
|
+
});
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// src/commands/const.ts
|
|
1785
|
+
init_store();
|
|
1786
|
+
init_metadata();
|
|
1787
|
+
|
|
1366
1788
|
// src/utils/fuzzy-match.ts
|
|
1367
1789
|
function levenshtein(a, b) {
|
|
1368
1790
|
const la = a.length;
|
|
@@ -1400,6 +1822,8 @@ function suggestMessage(kind, input, candidates) {
|
|
|
1400
1822
|
}
|
|
1401
1823
|
|
|
1402
1824
|
// src/commands/focused-inspect.ts
|
|
1825
|
+
init_store();
|
|
1826
|
+
init_metadata();
|
|
1403
1827
|
async function loadMeta(chainName, chainConfig, rpcOverride) {
|
|
1404
1828
|
try {
|
|
1405
1829
|
return await getOrFetchMetadata(chainName);
|
|
@@ -1842,6 +2266,8 @@ async function handleConst(target, opts) {
|
|
|
1842
2266
|
}
|
|
1843
2267
|
|
|
1844
2268
|
// src/commands/focused-inspect.ts
|
|
2269
|
+
init_store();
|
|
2270
|
+
init_metadata();
|
|
1845
2271
|
async function loadMeta2(chainName, chainConfig, rpcOverride) {
|
|
1846
2272
|
try {
|
|
1847
2273
|
return await getOrFetchMetadata(chainName);
|
|
@@ -2217,61 +2643,9 @@ async function showItemHelp2(category, target, opts) {
|
|
|
2217
2643
|
}
|
|
2218
2644
|
}
|
|
2219
2645
|
|
|
2220
|
-
// src/core/hash.ts
|
|
2221
|
-
import { blake2b } from "@noble/hashes/blake2.js";
|
|
2222
|
-
import { sha256 } from "@noble/hashes/sha2.js";
|
|
2223
|
-
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
2224
|
-
import { bytesToHex, hexToBytes as hexToBytes2 } from "@noble/hashes/utils.js";
|
|
2225
|
-
var ALGORITHMS = {
|
|
2226
|
-
blake2b256: {
|
|
2227
|
-
compute: (data) => blake2b(data, { dkLen: 32 }),
|
|
2228
|
-
outputLen: 32,
|
|
2229
|
-
description: "BLAKE2b with 256-bit output"
|
|
2230
|
-
},
|
|
2231
|
-
blake2b128: {
|
|
2232
|
-
compute: (data) => blake2b(data, { dkLen: 16 }),
|
|
2233
|
-
outputLen: 16,
|
|
2234
|
-
description: "BLAKE2b with 128-bit output"
|
|
2235
|
-
},
|
|
2236
|
-
keccak256: {
|
|
2237
|
-
compute: (data) => keccak_256(data),
|
|
2238
|
-
outputLen: 32,
|
|
2239
|
-
description: "Keccak-256 (Ethereum-compatible)"
|
|
2240
|
-
},
|
|
2241
|
-
sha256: {
|
|
2242
|
-
compute: (data) => sha256(data),
|
|
2243
|
-
outputLen: 32,
|
|
2244
|
-
description: "SHA-256"
|
|
2245
|
-
}
|
|
2246
|
-
};
|
|
2247
|
-
function computeHash(algorithm, data) {
|
|
2248
|
-
const algo = ALGORITHMS[algorithm];
|
|
2249
|
-
if (!algo) {
|
|
2250
|
-
throw new Error(`Unknown algorithm: ${algorithm}`);
|
|
2251
|
-
}
|
|
2252
|
-
return algo.compute(data);
|
|
2253
|
-
}
|
|
2254
|
-
function parseInputData(input) {
|
|
2255
|
-
if (input.startsWith("0x")) {
|
|
2256
|
-
const hex = input.slice(2);
|
|
2257
|
-
if (hex.length % 2 !== 0) {
|
|
2258
|
-
throw new Error(`Invalid hex input: odd number of characters`);
|
|
2259
|
-
}
|
|
2260
|
-
return hexToBytes2(hex);
|
|
2261
|
-
}
|
|
2262
|
-
return new TextEncoder().encode(input);
|
|
2263
|
-
}
|
|
2264
|
-
function toHex(bytes) {
|
|
2265
|
-
return `0x${bytesToHex(bytes)}`;
|
|
2266
|
-
}
|
|
2267
|
-
function isValidAlgorithm(name) {
|
|
2268
|
-
return name in ALGORITHMS;
|
|
2269
|
-
}
|
|
2270
|
-
function getAlgorithmNames() {
|
|
2271
|
-
return Object.keys(ALGORITHMS);
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
2646
|
// src/commands/hash.ts
|
|
2647
|
+
init_hash();
|
|
2648
|
+
init_errors();
|
|
2275
2649
|
async function resolveInput(data, opts) {
|
|
2276
2650
|
const sources = [data !== undefined, !!opts.file, !!opts.stdin].filter(Boolean).length;
|
|
2277
2651
|
if (sources > 1) {
|
|
@@ -2348,6 +2722,10 @@ function registerHashCommand(cli) {
|
|
|
2348
2722
|
});
|
|
2349
2723
|
}
|
|
2350
2724
|
|
|
2725
|
+
// src/commands/inspect.ts
|
|
2726
|
+
init_store();
|
|
2727
|
+
init_metadata();
|
|
2728
|
+
|
|
2351
2729
|
// src/utils/parse-target.ts
|
|
2352
2730
|
function parseTarget(input, options) {
|
|
2353
2731
|
const parts = input.split(".");
|
|
@@ -2598,6 +2976,10 @@ function registerInspectCommand(cli) {
|
|
|
2598
2976
|
});
|
|
2599
2977
|
}
|
|
2600
2978
|
|
|
2979
|
+
// src/commands/query.ts
|
|
2980
|
+
init_store();
|
|
2981
|
+
init_metadata();
|
|
2982
|
+
|
|
2601
2983
|
// src/utils/parse-value.ts
|
|
2602
2984
|
function parseValue(arg) {
|
|
2603
2985
|
if (/^\d+$/.test(arg))
|
|
@@ -2619,6 +3001,9 @@ function parseValue(arg) {
|
|
|
2619
3001
|
}
|
|
2620
3002
|
|
|
2621
3003
|
// src/commands/tx.ts
|
|
3004
|
+
init_store();
|
|
3005
|
+
init_types();
|
|
3006
|
+
init_accounts();
|
|
2622
3007
|
import { getViewBuilder } from "@polkadot-api/view-builder";
|
|
2623
3008
|
import { Binary as Binary2 } from "polkadot-api";
|
|
2624
3009
|
|
|
@@ -2626,7 +3011,12 @@ import { Binary as Binary2 } from "polkadot-api";
|
|
|
2626
3011
|
var pjsAppsLink = (rpc, hash) => `https://polkadot.js.org/apps/?rpc=${encodeURIComponent(rpc)}#/explorer/query/${hash}`;
|
|
2627
3012
|
var papiLink = (rpc, hash) => `https://dev.papi.how/explorer/${hash}#networkId=custom&endpoint=${encodeURIComponent(rpc)}`;
|
|
2628
3013
|
|
|
3014
|
+
// src/commands/tx.ts
|
|
3015
|
+
init_metadata();
|
|
3016
|
+
|
|
2629
3017
|
// src/core/resolve-address.ts
|
|
3018
|
+
init_accounts_store();
|
|
3019
|
+
init_accounts();
|
|
2630
3020
|
async function resolveAccountAddress(input) {
|
|
2631
3021
|
if (isDevAccount(input)) {
|
|
2632
3022
|
return getDevAddress(input);
|
|
@@ -2654,6 +3044,7 @@ async function resolveAccountAddress(input) {
|
|
|
2654
3044
|
}
|
|
2655
3045
|
|
|
2656
3046
|
// src/commands/tx.ts
|
|
3047
|
+
init_errors();
|
|
2657
3048
|
async function parseStructArgs(meta, fields, args, callLabel) {
|
|
2658
3049
|
const fieldNames = Object.keys(fields);
|
|
2659
3050
|
if (args.length !== fieldNames.length) {
|
|
@@ -3074,8 +3465,13 @@ async function parseStorageKeys(meta, palletName2, storageItem, args) {
|
|
|
3074
3465
|
}
|
|
3075
3466
|
|
|
3076
3467
|
// src/commands/tx.ts
|
|
3468
|
+
init_store();
|
|
3469
|
+
init_types();
|
|
3470
|
+
init_accounts();
|
|
3077
3471
|
import { getViewBuilder as getViewBuilder2 } from "@polkadot-api/view-builder";
|
|
3078
3472
|
import { Binary as Binary3 } from "polkadot-api";
|
|
3473
|
+
init_metadata();
|
|
3474
|
+
init_errors();
|
|
3079
3475
|
async function handleTx(target, args, opts) {
|
|
3080
3476
|
if (!target) {
|
|
3081
3477
|
const config2 = await loadConfig();
|
|
@@ -3865,6 +4261,7 @@ function watchTransaction(observable) {
|
|
|
3865
4261
|
}
|
|
3866
4262
|
|
|
3867
4263
|
// src/config/store.ts
|
|
4264
|
+
init_types();
|
|
3868
4265
|
import { access as access3, mkdir as mkdir3, readFile as readFile3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
3869
4266
|
import { homedir as homedir2 } from "node:os";
|
|
3870
4267
|
import { join as join3 } from "node:path";
|
|
@@ -3901,6 +4298,7 @@ async function saveConfig2(config) {
|
|
|
3901
4298
|
}
|
|
3902
4299
|
|
|
3903
4300
|
// src/core/update-notifier.ts
|
|
4301
|
+
init_store();
|
|
3904
4302
|
import { readFileSync } from "node:fs";
|
|
3905
4303
|
import { mkdir as mkdir4, writeFile as writeFile4 } from "node:fs/promises";
|
|
3906
4304
|
import { join as join4 } from "node:path";
|
|
@@ -4089,159 +4487,180 @@ function parseDotPath(input, knownChains = []) {
|
|
|
4089
4487
|
}
|
|
4090
4488
|
|
|
4091
4489
|
// src/cli.ts
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
});
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
default: 100
|
|
4106
|
-
}).action(async (dotpath, args, opts) => {
|
|
4107
|
-
if (!dotpath) {
|
|
4108
|
-
printHelp();
|
|
4109
|
-
return;
|
|
4110
|
-
}
|
|
4111
|
-
const config = await loadConfig2();
|
|
4112
|
-
const knownChains = Object.keys(config.chains);
|
|
4113
|
-
let parsed;
|
|
4114
|
-
try {
|
|
4115
|
-
parsed = parseDotPath(dotpath, knownChains);
|
|
4116
|
-
} catch {
|
|
4117
|
-
throw new CliError2(`Unknown command "${dotpath}". Run "dot --help" for available commands.`);
|
|
4118
|
-
}
|
|
4119
|
-
if (parsed.chain && opts.chain) {
|
|
4120
|
-
throw new CliError2(`Chain specified both as prefix ("${parsed.chain}") and as --chain flag ("${opts.chain}"). Use one or the other.`);
|
|
4121
|
-
}
|
|
4122
|
-
const effectiveChain = parsed.chain ?? opts.chain;
|
|
4123
|
-
const handlerOpts = { chain: effectiveChain, rpc: opts.rpc, output: opts.output };
|
|
4124
|
-
const target = parsed.pallet ? parsed.item ? `${parsed.pallet}.${parsed.item}` : parsed.pallet : undefined;
|
|
4125
|
-
if (cli.options.help && parsed.pallet && parsed.item) {
|
|
4126
|
-
await showItemHelp2(parsed.category, target, handlerOpts);
|
|
4127
|
-
return;
|
|
4128
|
-
}
|
|
4129
|
-
switch (parsed.category) {
|
|
4130
|
-
case "query":
|
|
4131
|
-
await handleQuery(target, args, { ...handlerOpts, limit: opts.limit });
|
|
4132
|
-
break;
|
|
4133
|
-
case "tx":
|
|
4134
|
-
if (parsed.pallet && /^0x[0-9a-fA-F]+$/.test(parsed.pallet)) {
|
|
4135
|
-
await handleTx(parsed.pallet, args, {
|
|
4136
|
-
...handlerOpts,
|
|
4137
|
-
from: opts.from,
|
|
4138
|
-
dryRun: opts.dryRun,
|
|
4139
|
-
encode: opts.encode,
|
|
4140
|
-
ext: opts.ext
|
|
4141
|
-
});
|
|
4142
|
-
} else {
|
|
4143
|
-
await handleTx(target, args, {
|
|
4144
|
-
...handlerOpts,
|
|
4145
|
-
from: opts.from,
|
|
4146
|
-
dryRun: opts.dryRun,
|
|
4147
|
-
encode: opts.encode,
|
|
4148
|
-
ext: opts.ext
|
|
4149
|
-
});
|
|
4490
|
+
if (process.argv[2] === "__complete") {
|
|
4491
|
+
(async () => {
|
|
4492
|
+
try {
|
|
4493
|
+
const dashDashIndex = process.argv.indexOf("--");
|
|
4494
|
+
const completionArgs = dashDashIndex >= 0 ? process.argv.slice(dashDashIndex + 1) : [];
|
|
4495
|
+
const currentWord = completionArgs[0] ?? "";
|
|
4496
|
+
const precedingWords = completionArgs.slice(1);
|
|
4497
|
+
const { generateCompletions: generateCompletions2 } = await Promise.resolve().then(() => (init_complete(), exports_complete));
|
|
4498
|
+
const results = await generateCompletions2(currentWord, precedingWords);
|
|
4499
|
+
if (results.length > 0) {
|
|
4500
|
+
process.stdout.write(`${results.join(`
|
|
4501
|
+
`)}
|
|
4502
|
+
`);
|
|
4150
4503
|
}
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4504
|
+
} catch {}
|
|
4505
|
+
process.exit(0);
|
|
4506
|
+
})();
|
|
4507
|
+
} else {
|
|
4508
|
+
let printHelp = function() {
|
|
4509
|
+
console.log(`dot/${version} \u2014 Polkadot CLI`);
|
|
4510
|
+
console.log();
|
|
4511
|
+
console.log("Usage:");
|
|
4512
|
+
console.log(" dot <category>[.Pallet[.Item]] [args] [options]");
|
|
4513
|
+
console.log(" dot [Chain.]<category>[.Pallet[.Item]] [args] [options]");
|
|
4514
|
+
console.log();
|
|
4515
|
+
console.log("Categories:");
|
|
4516
|
+
console.log(" query Query on-chain storage");
|
|
4517
|
+
console.log(" tx Submit an extrinsic");
|
|
4518
|
+
console.log(" const Look up or list pallet constants");
|
|
4519
|
+
console.log(" events List or inspect pallet events");
|
|
4520
|
+
console.log(" errors List or inspect pallet errors");
|
|
4521
|
+
console.log();
|
|
4522
|
+
console.log("Examples:");
|
|
4523
|
+
console.log(" dot query.System.Account <addr> Query a storage item");
|
|
4524
|
+
console.log(" dot query.System List storage items in System");
|
|
4525
|
+
console.log(" dot tx.System.remark 0xdead --from alice");
|
|
4526
|
+
console.log(" dot const.Balances.ExistentialDeposit");
|
|
4527
|
+
console.log(" dot events.Balances List events in Balances");
|
|
4528
|
+
console.log(" dot polkadot.query.System.Number With chain prefix");
|
|
4529
|
+
console.log();
|
|
4530
|
+
console.log("Commands:");
|
|
4531
|
+
console.log(" inspect [target] Inspect chain metadata (alias: explore)");
|
|
4532
|
+
console.log(" chain Manage chain configurations");
|
|
4533
|
+
console.log(" account Manage accounts");
|
|
4534
|
+
console.log(" hash Hash utilities");
|
|
4535
|
+
console.log(" completions <sh> Generate shell completions (zsh, bash, fish)");
|
|
4536
|
+
console.log();
|
|
4537
|
+
console.log("Global options:");
|
|
4538
|
+
console.log(" --chain <name> Target chain (default from config)");
|
|
4539
|
+
console.log(" --rpc <url> Override RPC endpoint");
|
|
4540
|
+
console.log(" --light-client Use Smoldot light client");
|
|
4541
|
+
console.log(" --output <format> Output format: pretty or json");
|
|
4542
|
+
console.log(" --help, -h Display this message");
|
|
4543
|
+
console.log(" --version Show version");
|
|
4544
|
+
};
|
|
4545
|
+
startBackgroundCheck(version);
|
|
4546
|
+
const cli = cac("dot");
|
|
4547
|
+
cli.option("--chain <name>", "Target chain (default from config)");
|
|
4548
|
+
cli.option("--rpc <url>", "Override RPC endpoint for this call");
|
|
4549
|
+
cli.option("--light-client", "Use Smoldot light client instead of WebSocket");
|
|
4550
|
+
cli.option("--output <format>", "Output format: pretty or json", {
|
|
4551
|
+
default: "pretty"
|
|
4552
|
+
});
|
|
4553
|
+
registerChainCommands(cli);
|
|
4554
|
+
registerInspectCommand(cli);
|
|
4555
|
+
registerAccountCommands(cli);
|
|
4556
|
+
registerHashCommand(cli);
|
|
4557
|
+
registerCompletionsCommand(cli);
|
|
4558
|
+
cli.command("[dotpath] [...args]").option("--from <name>", "Account to sign with (for tx)").option("--dry-run", "Estimate fees without submitting (for tx)").option("--encode", "Encode call to hex without signing (for tx)").option("--ext <json>", "Custom signed extension values as JSON (for tx)").option("--limit <n>", "Max entries to return for map queries (0 = unlimited)", {
|
|
4559
|
+
default: 100
|
|
4560
|
+
}).action(async (dotpath, args, opts) => {
|
|
4561
|
+
if (!dotpath) {
|
|
4562
|
+
printHelp();
|
|
4563
|
+
return;
|
|
4564
|
+
}
|
|
4565
|
+
const config = await loadConfig2();
|
|
4566
|
+
const knownChains = Object.keys(config.chains);
|
|
4567
|
+
let parsed;
|
|
4568
|
+
try {
|
|
4569
|
+
parsed = parseDotPath(dotpath, knownChains);
|
|
4570
|
+
} catch {
|
|
4571
|
+
throw new CliError2(`Unknown command "${dotpath}". Run "dot --help" for available commands.`);
|
|
4572
|
+
}
|
|
4573
|
+
if (parsed.chain && opts.chain) {
|
|
4574
|
+
throw new CliError2(`Chain specified both as prefix ("${parsed.chain}") and as --chain flag ("${opts.chain}"). Use one or the other.`);
|
|
4575
|
+
}
|
|
4576
|
+
const effectiveChain = parsed.chain ?? opts.chain;
|
|
4577
|
+
const handlerOpts = { chain: effectiveChain, rpc: opts.rpc, output: opts.output };
|
|
4578
|
+
const target = parsed.pallet ? parsed.item ? `${parsed.pallet}.${parsed.item}` : parsed.pallet : undefined;
|
|
4579
|
+
if (cli.options.help && parsed.pallet && parsed.item) {
|
|
4580
|
+
await showItemHelp2(parsed.category, target, handlerOpts);
|
|
4581
|
+
return;
|
|
4582
|
+
}
|
|
4583
|
+
switch (parsed.category) {
|
|
4584
|
+
case "query":
|
|
4585
|
+
await handleQuery(target, args, { ...handlerOpts, limit: opts.limit });
|
|
4586
|
+
break;
|
|
4587
|
+
case "tx":
|
|
4588
|
+
if (parsed.pallet && /^0x[0-9a-fA-F]+$/.test(parsed.pallet)) {
|
|
4589
|
+
await handleTx(parsed.pallet, args, {
|
|
4590
|
+
...handlerOpts,
|
|
4591
|
+
from: opts.from,
|
|
4592
|
+
dryRun: opts.dryRun,
|
|
4593
|
+
encode: opts.encode,
|
|
4594
|
+
ext: opts.ext
|
|
4595
|
+
});
|
|
4596
|
+
} else {
|
|
4597
|
+
await handleTx(target, args, {
|
|
4598
|
+
...handlerOpts,
|
|
4599
|
+
from: opts.from,
|
|
4600
|
+
dryRun: opts.dryRun,
|
|
4601
|
+
encode: opts.encode,
|
|
4602
|
+
ext: opts.ext
|
|
4603
|
+
});
|
|
4604
|
+
}
|
|
4605
|
+
break;
|
|
4606
|
+
case "const":
|
|
4607
|
+
await handleConst(target, handlerOpts);
|
|
4608
|
+
break;
|
|
4609
|
+
case "events":
|
|
4610
|
+
await handleEvents2(target, handlerOpts);
|
|
4611
|
+
break;
|
|
4612
|
+
case "errors":
|
|
4613
|
+
await handleErrors2(target, handlerOpts);
|
|
4614
|
+
break;
|
|
4615
|
+
}
|
|
4616
|
+
});
|
|
4617
|
+
cli.option("--help, -h", "Display this message");
|
|
4618
|
+
cli.version(version);
|
|
4619
|
+
async function showUpdateAndExit(code) {
|
|
4620
|
+
await waitForPendingCheck();
|
|
4621
|
+
const note = getUpdateNotification(version);
|
|
4622
|
+
if (note)
|
|
4623
|
+
process.stderr.write(`${note}
|
|
4206
4624
|
`);
|
|
4207
|
-
|
|
4208
|
-
}
|
|
4209
|
-
async function handleError(err) {
|
|
4210
|
-
if (err instanceof CliError2) {
|
|
4211
|
-
console.error(`Error: ${err.message}`);
|
|
4212
|
-
} else if (err instanceof Error) {
|
|
4213
|
-
console.error(`Error: ${err.message}`);
|
|
4214
|
-
} else {
|
|
4215
|
-
console.error("An unexpected error occurred:", err);
|
|
4625
|
+
process.exit(code);
|
|
4216
4626
|
}
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
}
|
|
4225
|
-
|
|
4627
|
+
async function handleError(err) {
|
|
4628
|
+
if (err instanceof CliError2) {
|
|
4629
|
+
console.error(`Error: ${err.message}`);
|
|
4630
|
+
} else if (err instanceof Error) {
|
|
4631
|
+
console.error(`Error: ${err.message}`);
|
|
4632
|
+
} else {
|
|
4633
|
+
console.error("An unexpected error occurred:", err);
|
|
4634
|
+
}
|
|
4635
|
+
return showUpdateAndExit(1);
|
|
4636
|
+
}
|
|
4637
|
+
async function main() {
|
|
4638
|
+
try {
|
|
4639
|
+
cli.parse(process.argv, { run: false });
|
|
4640
|
+
if (cli.options.version) {
|
|
4641
|
+
await showUpdateAndExit(0);
|
|
4642
|
+
} else if (cli.options.help) {
|
|
4643
|
+
if (cli.matchedCommand) {
|
|
4644
|
+
const result = cli.runMatchedCommand();
|
|
4645
|
+
if (result && typeof result.then === "function") {
|
|
4646
|
+
await result.then(() => showUpdateAndExit(0), handleError);
|
|
4647
|
+
}
|
|
4648
|
+
} else {
|
|
4649
|
+
printHelp();
|
|
4650
|
+
await showUpdateAndExit(0);
|
|
4651
|
+
}
|
|
4652
|
+
} else if (!cli.matchedCommand) {
|
|
4653
|
+
printHelp();
|
|
4654
|
+
await showUpdateAndExit(0);
|
|
4655
|
+
} else {
|
|
4226
4656
|
const result = cli.runMatchedCommand();
|
|
4227
4657
|
if (result && typeof result.then === "function") {
|
|
4228
4658
|
await result.then(() => showUpdateAndExit(0), handleError);
|
|
4229
4659
|
}
|
|
4230
|
-
} else {
|
|
4231
|
-
printHelp();
|
|
4232
|
-
await showUpdateAndExit(0);
|
|
4233
|
-
}
|
|
4234
|
-
} else if (!cli.matchedCommand) {
|
|
4235
|
-
printHelp();
|
|
4236
|
-
await showUpdateAndExit(0);
|
|
4237
|
-
} else {
|
|
4238
|
-
const result = cli.runMatchedCommand();
|
|
4239
|
-
if (result && typeof result.then === "function") {
|
|
4240
|
-
await result.then(() => showUpdateAndExit(0), handleError);
|
|
4241
4660
|
}
|
|
4661
|
+
} catch (err) {
|
|
4662
|
+
await handleError(err);
|
|
4242
4663
|
}
|
|
4243
|
-
} catch (err) {
|
|
4244
|
-
await handleError(err);
|
|
4245
4664
|
}
|
|
4665
|
+
main();
|
|
4246
4666
|
}
|
|
4247
|
-
main();
|