@xyo-network/xl1-cli-lib 1.22.0 → 1.23.2

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/dist/node/xl1.mjs CHANGED
@@ -1,22 +1,30 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
1
  // src/start.ts
5
2
  import { config } from "dotenv";
6
3
 
7
4
  // src/runCLI.ts
8
- import { stdin as input, stdout as output } from "process";
9
- import { createInterface } from "readline/promises";
5
+ import { stdin as input, stdout as output } from "node:process";
6
+ import { createInterface } from "node:readline/promises";
10
7
  import { isDefined as isDefined3 } from "@xylabs/sdk-js";
11
8
  import { apiCommand } from "@xyo-network/chain-api";
12
9
  import { bridgeCommand } from "@xyo-network/chain-bridge";
13
10
  import { finalizerCommand } from "@xyo-network/chain-finalizer";
14
11
  import { mempoolCommand } from "@xyo-network/chain-mempool";
15
- import { contextFromConfigWithoutLocator, detectDerivationPathCollisions, formatWalletReport, initializeResolvedWalletReport, locatorsFromConfig, Orchestrator } from "@xyo-network/chain-orchestration";
12
+ import {
13
+ contextFromConfigWithoutLocator,
14
+ detectDerivationPathCollisions,
15
+ formatWalletReport,
16
+ initializeResolvedWalletReport,
17
+ locatorsFromConfig,
18
+ Orchestrator
19
+ } from "@xyo-network/chain-orchestration";
16
20
  import { initHealthEndpoints } from "@xyo-network/chain-orchestration-express";
17
21
  import { producerCommand } from "@xyo-network/chain-producer";
18
22
  import { rewardRedemptionCommand } from "@xyo-network/chain-reward-redemption";
19
- import { ActorConfigZod, ConfigZod as ConfigZod2, DefaultMetricsScrapePorts } from "@xyo-network/xl1-sdk";
23
+ import {
24
+ ActorConfigZod,
25
+ ConfigZod as ConfigZod2,
26
+ DefaultMetricsScrapePorts
27
+ } from "@xyo-network/xl1-sdk";
20
28
  import yargs from "yargs";
21
29
  import { hideBin } from "yargs/helpers";
22
30
 
@@ -25,13 +33,26 @@ import { getApiActor } from "@xyo-network/chain-api";
25
33
  import { getBridgeActor } from "@xyo-network/chain-bridge";
26
34
  import { getFinalizerActor } from "@xyo-network/chain-finalizer";
27
35
  import { getMempoolActor } from "@xyo-network/chain-mempool";
28
- import { ApiConfigZod, BridgeConfigZod, FinalizerConfigZod, MempoolConfigZod, ProducerConfigZod, RewardRedemptionConfigZod } from "@xyo-network/chain-orchestration";
36
+ import {
37
+ ApiConfigZod,
38
+ BridgeConfigZod,
39
+ FinalizerConfigZod,
40
+ MempoolConfigZod,
41
+ ProducerConfigZod,
42
+ RewardRedemptionConfigZod
43
+ } from "@xyo-network/chain-orchestration";
29
44
  import { getProducerActor } from "@xyo-network/chain-producer";
30
45
  import { getRewardRedemptionActor } from "@xyo-network/chain-reward-redemption";
31
46
 
32
47
  // src/initLogger.ts
