@clanker-chain/clanker-cli 2026.9.12-1 → 2026.9.13
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/chain-identity.mjs +40 -62
- package/bin/clanker.mjs +48 -10
- package/lib/doctor.mjs +16 -8
- package/lib/login.mjs +200 -0
- package/lib/operator-signer.mjs +284 -0
- package/lib/pair.mjs +8 -20
- package/lib/privy-client.mjs +419 -0
- package/lib/privy-constants.mjs +20 -0
- package/lib/privy-hpke.mjs +101 -0
- package/lib/privy-session.mjs +151 -0
- package/lib/profile.mjs +1 -1
- package/lib/resolve.mjs +3 -2
- package/lib/setup.mjs +34 -8
- package/package.json +6 -1
package/lib/resolve.mjs
CHANGED
|
@@ -80,7 +80,8 @@ export function keyPointerFromSource(opts) {
|
|
|
80
80
|
|
|
81
81
|
/** Honest error when mint/pair/rotate/transfer have no owner signer. */
|
|
82
82
|
export const OWNER_SIGNER_REQUIRED =
|
|
83
|
-
"Owner actions need a signing key (--key-file / OPERATOR_PRIVATE_KEY)
|
|
83
|
+
"Owner actions need clanker login (email vault), or a signing key (--key-file / OPERATOR_PRIVATE_KEY). " +
|
|
84
|
+
"A read-only profile can still run whoami, bots, fund, and doctor.";
|
|
84
85
|
|
|
85
86
|
/**
|
|
86
87
|
* Resolve the operator signing key with Anvil guard.
|
|
@@ -217,7 +218,7 @@ export function resolveReadIdentity(argv = [], opts = {}) {
|
|
|
217
218
|
} catch (err) {
|
|
218
219
|
const msg = err?.message ?? String(err);
|
|
219
220
|
if (
|
|
220
|
-
!/private key required|Owner actions need
|
|
221
|
+
!/private key required|Owner actions need|clanker login|Anvil account #0|Key file not found|Profile keyFile/i.test(
|
|
221
222
|
msg,
|
|
222
223
|
)
|
|
223
224
|
) {
|
package/lib/setup.mjs
CHANGED
|
@@ -45,6 +45,7 @@ import {
|
|
|
45
45
|
generateOperatorKeyFile,
|
|
46
46
|
} from "./operator-key.mjs";
|
|
47
47
|
import { wireOpenClawMqtt } from "./openclaw-wire.mjs";
|
|
48
|
+
import { runLogin } from "./login.mjs";
|
|
48
49
|
import { c, nextHint } from "./ui.mjs";
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -405,7 +406,7 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
405
406
|
);
|
|
406
407
|
clack.log.message(
|
|
407
408
|
c.dim(
|
|
408
|
-
"
|
|
409
|
+
"Sign in with email (recommended), attach an existing 0x, or create ~/.clanker/op.key.",
|
|
409
410
|
),
|
|
410
411
|
);
|
|
411
412
|
clack.log.message(c.dim(`Profile: ${home}`));
|
|
@@ -466,6 +467,7 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
466
467
|
let address = flags.address ?? null;
|
|
467
468
|
let foundryAccountUsed = null;
|
|
468
469
|
let generatedKeyFile = null;
|
|
470
|
+
let privyKeyPointer = null;
|
|
469
471
|
if (!address && flags.generateKey) {
|
|
470
472
|
const dest = flags.keyFile || defaultOperatorKeyPath(home);
|
|
471
473
|
let forceGen = flags.force;
|
|
@@ -511,15 +513,20 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
511
513
|
}
|
|
512
514
|
if (!address) {
|
|
513
515
|
const options = [
|
|
516
|
+
{
|
|
517
|
+
value: "__login__",
|
|
518
|
+
label: "Sign in (email — recommended)",
|
|
519
|
+
hint: "Privy vault — no op.key on disk",
|
|
520
|
+
},
|
|
514
521
|
{
|
|
515
522
|
value: "__paste__",
|
|
516
523
|
label: "I already have an owner address",
|
|
517
|
-
hint: "/join or any 0x — usually read-only",
|
|
524
|
+
hint: "/join or any 0x — usually read-only until login",
|
|
518
525
|
},
|
|
519
526
|
{
|
|
520
527
|
value: "__generate__",
|
|
521
528
|
label: "Create a new operator key for me",
|
|
522
|
-
hint: "writes ~/.clanker/op.key",
|
|
529
|
+
hint: "writes ~/.clanker/op.key (self-custody)",
|
|
523
530
|
},
|
|
524
531
|
{
|
|
525
532
|
value: "__keyfile__",
|
|
@@ -547,12 +554,22 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
547
554
|
await clack.select({
|
|
548
555
|
message: "How do you want to set your operator identity?",
|
|
549
556
|
options,
|
|
550
|
-
initialValue: "
|
|
557
|
+
initialValue: "__login__",
|
|
551
558
|
}),
|
|
552
559
|
);
|
|
553
560
|
|
|
554
561
|
let attachReadOnly = false;
|
|
555
|
-
if (pick === "
|
|
562
|
+
if (pick === "__login__") {
|
|
563
|
+
clack.log.step("Opening browser for clanker login…");
|
|
564
|
+
const logged = await runLogin([], {
|
|
565
|
+
home,
|
|
566
|
+
env,
|
|
567
|
+
});
|
|
568
|
+
address = logged.address;
|
|
569
|
+
privyKeyPointer = { type: "privy", value: logged.walletId };
|
|
570
|
+
flags.skipKey = true;
|
|
571
|
+
clack.log.success(`Signed in as ${address}`);
|
|
572
|
+
} else if (pick === "__generate__") {
|
|
556
573
|
const dest = defaultOperatorKeyPath(home);
|
|
557
574
|
let forceGen = flags.force;
|
|
558
575
|
if (existsSync(dest) && !forceGen) {
|
|
@@ -722,7 +739,9 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
722
739
|
}
|
|
723
740
|
}
|
|
724
741
|
|
|
725
|
-
const key =
|
|
742
|
+
const key =
|
|
743
|
+
privyKeyPointer ||
|
|
744
|
+
buildKeyPointer({ keyFile, keyEnv, skipKey, env });
|
|
726
745
|
if (key?.type === "keyFile") {
|
|
727
746
|
const fromKey = getAddress(addressFromKeyFile(key.value));
|
|
728
747
|
if (fromKey !== address) {
|
|
@@ -767,11 +786,18 @@ export async function runSetupInteractive(argv, opts = {}) {
|
|
|
767
786
|
await finishSetupResult(result, { ...flags, operator: label }, opts);
|
|
768
787
|
|
|
769
788
|
clack.outro(c.green(`Wrote ${result.configPath}\nWrote ${result.operatorPath}`));
|
|
770
|
-
if (
|
|
789
|
+
if (privyKeyPointer) {
|
|
790
|
+
nextHint([
|
|
791
|
+
"clanker fund",
|
|
792
|
+
"clanker whoami",
|
|
793
|
+
"clanker pair add <peer> --yes",
|
|
794
|
+
"clanker operator mint <label> --yes # if not minted yet",
|
|
795
|
+
]);
|
|
796
|
+
} else if (!key) {
|
|
771
797
|
nextHint([
|
|
798
|
+
"clanker login # to enable mint/pair with the email vault",
|
|
772
799
|
"clanker fund",
|
|
773
800
|
"clanker whoami",
|
|
774
|
-
"mint/pair/rotate need a signing key or stay on /join",
|
|
775
801
|
]);
|
|
776
802
|
} else if (preset === "sepolia" && generatedKeyFile) {
|
|
777
803
|
nextHint(consumerFundHints({ address, label }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clanker-chain/clanker-cli",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.13",
|
|
4
4
|
"description": "CLI for wiring clanker-chain identity and MQTT into OpenClaw and other agentic stacks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -24,6 +24,11 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@clack/prompts": "^1.8.0",
|
|
27
|
+
"@hpke/chacha20poly1305": "^1.8.0",
|
|
28
|
+
"@hpke/core": "^1.9.0",
|
|
29
|
+
"@noble/curves": "^1.9.7",
|
|
30
|
+
"@noble/hashes": "^1.8.0",
|
|
31
|
+
"canonicalize": "^2.1.0",
|
|
27
32
|
"picocolors": "^1.1.1",
|
|
28
33
|
"viem": "^2.56.3"
|
|
29
34
|
},
|