@clanker-chain/clanker-cli 2026.9.7 → 2026.9.8-1
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/bin/clanker.mjs +242 -90
- package/lib/doctor.mjs +226 -0
- package/lib/foundry.mjs +114 -0
- package/lib/openclaw-wire.mjs +104 -0
- package/lib/operator-key.mjs +50 -0
- package/lib/profile.mjs +17 -9
- package/lib/resolve.mjs +57 -1
- package/lib/setup-detect.mjs +224 -0
- package/lib/setup.mjs +741 -0
- package/lib/ui.mjs +104 -0
- package/package.json +3 -1
package/bin/clanker.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { existsSync,
|
|
4
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import process from "node:process";
|
|
8
8
|
import { getAddress } from "viem";
|
|
9
9
|
import {
|
|
10
10
|
ANVIL_DEFAULT_PRIVATE_KEY,
|
|
11
|
-
harnessSnippet,
|
|
12
11
|
initProfile,
|
|
13
12
|
isLocalRpc,
|
|
14
13
|
loadConfig,
|
|
@@ -23,7 +22,19 @@ import {
|
|
|
23
22
|
readBot,
|
|
24
23
|
resolvePreferredOperator,
|
|
25
24
|
} from "../lib/identity-query.mjs";
|
|
26
|
-
import { resolveForRead, resolveOperatorKey } from "../lib/resolve.mjs";
|
|
25
|
+
import { resolveForRead, resolveOperatorKey, resolveReadIdentity } from "../lib/resolve.mjs";
|
|
26
|
+
import { runSetup } from "../lib/setup.mjs";
|
|
27
|
+
import { runDoctor } from "../lib/doctor.mjs";
|
|
28
|
+
import {
|
|
29
|
+
hubConnectChecklist,
|
|
30
|
+
wireOpenClawMqtt,
|
|
31
|
+
} from "../lib/openclaw-wire.mjs";
|
|
32
|
+
import {
|
|
33
|
+
c,
|
|
34
|
+
confirmPlan,
|
|
35
|
+
exitCliError,
|
|
36
|
+
nextHint,
|
|
37
|
+
} from "../lib/ui.mjs";
|
|
27
38
|
|
|
28
39
|
function resolveFoundryBinary(name) {
|
|
29
40
|
const home = os.homedir();
|
|
@@ -144,16 +155,18 @@ function usage() {
|
|
|
144
155
|
console.log(`clanker - clanker-chain helper CLI
|
|
145
156
|
|
|
146
157
|
Usage:
|
|
158
|
+
clanker setup [--preset sepolia|local] [--operator <label>] [--address 0x…] [--key-file path] [--force]
|
|
159
|
+
clanker doctor [--json]
|
|
147
160
|
clanker init --preset sepolia|local [--force]
|
|
148
|
-
clanker whoami [--json] [--operator <label>] [--address 0x…]
|
|
149
|
-
clanker operator mint <label> [--json]
|
|
150
|
-
clanker operator transfer propose <label> <newOwner>
|
|
151
|
-
clanker operator transfer accept <label>
|
|
152
|
-
clanker bot mint <label> [operator] [--json]
|
|
161
|
+
clanker whoami [--json] [--operator <label>] [--address 0x…] [--with-bots]
|
|
162
|
+
clanker operator mint <label> [--json] [--yes]
|
|
163
|
+
clanker operator transfer propose <label> <newOwner> [--yes]
|
|
164
|
+
clanker operator transfer accept <label> [--yes]
|
|
165
|
+
clanker bot mint <label> [operator] [--json] [--yes]
|
|
153
166
|
clanker bots [--json] [--operator <label>] [--address 0x…]
|
|
154
167
|
clanker bot status <label> [--json]
|
|
155
|
-
clanker bot revoke <label> [--json]
|
|
156
|
-
clanker bot rotate <label> <newKeyAddress> [--json]
|
|
168
|
+
clanker bot revoke <label> [--json] [--yes]
|
|
169
|
+
clanker bot rotate <label> <newKeyAddress> [--json] [--yes]
|
|
157
170
|
clanker init-openclaw
|
|
158
171
|
clanker chain up|deploy|mint-operator|mint-bot|rotate-bot-key|revoke-bot ...
|
|
159
172
|
clanker check mqtt <bot_id> <operator_id>
|
|
@@ -161,12 +174,12 @@ Usage:
|
|
|
161
174
|
|
|
162
175
|
Profile:
|
|
163
176
|
~/.clanker/config.json network preset (registry, RPC, broker URLs)
|
|
164
|
-
~/.clanker/operator.json label + owner + key pointer (never raw hex)
|
|
177
|
+
~/.clanker/operator.json label + owner + optional key pointer (never raw hex)
|
|
165
178
|
~/.clanker/keys/ bot keys (also written to ~/.openclaw/keys/)
|
|
166
179
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
Humans: \`clanker setup\` then \`clanker doctor\` / \`whoami\`.
|
|
181
|
+
Mutates print a plan and confirm unless --yes or --json.
|
|
182
|
+
whoami is fast by default; pass --with-bots to enrich child bots (or use \`clanker bots\`).
|
|
170
183
|
|
|
171
184
|
See docs/operator-cli.md.
|
|
172
185
|
`);
|
|
@@ -213,18 +226,20 @@ async function cmdWhoami(argv) {
|
|
|
213
226
|
let address;
|
|
214
227
|
let source;
|
|
215
228
|
let network;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
network = resolveForRead(argv);
|
|
219
|
-
address = getAddress(addressFlag);
|
|
220
|
-
source = "--address";
|
|
221
|
-
} else {
|
|
222
|
-
const resolved = resolveOperatorKey(argv);
|
|
229
|
+
try {
|
|
230
|
+
const resolved = resolveReadIdentity(argv);
|
|
223
231
|
address = resolved.address;
|
|
224
232
|
source = resolved.source;
|
|
225
233
|
network = resolved.network;
|
|
234
|
+
} catch (err) {
|
|
235
|
+
exitCliError({
|
|
236
|
+
error: err.message,
|
|
237
|
+
because: "whoami needs an owner address from --address, a key, or operator.json",
|
|
238
|
+
try: ["clanker setup", "clanker doctor", "clanker whoami --address 0x…"],
|
|
239
|
+
});
|
|
226
240
|
}
|
|
227
241
|
|
|
242
|
+
const withBots = hasFlag(argv, "--with-bots");
|
|
228
243
|
const pub = await publicClientFromRpc(network.rpc);
|
|
229
244
|
const preferred =
|
|
230
245
|
flagValue(argv, "--operator") ?? loadOperator(network.home)?.label ?? null;
|
|
@@ -237,9 +252,14 @@ async function cmdWhoami(argv) {
|
|
|
237
252
|
owner: getAddress(address),
|
|
238
253
|
});
|
|
239
254
|
if (resolved.error) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
255
|
+
exitCliError({
|
|
256
|
+
error: resolved.error,
|
|
257
|
+
because: "preferred operator label did not match this owner on-chain",
|
|
258
|
+
try: [
|
|
259
|
+
"clanker whoami --address 0x…",
|
|
260
|
+
"clanker setup --force # fix label/owner",
|
|
261
|
+
],
|
|
262
|
+
});
|
|
243
263
|
}
|
|
244
264
|
selected = [resolved.operator];
|
|
245
265
|
} else {
|
|
@@ -250,12 +270,14 @@ async function cmdWhoami(argv) {
|
|
|
250
270
|
});
|
|
251
271
|
}
|
|
252
272
|
|
|
253
|
-
|
|
254
|
-
op
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
273
|
+
if (withBots) {
|
|
274
|
+
for (const op of selected) {
|
|
275
|
+
op.bots = await findBotsByOperator(pub, {
|
|
276
|
+
registry: network.registry,
|
|
277
|
+
operatorId: op.id,
|
|
278
|
+
fromBlock: network.fromBlock,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
259
281
|
}
|
|
260
282
|
|
|
261
283
|
const data = {
|
|
@@ -271,31 +293,38 @@ async function cmdWhoami(argv) {
|
|
|
271
293
|
active: o.active,
|
|
272
294
|
registeredAt: o.registeredAt.toString(),
|
|
273
295
|
revokedAt: o.revokedAt.toString(),
|
|
274
|
-
bots:
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
296
|
+
bots: withBots
|
|
297
|
+
? (o.bots ?? []).map((b) => ({
|
|
298
|
+
label: b.label,
|
|
299
|
+
botKey: b.botKey,
|
|
300
|
+
active: b.active,
|
|
301
|
+
registeredAt: b.registeredAt.toString(),
|
|
302
|
+
revokedAt: b.revokedAt.toString(),
|
|
303
|
+
}))
|
|
304
|
+
: [],
|
|
281
305
|
})),
|
|
282
306
|
};
|
|
283
307
|
|
|
284
308
|
if (hasFlag(argv, "--json")) printJson(data);
|
|
285
|
-
else
|
|
309
|
+
else {
|
|
310
|
+
printHumanWhoami(data);
|
|
311
|
+
if (!withBots && data.operators.length) {
|
|
312
|
+
console.log(c.dim("(bots omitted — pass --with-bots or run clanker bots)"));
|
|
313
|
+
}
|
|
314
|
+
nextHint(["clanker bots", "clanker doctor"]);
|
|
315
|
+
}
|
|
286
316
|
}
|
|
287
317
|
|
|
288
318
|
async function cmdBots(argv) {
|
|
289
319
|
let address;
|
|
290
320
|
let network;
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
network = resolveForRead(argv);
|
|
294
|
-
address = getAddress(addressFlag);
|
|
295
|
-
} else {
|
|
296
|
-
const resolved = resolveOperatorKey(argv);
|
|
321
|
+
try {
|
|
322
|
+
const resolved = resolveReadIdentity(argv);
|
|
297
323
|
address = resolved.address;
|
|
298
324
|
network = resolved.network;
|
|
325
|
+
} catch (err) {
|
|
326
|
+
console.error(err.message);
|
|
327
|
+
process.exit(1);
|
|
299
328
|
}
|
|
300
329
|
const { label, pub } = await resolveOperatorLabel(argv, address, network);
|
|
301
330
|
const bots = await findBotsByOperator(pub, {
|
|
@@ -357,6 +386,27 @@ async function main() {
|
|
|
357
386
|
|
|
358
387
|
const repoRoot = findRepoRoot();
|
|
359
388
|
|
|
389
|
+
if (cmd === "setup") {
|
|
390
|
+
try {
|
|
391
|
+
await runSetup(rest);
|
|
392
|
+
} catch (err) {
|
|
393
|
+
exitCliError({
|
|
394
|
+
error: err.message,
|
|
395
|
+
because: "setup could not write a valid local profile",
|
|
396
|
+
try: [
|
|
397
|
+
"clanker setup --preset sepolia --operator org.you --address 0x… --yes --force",
|
|
398
|
+
"clanker doctor",
|
|
399
|
+
],
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (cmd === "doctor") {
|
|
406
|
+
const { exitCode } = await runDoctor(rest);
|
|
407
|
+
process.exit(exitCode);
|
|
408
|
+
}
|
|
409
|
+
|
|
360
410
|
if (cmd === "init") {
|
|
361
411
|
const preset = flagValue(rest, "--preset") ?? rest.find((a) => !a.startsWith("--"));
|
|
362
412
|
if (!preset || preset === "init") {
|
|
@@ -403,13 +453,38 @@ async function main() {
|
|
|
403
453
|
console.error("Usage: clanker operator mint <label>");
|
|
404
454
|
process.exit(1);
|
|
405
455
|
}
|
|
456
|
+
let planRows;
|
|
457
|
+
try {
|
|
458
|
+
const preview = resolveOperatorKey(flags);
|
|
459
|
+
planRows = [
|
|
460
|
+
["action", "registerOperator"],
|
|
461
|
+
["label", label],
|
|
462
|
+
["owner", preview.address],
|
|
463
|
+
["rpc", preview.network.rpc],
|
|
464
|
+
["registry", preview.network.registry ?? "(none)"],
|
|
465
|
+
["key", preview.source],
|
|
466
|
+
];
|
|
467
|
+
} catch (err) {
|
|
468
|
+
exitCliError({
|
|
469
|
+
error: err.message,
|
|
470
|
+
because: "operator mint needs a signing key on this network",
|
|
471
|
+
try: [
|
|
472
|
+
"export OPERATOR_PRIVATE_KEY=0x…",
|
|
473
|
+
"clanker operator mint " + label + " --key-file ~/.clanker/op.key --yes",
|
|
474
|
+
"clanker doctor",
|
|
475
|
+
],
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
const ok = await confirmPlan(flags, planRows, `Mint operator ${label}?`);
|
|
479
|
+
if (!ok) process.exit(0);
|
|
406
480
|
const result = await chainMintOperator(label, flags);
|
|
407
481
|
if (hasFlag(flags, "--json") || hasFlag(opArgv, "--json")) printJson(result);
|
|
408
482
|
else {
|
|
409
|
-
console.log(`Minted operator ${label}`);
|
|
483
|
+
console.log(c.green(`Minted operator ${label}`));
|
|
410
484
|
console.log(`owner: ${result.owner}`);
|
|
411
485
|
console.log(`tx: ${result.tx}`);
|
|
412
486
|
console.log(`Wrote ~/.clanker/operator.json`);
|
|
487
|
+
nextHint([`clanker bot mint <bot_label>`, "clanker whoami"]);
|
|
413
488
|
}
|
|
414
489
|
return;
|
|
415
490
|
}
|
|
@@ -421,9 +496,23 @@ async function main() {
|
|
|
421
496
|
console.error("Usage: clanker operator transfer propose <label> <newOwner>");
|
|
422
497
|
process.exit(1);
|
|
423
498
|
}
|
|
499
|
+
const ok = await confirmPlan(
|
|
500
|
+
flags,
|
|
501
|
+
[
|
|
502
|
+
["action", "proposeOperatorTransfer"],
|
|
503
|
+
["label", label],
|
|
504
|
+
["newOwner", getAddress(newOwner)],
|
|
505
|
+
],
|
|
506
|
+
`Propose transfer of ${label}?`,
|
|
507
|
+
);
|
|
508
|
+
if (!ok) process.exit(0);
|
|
424
509
|
const result = await chainProposeOperatorTransfer(label, getAddress(newOwner), flags);
|
|
425
510
|
if (hasFlag(flags, "--json")) printJson(result);
|
|
426
|
-
else
|
|
511
|
+
else {
|
|
512
|
+
console.log(c.green(`Proposed transfer of ${label} → ${newOwner}`));
|
|
513
|
+
console.log(`tx: ${result.tx}`);
|
|
514
|
+
nextHint([`clanker operator transfer accept ${label} # as new owner`]);
|
|
515
|
+
}
|
|
427
516
|
return;
|
|
428
517
|
}
|
|
429
518
|
if (action === "accept") {
|
|
@@ -431,9 +520,23 @@ async function main() {
|
|
|
431
520
|
console.error("Usage: clanker operator transfer accept <label>");
|
|
432
521
|
process.exit(1);
|
|
433
522
|
}
|
|
523
|
+
const ok = await confirmPlan(
|
|
524
|
+
flags,
|
|
525
|
+
[
|
|
526
|
+
["action", "acceptOperatorTransfer"],
|
|
527
|
+
["label", label],
|
|
528
|
+
],
|
|
529
|
+
`Accept transfer of ${label}?`,
|
|
530
|
+
);
|
|
531
|
+
if (!ok) process.exit(0);
|
|
434
532
|
const result = await chainAcceptOperatorTransfer(label, flags);
|
|
435
533
|
if (hasFlag(flags, "--json")) printJson(result);
|
|
436
|
-
else
|
|
534
|
+
else {
|
|
535
|
+
console.log(c.green(`Accepted transfer of ${label}`));
|
|
536
|
+
console.log(`owner: ${result.owner}`);
|
|
537
|
+
console.log(`tx: ${result.tx}`);
|
|
538
|
+
nextHint(["clanker whoami", "clanker bots"]);
|
|
539
|
+
}
|
|
437
540
|
return;
|
|
438
541
|
}
|
|
439
542
|
console.error("Usage: clanker operator transfer propose|accept ...");
|
|
@@ -473,20 +576,64 @@ async function main() {
|
|
|
473
576
|
}
|
|
474
577
|
let operatorLabel = operatorArg ?? flagValue(flags, "--operator") ?? null;
|
|
475
578
|
if (!operatorLabel) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
579
|
+
try {
|
|
580
|
+
const { address, network } = resolveOperatorKey(flags);
|
|
581
|
+
const inferred = await resolveOperatorLabel(flags, address, network);
|
|
582
|
+
operatorLabel = inferred.label;
|
|
583
|
+
} catch (err) {
|
|
584
|
+
exitCliError({
|
|
585
|
+
error: err.message,
|
|
586
|
+
because: "bot mint needs an operator label or a resolvable signing key",
|
|
587
|
+
try: [
|
|
588
|
+
`clanker bot mint ${botLabel} <operator_label> --yes`,
|
|
589
|
+
"clanker setup",
|
|
590
|
+
],
|
|
591
|
+
});
|
|
592
|
+
}
|
|
479
593
|
}
|
|
594
|
+
const ok = await confirmPlan(
|
|
595
|
+
flags,
|
|
596
|
+
[
|
|
597
|
+
["action", "registerBot"],
|
|
598
|
+
["bot", botLabel],
|
|
599
|
+
["operator", operatorLabel],
|
|
600
|
+
],
|
|
601
|
+
`Mint bot ${botLabel} under ${operatorLabel}?`,
|
|
602
|
+
);
|
|
603
|
+
if (!ok) process.exit(0);
|
|
480
604
|
const result = await chainMintBot(botLabel, operatorLabel, flags);
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
605
|
+
const mqtt = result.channels_mqtt ?? {};
|
|
606
|
+
const wire = wireOpenClawMqtt({
|
|
607
|
+
botId: botLabel,
|
|
608
|
+
operatorId: operatorLabel,
|
|
609
|
+
network: {
|
|
610
|
+
rpc: mqtt.chainRpcUrl,
|
|
611
|
+
registry: mqtt.registryAddress,
|
|
612
|
+
brokerUrl: mqtt.brokerUrl,
|
|
613
|
+
mqttAuthServiceUrl: mqtt.mqttAuthServiceUrl,
|
|
614
|
+
},
|
|
615
|
+
keyPath: result.key_path,
|
|
616
|
+
});
|
|
617
|
+
if (hasFlag(flags, "--json")) {
|
|
618
|
+
printJson({ ...result, openclaw: wire });
|
|
619
|
+
} else {
|
|
620
|
+
console.log(c.green(`Minted bot ${botLabel} under ${operatorLabel}`));
|
|
484
621
|
console.log(`botKey: ${result.bot_key}`);
|
|
485
622
|
console.log(`key file: ${result.key_path}`);
|
|
486
623
|
console.log(`also: ${result.clanker_key_path}`);
|
|
487
624
|
console.log(`tx: ${result.tx}`);
|
|
488
|
-
console.log(
|
|
489
|
-
|
|
625
|
+
console.log(
|
|
626
|
+
wire.created
|
|
627
|
+
? c.green(`Wrote ${wire.path}`)
|
|
628
|
+
: c.green(`Updated channels.mqtt in ${wire.path}`),
|
|
629
|
+
);
|
|
630
|
+
nextHint(
|
|
631
|
+
hubConnectChecklist({
|
|
632
|
+
botId: botLabel,
|
|
633
|
+
channelsMqtt: wire.channelsMqtt,
|
|
634
|
+
pluginPin: wire.pluginPin,
|
|
635
|
+
}),
|
|
636
|
+
);
|
|
490
637
|
}
|
|
491
638
|
return;
|
|
492
639
|
}
|
|
@@ -497,9 +644,22 @@ async function main() {
|
|
|
497
644
|
console.error("Usage: clanker bot revoke <label>");
|
|
498
645
|
process.exit(1);
|
|
499
646
|
}
|
|
647
|
+
const ok = await confirmPlan(
|
|
648
|
+
flags,
|
|
649
|
+
[
|
|
650
|
+
["action", "revokeBot"],
|
|
651
|
+
["bot", botLabel],
|
|
652
|
+
],
|
|
653
|
+
`Revoke bot ${botLabel}?`,
|
|
654
|
+
);
|
|
655
|
+
if (!ok) process.exit(0);
|
|
500
656
|
const result = await chainRevokeBot(botLabel, flags);
|
|
501
657
|
if (hasFlag(flags, "--json")) printJson(result);
|
|
502
|
-
else
|
|
658
|
+
else {
|
|
659
|
+
console.log(c.yellow(`Revoked ${botLabel}`));
|
|
660
|
+
console.log(`tx: ${result.tx}`);
|
|
661
|
+
nextHint(["clanker bots", "clanker bot status " + botLabel]);
|
|
662
|
+
}
|
|
503
663
|
return;
|
|
504
664
|
}
|
|
505
665
|
|
|
@@ -509,9 +669,23 @@ async function main() {
|
|
|
509
669
|
console.error("Usage: clanker bot rotate <label> <newKeyAddress>");
|
|
510
670
|
process.exit(1);
|
|
511
671
|
}
|
|
672
|
+
const ok = await confirmPlan(
|
|
673
|
+
flags,
|
|
674
|
+
[
|
|
675
|
+
["action", "rotateBotKey"],
|
|
676
|
+
["bot", botLabel],
|
|
677
|
+
["newKey", getAddress(newKey)],
|
|
678
|
+
],
|
|
679
|
+
`Rotate key for ${botLabel}?`,
|
|
680
|
+
);
|
|
681
|
+
if (!ok) process.exit(0);
|
|
512
682
|
const result = await chainRotateBotKey(botLabel, getAddress(newKey), flags);
|
|
513
683
|
if (hasFlag(flags, "--json")) printJson(result);
|
|
514
|
-
else
|
|
684
|
+
else {
|
|
685
|
+
console.log(c.green(`Rotated ${botLabel} → ${newKey}`));
|
|
686
|
+
console.log(`tx: ${result.tx}`);
|
|
687
|
+
nextHint(["Update ~/.openclaw/keys/" + botLabel + ".key", "clanker bot status " + botLabel]);
|
|
688
|
+
}
|
|
515
689
|
return;
|
|
516
690
|
}
|
|
517
691
|
|
|
@@ -717,22 +891,6 @@ async function main() {
|
|
|
717
891
|
}
|
|
718
892
|
|
|
719
893
|
if (cmd === "init-openclaw") {
|
|
720
|
-
const home = os.homedir();
|
|
721
|
-
const openclawDir = join(home, ".openclaw");
|
|
722
|
-
const cfgPath = join(openclawDir, "openclaw.json");
|
|
723
|
-
if (!existsSync(openclawDir)) {
|
|
724
|
-
mkdirSync(openclawDir, { recursive: true });
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
if (existsSync(cfgPath)) {
|
|
728
|
-
console.log(`${cfgPath} already exists.`);
|
|
729
|
-
console.log(
|
|
730
|
-
'Ensure plugins.enabled includes "mqtt" and "mqtt-tools", and channels.mqtt has botId, operatorId, brokerUrl, chainRpcUrl, registryAddress.',
|
|
731
|
-
);
|
|
732
|
-
console.log("See SETUP.md and docs/operator-cli.md.");
|
|
733
|
-
process.exit(0);
|
|
734
|
-
}
|
|
735
|
-
|
|
736
894
|
const profile = loadConfig();
|
|
737
895
|
const operator = loadOperator();
|
|
738
896
|
// No profile: local defaults only — do not mix Sepolia registry with localhost MQTT.
|
|
@@ -750,27 +908,21 @@ async function main() {
|
|
|
750
908
|
mqttAuthServiceUrl: "http://localhost:9090",
|
|
751
909
|
};
|
|
752
910
|
|
|
753
|
-
const
|
|
911
|
+
const wire = wireOpenClawMqtt({
|
|
754
912
|
botId: "openclaw.your-bot.local",
|
|
755
913
|
operatorId: operator?.label ?? "org.openclaw.your-operator",
|
|
756
914
|
network,
|
|
757
915
|
});
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
},
|
|
769
|
-
};
|
|
770
|
-
writeFileSync(cfgPath, JSON.stringify(cfg, null, 2), "utf8");
|
|
771
|
-
console.log(`Created ${cfgPath} with mqtt + mqtt-tools from ${profile ? "active" : "default"} preset.`);
|
|
772
|
-
console.log("Next: clanker bot mint <label>, then set channels.mqtt.botId / operatorId.");
|
|
773
|
-
console.log("See docs/operator-cli.md and SETUP.md.");
|
|
916
|
+
console.log(
|
|
917
|
+
wire.created
|
|
918
|
+
? `Created ${wire.path} with mqtt + mqtt-tools from ${profile ? "active" : "default"} preset.`
|
|
919
|
+
: `Updated channels.mqtt in ${wire.path} (plugins mqtt + mqtt-tools ensured).`,
|
|
920
|
+
);
|
|
921
|
+
nextHint([
|
|
922
|
+
"clanker bot mint <label>",
|
|
923
|
+
"Then channels.mqtt.botId / operatorId / privateKeyFile update automatically",
|
|
924
|
+
"See docs/operator-cli.md and docs/closed-beta-invite.md",
|
|
925
|
+
]);
|
|
774
926
|
process.exit(0);
|
|
775
927
|
}
|
|
776
928
|
|