33
- import { Base, ConsoleLogger, isDefined, LogLevel, SilentLogger } from "@xylabs/sdk-js";
34
- var initLogger = /* @__PURE__ */ __name((config2) => {
48
+ import {
49
+ Base,
50
+ ConsoleLogger,
51
+ isDefined,
52
+ LogLevel,
53
+ SilentLogger
54
+ } from "@xylabs/sdk-js";
55
+ var initLogger = (config2) => {
35
56
  let logger;
36
57
  if (config2.log.silent) {
37
58
  logger = new SilentLogger();
@@ -45,31 +66,18 @@ var initLogger = /* @__PURE__ */ __name((config2) => {
45
66
  }
46
67
  Base.defaultLogger = logger;
47
68
  return logger;
48
- }, "initLogger");
69
+ };
49
70
 
50
71
  // src/commands/start/startCommand.ts
51
- var KNOWN_ACTORS = [
52
- "api",
53
- "bridge",
54
- "finalizer",
55
- "mempool",
56
- "producer",
57
- "rewardRedemption"
58
- ];
72
+ var KNOWN_ACTORS = ["api", "bridge", "finalizer", "mempool", "producer", "rewardRedemption"];
59
73
  var BOOT_TIMEOUT_MS = 6e4;
60
74
  function getActorsFromConfig(configuration2) {
61
75
  const enabledActors = configuration2.actors.filter((actor) => actor.enabled !== false).map((actor) => actor.name);
62
76
  return enabledActors.length > 0 ? enabledActors : void 0;
63
77
  }
64
- __name(getActorsFromConfig, "getActorsFromConfig");
65
78
  function getDefaultActors() {
66
- return [
67
- "api",
68
- "producer",
69
- "finalizer"
70
- ];
79
+ return ["api", "producer", "finalizer"];
71
80
  }
72
- __name(getDefaultActors, "getDefaultActors");
73
81
  async function buildActor(name, locator) {
74
82
  switch (name) {
75
83
  case "api": {
@@ -101,7 +109,6 @@ async function buildActor(name, locator) {
101
109
  }
102
110
  }
103
111
  }
104
- __name(buildActor, "buildActor");
105
112
  async function bootActors(requestedActors, locators, orchestrator, configuration2) {
106
113
  const startedAt = Date.now();
107
114
  const actors = await Promise.all(requestedActors.map((name) => buildActor(name, locators[name])));
@@ -111,39 +118,34 @@ async function bootActors(requestedActors, locators, orchestrator, configuration
111
118
  await orchestrator.start();
112
119
  await orchestrator.whenReady(BOOT_TIMEOUT_MS);
113
120
  const ms = Date.now() - startedAt;
114
- initLogger(configuration2).info(`[xl1] system ready (${requestedActors.length} actor${requestedActors.length === 1 ? "" : "s"}, ${ms}ms)`);
121
+ initLogger(configuration2).info(`[xl1] system ready (${requestedActors.join("/")} in ${ms}ms)`);
115
122
  }
116
- __name(bootActors, "bootActors");
117
123
  function startCommand(getConfiguration2, getLocatorsFromConfig2) {
118
124
  return {
119
- command: [
120
- "start [actors..]",
121
- "$0"
122
- ],
125
+ command: ["start [actors..]", "$0"],
123
126
  describe: "Run a full XL1 Node",
124
- builder: /* @__PURE__ */ __name((yargs2) => {
127
+ builder: (yargs2) => {
125
128
  return yargs2.positional("actors", {
126
129
  type: "string",
127
130
  array: true,
128
131
  choices: KNOWN_ACTORS,
129
132
  description: "Actors to start (e.g. xl1 start api producer or xl1 start api,producer)",
130
- coerce: /* @__PURE__ */ __name((values) => values.flatMap((v) => v.split(",")), "coerce")
133
+ coerce: (values) => values.flatMap((v) => v.split(","))
131
134
  }).option("actors", {
132
135
  type: "array",
133
136
  string: true,
134
137
  choices: KNOWN_ACTORS,
135
138
  description: "List of actors to start (e.g. --actors api producer finalizer). Defaults to api, producer, and finalizer."
136
139
  });
137
- }, "builder"),
138
- handler: /* @__PURE__ */ __name(async (argv) => {
140
+ },
141
+ handler: async (argv) => {
139
142
  const configuration2 = getConfiguration2();
140
143
  const requestedActors = argv.actors !== void 0 && argv.actors.length > 0 ? argv.actors : getActorsFromConfig(configuration2) ?? getDefaultActors();
141
144
  const { locators, orchestrator } = await getLocatorsFromConfig2(requestedActors, configuration2);
142
145
  await bootActors(requestedActors, locators, orchestrator, configuration2);
143
- }, "handler")
146
+ }
144
147
  };
145
148
  }
146
- __name(startCommand, "startCommand");
147
149
 
148
150
  // src/commands/withDeprecationWarning.ts
149
151
  import { delay } from "@xylabs/sdk-js";
@@ -152,53 +154,76 @@ function withDeprecationWarning(module) {
152
154
  if (typeof deprecated === "string") {
153
155
  return {
154
156
  ...module,
155
- handler: /* @__PURE__ */ __name(async (argv) => {
157
+ handler: async (argv) => {
156
158
  console.warn(`[deprecated] ${deprecated}`);
157
159
  await delay(3e3);
158
160
  return handler(argv);
159
- }, "handler")
161
+ }
160
162
  };
161
163
  }
162
164
  return module;
163
165
  }
164
- __name(withDeprecationWarning, "withDeprecationWarning");
165
166
 
166
167
  // src/configMiddleware.ts
167
168
  import { createDeepMerge, isDefined as isDefined2 } from "@xylabs/sdk-js";
168
- import { ActorMnemonicNotAllowedError, assertNoActorMnemonics, ConfigFileNotFoundError, tryParseConfig } from "@xyo-network/chain-orchestration";
169
- import { ConfigZod, isZodError, resolveConfig } from "@xyo-network/xl1-sdk";
170
- var deepMerge = createDeepMerge({
171
- arrayStrategy: "concat"
172
- });
169
+ import {
170
+ ActorMnemonicNotAllowedError,
171
+ assertNoActorMnemonics,
172
+ ConfigFileNotFoundError,
173
+ tryParseConfig
174
+ } from "@xyo-network/chain-orchestration";
175
+ import {
176
+ ConfigZod,
177
+ isZodError,
178
+ resolveConfig
179
+ } from "@xyo-network/xl1-sdk";
180
+ var deepMerge = createDeepMerge({ arrayStrategy: "concat" });
181
+ var REDACTED = "[REDACTED]";
182
+ var REDACTED_KEY_NAMES = /* @__PURE__ */ new Set(["mnemonic", "connectionString"]);
183
+ var REDACTED_KEY_SUFFIX = /(PrivateKey|Secret|Password)$/i;
184
+ function shouldRedactKey(key) {
185
+ if (REDACTED_KEY_NAMES.has(key)) return true;
186
+ return REDACTED_KEY_SUFFIX.test(key);
187
+ }
188
+ function redactConfig(config2) {
189
+ const cloned = structuredClone(config2);
190
+ redactInPlace(cloned);
191
+ return cloned;
192
+ }
193
+ function redactInPlace(node) {
194
+ if (Array.isArray(node)) {
195
+ for (const item of node) redactInPlace(item);
196
+ return;
197
+ }
198
+ if (node === null || typeof node !== "object") return;
199
+ const obj = node;
200
+ for (const key of Object.keys(obj)) {
201
+ if (shouldRedactKey(key) && obj[key] !== void 0 && obj[key] !== null) {
202
+ obj[key] = REDACTED;
203
+ } else {
204
+ redactInPlace(obj[key]);
205
+ }
206
+ }
207
+ }
173
208
  function coerceActorsArray(argv) {
174
209
  const actors = argv.actors;
175
210
  if (actors === void 0 || Array.isArray(actors)) return argv;
176
211
  if (typeof actors !== "object" || actors === null) return argv;
177
212
  const entries = Object.entries(actors);
178
- const numericEntries = entries.map(([key, value]) => [
179
- Number(key),
180
- value
181
- ]).filter(([key]) => Number.isInteger(key) && key >= 0);
213
+ const numericEntries = entries.map(([key, value]) => [Number(key), value]).filter(([key]) => Number.isInteger(key) && key >= 0);
182
214
  if (numericEntries.length !== entries.length) return argv;
183
215
  const asArray = [];
184
216
  for (const [key, value] of numericEntries) asArray[key] = value;
185
- return {
186
- ...argv,
187
- actors: asArray
188
- };
217
+ return { ...argv, actors: asArray };
189
218
  }
190
- __name(coerceActorsArray, "coerceActorsArray");
191
219
  function safeParseOrThrow(input2) {
192
220
  const result = ConfigZod.safeParse(input2);
193
221
  if (!result.success) throw result.error;
194
222
  return result.data;
195
223
  }
196
- __name(safeParseOrThrow, "safeParseOrThrow");
197
224
  async function buildFinalConfig(argv) {
198
225
  const configPath = argv.config;
199
- const parsedConfigFile = await tryParseConfig({
200
- configPath
201
- });
226
+ const parsedConfigFile = await tryParseConfig({ configPath });
202
227
  const rootMnemonicFromFile = typeof parsedConfigFile.mnemonic === "string" ? parsedConfigFile.mnemonic : void 0;
203
228
  const normalizedArgv = coerceActorsArray(argv);
204
229
  const parsedConfigArgs = ConfigZod.safeParse(normalizedArgv).data ?? {};
@@ -206,19 +231,17 @@ async function buildFinalConfig(argv) {
206
231
  const mergedConfig = safeParseOrThrow(deepMerge(parsedConfigFile, parsedConfigArgs));
207
232
  const validated = safeParseOrThrow(resolveConfig(safeParseOrThrow(mergedConfig)));
208
233
  const rootMnemonic = rootMnemonicFromArgs ?? rootMnemonicFromFile;
209
- return isDefined2(rootMnemonic) ? {
210
- ...validated,
211
- mnemonic: rootMnemonic
212
- } : validated;
234
+ return isDefined2(rootMnemonic) ? { ...validated, mnemonic: rootMnemonic } : validated;
213
235
  }
214
- __name(buildFinalConfig, "buildFinalConfig");
215
236
  async function configMiddleware(argv, setConfiguration) {
216
237
  try {
217
238
  const finalConfig = await buildFinalConfig(argv);
218
239
  assertNoActorMnemonics(finalConfig);
219
240
  setConfiguration(finalConfig);
220
241
  if (argv["dump-config"]) {
221
- console.log(JSON.stringify(finalConfig, null, 2));
242
+ const withSecrets = Boolean(argv["with-secrets"]);
243
+ const output2 = withSecrets ? finalConfig : redactConfig(finalConfig);
244
+ console.log(JSON.stringify(output2, null, 2));
222
245
  process.exit(0);
223
246
  }
224
247
  } catch (err) {
@@ -234,12 +257,141 @@ async function configMiddleware(argv, setConfiguration) {
234
257
  if (!(err instanceof ConfigFileNotFoundError) && !(err instanceof ActorMnemonicNotAllowedError)) {
235
258
  console.error(`Stack: ${err instanceof Error ? err.stack : "N/A"}`);
236
259
  }
237
- throw new Error("Invalid configuration", {
238
- cause: err
239
- });
260
+ throw new Error("Invalid configuration", { cause: err });
240
261
  }
241
262
  }
242
- __name(configMiddleware, "configMiddleware");
263
+
264
+ // src/dumpProviders.ts
265
+ var CANONICAL_ACTOR_ORDER = [
266
+ "_root",
267
+ "producer",
268
+ "finalizer",
269
+ "api",
270
+ "mempool",
271
+ "bridge",
272
+ "rewardRedemption"
273
+ ];
274
+ function enumerateLocator(locator) {
275
+ const collapsed = /* @__PURE__ */ new Map();
276
+ const registry = locator.registry;
277
+ for (const moniker of Object.keys(registry)) {
278
+ const factories = registry[moniker];
279
+ if (!factories) continue;
280
+ for (const factory of factories) {
281
+ const f = factory;
282
+ const providerName = f.providerName ?? "<unknown>";
283
+ const scope = f.scope ?? "<unknown>";
284
+ const dependencies = f.dependencies ?? [];
285
+ const fingerprint = `${moniker}|${providerName}|${scope}|${dependencies.join(",")}`;
286
+ const existing = collapsed.get(fingerprint);
287
+ if (existing) {
288
+ existing.count += 1;
289
+ } else {
290
+ collapsed.set(fingerprint, {
291
+ count: 1,
292
+ dependencies,
293
+ moniker,
294
+ providerName,
295
+ scope
296
+ });
297
+ }
298
+ }
299
+ }
300
+ return [...collapsed.values()].toSorted((a, b) => a.moniker.localeCompare(b.moniker) || a.providerName.localeCompare(b.providerName));
301
+ }
302
+ function buildOwnerIndex(perActor) {
303
+ const monikerOwners = /* @__PURE__ */ new Map();
304
+ for (const [actorName, entries] of perActor) {
305
+ for (const entry of entries) {
306
+ let owners = monikerOwners.get(entry.moniker);
307
+ if (!owners) {
308
+ owners = /* @__PURE__ */ new Set();
309
+ monikerOwners.set(entry.moniker, owners);
310
+ }
311
+ owners.add(actorName);
312
+ }
313
+ }
314
+ return monikerOwners;
315
+ }
316
+ function renderDuplicatesSummary(monikerOwners) {
317
+ const duplicates = [...monikerOwners.entries()].filter(([, owners]) => owners.size > 1).map(([moniker, owners]) => ({ moniker, owners: [...owners].toSorted().map(formatGroupForDisplay) })).toSorted((a, b) => a.moniker.localeCompare(b.moniker));
318
+ if (duplicates.length === 0) return [];
319
+ const lines = ["Duplicate monikers (registered by more than one locator):"];
320
+ for (const { moniker, owners } of duplicates) {
321
+ lines.push(` - ${moniker}: ${owners.join(", ")}`);
322
+ }
323
+ lines.push("");
324
+ return lines;
325
+ }
326
+ function groupActorsBySharedRegistry(locators) {
327
+ const groups = [];
328
+ for (const actorName of Object.keys(locators)) {
329
+ const locator = locators[actorName];
330
+ const existing = groups.find((g) => g.registry === locator.registry);
331
+ if (existing) {
332
+ existing.actorNames.push(actorName);
333
+ } else {
334
+ groups.push({
335
+ actorNames: [actorName],
336
+ locator,
337
+ registry: locator.registry
338
+ });
339
+ }
340
+ }
341
+ return groups;
342
+ }
343
+ function groupId(actorNames) {
344
+ return [...actorNames].toSorted().join(",");
345
+ }
346
+ function formatGroupForDisplay(groupKey) {
347
+ const members = groupKey.split(",");
348
+ return members.length === 1 ? members[0] : `(${members.join(", ")})`;
349
+ }
350
+ function renderGroupSection(actorNames, entries, monikerOwners) {
351
+ const sortedActors = [...actorNames].toSorted();
352
+ const ownGroupKey = groupId(sortedActors);
353
+ const heading = sortedActors.length === 1 ? `Providers for actor: ${sortedActors[0]} (${entries.length} registered)` : `Providers shared by actors: ${sortedActors.join(", ")} (${entries.length} registered)`;
354
+ const lines = [heading];
355
+ if (entries.length === 0) {
356
+ lines.push(" (none)", "");
357
+ return lines;
358
+ }
359
+ for (let i = 0; i < entries.length; i++) {
360
+ const entry = entries[i];
361
+ const isLast = i === entries.length - 1;
362
+ const branch = isLast ? "\u2514\u2500\u2500" : "\u251C\u2500\u2500";
363
+ const owners = monikerOwners.get(entry.moniker) ?? /* @__PURE__ */ new Set();
364
+ const otherOwners = [...owners].filter((o) => o !== ownGroupKey).toSorted().map(formatGroupForDisplay);
365
+ const dupNote = otherOwners.length > 0 ? ` \u26A0 also in: ${otherOwners.join(", ")}` : "";
366
+ const depsNote = entry.dependencies.length > 0 ? `, deps: [${entry.dependencies.join(", ")}]` : "";
367
+ const countNote = entry.count > 1 ? ` (\xD7${entry.count})` : "";
368
+ lines.push(` ${branch} ${entry.moniker}${countNote} [impl: ${entry.providerName}, scope: ${entry.scope}${depsNote}]${dupNote}`);
369
+ }
370
+ lines.push("");
371
+ return lines;
372
+ }
373
+ function formatProviderTree(locators) {
374
+ const groups = groupActorsBySharedRegistry(locators);
375
+ const groupKeys = groups.map((g) => ({ ...g, key: groupId(g.actorNames) }));
376
+ const perGroup = /* @__PURE__ */ new Map();
377
+ for (const g of groupKeys) perGroup.set(g.key, enumerateLocator(g.locator));
378
+ const monikerOwners = buildOwnerIndex(perGroup);
379
+ const orderedGroups = [...groupKeys].toSorted((a, b) => {
380
+ const aHasRoot = a.actorNames.includes("_root");
381
+ const bHasRoot = b.actorNames.includes("_root");
382
+ if (aHasRoot !== bHasRoot) return aHasRoot ? -1 : 1;
383
+ const ai = CANONICAL_ACTOR_ORDER.indexOf(a.actorNames[0]);
384
+ const bi = CANONICAL_ACTOR_ORDER.indexOf(b.actorNames[0]);
385
+ if (ai !== bi) return (ai === -1 ? Number.MAX_SAFE_INTEGER : ai) - (bi === -1 ? Number.MAX_SAFE_INTEGER : bi);
386
+ return a.key.localeCompare(b.key);
387
+ });
388
+ const lines = ["XL1 Provider Dump", "=================", ""];
389
+ for (const g of orderedGroups) {
390
+ lines.push(...renderGroupSection(g.actorNames.toSorted(), perGroup.get(g.key) ?? [], monikerOwners));
391
+ }
392
+ lines.push(...renderDuplicatesSummary(monikerOwners));
393
+ return lines.join("\n");
394
+ }
243
395
 
244
396
  // src/images.ts
245
397
  var XL1LogoColorizedAscii = `\x1B[38;2;128;128;128m\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\x1B[0m\x1B[38;2;118;111;144m_\x1B[0m
@@ -264,10 +416,10 @@ var XL1LogoColorizedAscii = `\x1B[38;2;128;128;128m\xA0\xA0\xA0\xA0\xA0\xA0\xA0\
264
416
  // src/optionsFromGlobalZodRegistry.ts
265
417
  import { isUsageMeta } from "@xyo-network/xl1-sdk";
266
418
  import { globalRegistry } from "zod";
267
- var usageMetaToOptions = /* @__PURE__ */ __name((meta) => {
419
+ var usageMetaToOptions = (meta) => {
268
420
  return meta;
269
- }, "usageMetaToOptions");
270
- var optionsFromGlobalZodRegistry = /* @__PURE__ */ __name(() => {
421
+ };
422
+ var optionsFromGlobalZodRegistry = () => {
271
423
  const opts = {};
272
424
  for (const schema of Object.values(globalRegistry._map)) {
273
425
  if (isUsageMeta(schema)) {
@@ -276,7 +428,7 @@ var optionsFromGlobalZodRegistry = /* @__PURE__ */ __name(() => {
276
428
  }
277
429
  }
278
430
  return opts;
279
- }, "optionsFromGlobalZodRegistry");
431
+ };
280
432
 
281
433
  // src/runCLI.ts
282
434
  var DEFAULT_HEALTH_CHECK_PORT = 9090;
@@ -285,30 +437,25 @@ function defaultScrapePortForActors(actors) {
285
437
  const key = primary === "rewardRedemption" ? "rewardRedemptionApi" : primary;
286
438
  return DefaultMetricsScrapePorts[key] ?? DefaultMetricsScrapePorts.producer;
287
439
  }
288
- __name(defaultScrapePortForActors, "defaultScrapePortForActors");
289
440
  var configuration;
290
441
  var skipInsecureConfirm = false;
291
- var version = isDefined3("1.22.0") ? "1.22.0" : "unknown";
442
+ var dumpProviders = false;
443
+ var version = isDefined3("1.23.2") ? "1.23.2" : "unknown";
292
444
  function getConfiguration() {
293
445
  return configuration;
294
446
  }
295
- __name(getConfiguration, "getConfiguration");
296
447
  async function promptForInsecureGenesisConfirmation(logger) {
297
448
  if (!input.isTTY || !output.isTTY) {
298
449
  logger.warn("Insecure genesis reward wallet is active. Interactive confirmation skipped because this session is not a TTY.");
299
450
  return;
300
451
  }
301
- const rl = createInterface({
302
- input,
303
- output
304
- });
452
+ const rl = createInterface({ input, output });
305
453
  try {
306
454
  await rl.question("Insecure genesis reward wallet is active. Hit RETURN to continue.");
307
455
  } finally {
308
456
  rl.close();
309
457
  }
310
458
  }
311
- __name(promptForInsecureGenesisConfirmation, "promptForInsecureGenesisConfirmation");
312
459
  async function getLocatorsFromConfig(actors, configuration2) {
313
460
  const actorConfigs = [];
314
461
  for (const actorName of actors) {
@@ -316,20 +463,13 @@ async function getLocatorsFromConfig(actors, configuration2) {
316
463
  if (existingConfig) {
317
464
  actorConfigs.push(existingConfig);
318
465
  } else {
319
- const actorConfig = ActorConfigZod.loose().parse({
320
- name: actorName
321
- });
466
+ const actorConfig = ActorConfigZod.loose().parse({ name: actorName });
322
467
  actorConfigs.push(actorConfig);
323
468
  }
324
469
  }
325
- const config2 = ConfigZod2.parse({
326
- ...configuration2,
327
- actors: actorConfigs
328
- });
470
+ const config2 = ConfigZod2.parse({ ...configuration2, actors: actorConfigs });
329
471
  const logger = initLogger(configuration2);
330
- const orchestrator = await Orchestrator.create({
331
- logger
332
- });
472
+ const orchestrator = await Orchestrator.create({ logger });
333
473
  const collision = detectDerivationPathCollisions(actors, configuration2);
334
474
  if (collision) throw collision;
335
475
  const walletReport = await initializeResolvedWalletReport(actors, configuration2);
@@ -341,6 +481,10 @@ async function getLocatorsFromConfig(actors, configuration2) {
341
481
  }
342
482
  const onInsecureGenesisConfirm = skipInsecureConfirm ? void 0 : async () => await promptForInsecureGenesisConfirmation(logger);
343
483
  const locators = await locatorsFromConfig(context, config2, onInsecureGenesisConfirm);
484
+ if (dumpProviders) {
485
+ console.log(formatProviderTree(locators));
486
+ process.exit(0);
487
+ }
344
488
  const healthCheckPort = configuration2.healthCheckPort ?? DEFAULT_HEALTH_CHECK_PORT;
345
489
  const healthServer = healthCheckPort > 0 && context.statusReporter !== void 0 ? await initHealthEndpoints({
346
490
  logger,
@@ -362,12 +506,8 @@ async function getLocatorsFromConfig(actors, configuration2) {
362
506
  }
363
507
  })();
364
508
  });
365
- return {
366
- locators,
367
- orchestrator
368
- };
509
+ return { locators, orchestrator };
369
510
  }
370
- __name(getLocatorsFromConfig, "getLocatorsFromConfig");
371
511
  async function runCLI() {
372
512
  const y = yargs(hideBin(process.argv));
373
513
  const argv = y.usage(`
@@ -378,13 +518,17 @@ Run various components of the XL1 ecosystem.
378
518
  Usage:
379
519
  $0 <command> [options]`).parserConfiguration({
380
520
  "dot-notation": true,
521
+ // foo.bar → { foo: { bar } }
381
522
  "parse-numbers": false,
523
+ // Don't auto-parse numbers to allow strings like "0x1"
382
524
  "populate--": true
525
+ // Populate -- with all options so we can detected user-supplied vs defaults
383
526
  }).env("XL1").scriptName("xl1").middleware(async (argv2) => {
384
527
  await configMiddleware(argv2, (config2) => {
385
528
  configuration = config2;
386
529
  });
387
530
  skipInsecureConfirm = Boolean(argv2["skip-insecure-confirm"]);
531
+ dumpProviders = Boolean(argv2["dump-providers"]);
388
532
  }).options(optionsFromGlobalZodRegistry()).wrap(y.terminalWidth()).command(withDeprecationWarning(apiCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(bridgeCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(finalizerCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(mempoolCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(producerCommand(getConfiguration, getLocatorsFromConfig))).command(withDeprecationWarning(rewardRedemptionCommand(getConfiguration, getLocatorsFromConfig))).command(startCommand(getConfiguration, getLocatorsFromConfig)).options({
389
533
  "config": {
390
534
  type: "string",
@@ -397,7 +541,17 @@ $0 <command> [options]`).parserConfiguration({
397
541
  },
398
542
  "dump-config": {
399
543
  type: "boolean",
400
- description: "Just process the configuration and print the resolved config to stdout, then exit.",
544
+ description: "Just process the configuration and print the resolved config to stdout, then exit. Secrets are redacted unless --with-secrets is also passed.",
545
+ default: false
546
+ },
547
+ "with-secrets": {
548
+ type: "boolean",
549
+ description: 'When used with --dump-config, print raw secret values (mnemonic, private keys, passwords) instead of "[REDACTED]". Use only on a developer machine.',
550
+ default: false
551
+ },
552
+ "dump-providers": {
553
+ type: "boolean",
554
+ description: "Run the normal command flow up to provider locator construction, print the per-actor provider tree (with duplicate detection), then exit.",
401
555
  default: false
402
556
  },
403
557
  "skip-insecure-confirm": {
@@ -408,19 +562,16 @@ $0 <command> [options]`).parserConfiguration({
408
562
  }).help().alias("help", "h").version(version).argv;
409
563
  await argv;
410
564
  }
411
- __name(runCLI, "runCLI");
412
565
 
413
566
  // src/start.ts
414
- var start = /* @__PURE__ */ __name(async () => {
415
- config({
416
- quiet: true
417
- });
567
+ var start = async () => {
568
+ config({ quiet: true });
418
569
  await runCLI();
419
- }, "start");
570
+ };
420
571
 
421
572
  // src/xl1.ts
422
573
  start().catch((err) => {
423
574
  if (process.env.NODE_ENV === "development") console.error("An error occurred during startup:", err);
424
575
  process.exit(1);
425
576
  });
426
- //# sourceMappingURL=xl1.mjs.map
577
+ //# sourceMappingURL=xl1.mjs.map