@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/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) or the browser door that created this address. A read-only profile can still run whoami, bots, fund, and doctor.";
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 a signing key|Anvil account #0|Key file not found|Profile keyFile/i.test(
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
- "Attach an existing owner address (/join or any 0x), or create ~/.clanker/op.key. Mint needs test ETH later.",
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: "__paste__",
557
+ initialValue: "__login__",
551
558
  }),
552
559
  );
553
560
 
554
561
  let attachReadOnly = false;
555
- if (pick === "__generate__") {
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 = buildKeyPointer({ keyFile, keyEnv, skipKey, env });
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 (!key) {
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.12-1",
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
  },