clawntenna 0.12.8 → 0.12.9

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.
@@ -3,7 +3,7 @@ import {
3
3
  CONFIG_DIR,
4
4
  loadCredentials,
5
5
  output
6
- } from "./chunk-AQHFWEZF.js";
6
+ } from "./chunk-S2IWR2YO.js";
7
7
 
8
8
  // src/cli/state.ts
9
9
  import { existsSync, mkdirSync, writeFileSync } from "fs";
@@ -21,7 +21,7 @@ function initState(address) {
21
21
  startedAt: now,
22
22
  lastScanAt: now,
23
23
  mode: "active",
24
- skillVersion: "0.12.8",
24
+ skillVersion: "0.12.9",
25
25
  lastSkillCheck: now
26
26
  },
27
27
  chains: {
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  CONFIG_DIR
4
- } from "./chunk-AQHFWEZF.js";
4
+ } from "./chunk-S2IWR2YO.js";
5
5
 
6
6
  // src/cli/skill.ts
7
7
  import { readFileSync, existsSync, copyFileSync, mkdirSync } from "fs";
@@ -4462,10 +4462,6 @@ var Clawntenna = class _Clawntenna {
4462
4462
  async registerPublicKey() {
4463
4463
  this.requireSigner();
4464
4464
  if (!this.ecdhPublicKey) throw new Error("ECDH key not derived yet");
4465
- const hasKey = await this.keyManager.hasPublicKey(this.requireAddress());
4466
- if (hasKey) {
4467
- throw new Error("Public key already registered on-chain");
4468
- }
4469
4465
  return this.keyManager.registerPublicKey(this.ecdhPublicKey);
4470
4466
  }
4471
4467
  /**
@@ -5006,8 +5002,8 @@ function validateKeyAddress(creds) {
5006
5002
  }
5007
5003
  }
5008
5004
  async function runPostInit(address) {
5009
- const { initState } = await import("./state-73B57RGU.js");
5010
- const { copySkillFiles } = await import("./skill-HV2NNR3H.js");
5005
+ const { initState } = await import("./state-IT53LF3J.js");
5006
+ const { copySkillFiles } = await import("./skill-CTQZ7YJE.js");
5011
5007
  const stateResult = initState(address);
5012
5008
  const skillResult = copySkillFiles();
5013
5009
  return { stateResult, skillResult };
@@ -5160,7 +5156,8 @@ function parseCommonFlags(flags) {
5160
5156
  chain: flags.chain ?? "base",
5161
5157
  key: flags.key,
5162
5158
  rpc: flags.rpc,
5163
- json: flags.json === "true"
5159
+ json: flags.json === "true",
5160
+ force: flags.force === "true"
5164
5161
  };
5165
5162
  }
5166
5163
  function loadClient(flags, requireWallet = true) {
package/dist/cli/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  stateInit
4
- } from "./chunk-AIISNOCB.js";
4
+ } from "./chunk-EOKSFPRZ.js";
5
5
  import {
6
6
  showHeartbeat,
7
7
  showSkill,
8
8
  showSkillJson
9
- } from "./chunk-AK26RTP5.js";
9
+ } from "./chunk-FDS4E5ME.js";
10
10
  import {
11
11
  REGISTRY_ABI,
12
12
  chainIdForCredentials,
@@ -17,7 +17,7 @@ import {
17
17
  outputError,
18
18
  parseCommonFlags,
19
19
  saveCredentials
20
- } from "./chunk-AQHFWEZF.js";
20
+ } from "./chunk-S2IWR2YO.js";
21
21
 
22
22
  // src/cli/send.ts
23
23
  async function send(topicId, message, flags) {
@@ -792,6 +792,13 @@ async function keysRegister(flags) {
792
792
  const creds = loadCredentials();
793
793
  const chainId = chainIdForCredentials(flags.chain);
794
794
  const ecdhCreds = creds?.chains[chainId]?.ecdh;
795
+ const hadExistingRegistration = await client.hasPublicKey(client.address);
796
+ if (hadExistingRegistration && !flags.force) {
797
+ outputError(
798
+ "ECDH public key already registered on-chain. Re-run with --force to update it. Warning: existing private-topic key grants encrypted to the old public key may need to be regranted.",
799
+ json
800
+ );
801
+ }
795
802
  if (ecdhCreds?.privateKey) {
796
803
  client.loadECDHKeypair(ecdhCreds.privateKey);
797
804
  } else {
@@ -799,21 +806,11 @@ async function keysRegister(flags) {
799
806
  await client.deriveECDHFromWallet();
800
807
  }
801
808
  if (!json) console.log("Registering ECDH public key on-chain...");
802
- let txHash = null;
803
- let blockNumber;
804
- let registeredOnChain = false;
805
- try {
806
- const tx = await client.registerPublicKey();
807
- const receipt = await tx.wait();
808
- txHash = tx.hash;
809
- blockNumber = receipt?.blockNumber;
810
- registeredOnChain = true;
811
- } catch (error) {
812
- if (!(error instanceof Error) || !error.message.includes("Public key already registered on-chain")) {
813
- throw error;
814
- }
815
- registeredOnChain = true;
816
- }
809
+ const tx = await client.registerPublicKey();
810
+ const receipt = await tx.wait();
811
+ const txHash = tx.hash;
812
+ const blockNumber = receipt?.blockNumber;
813
+ const registeredOnChain = true;
817
814
  const keypair = client.getECDHKeypairHex();
818
815
  if (creds && keypair) {
819
816
  if (!creds.chains[chainId]) {
@@ -831,13 +828,19 @@ async function keysRegister(flags) {
831
828
  saveCredentials(creds);
832
829
  }
833
830
  if (json) {
834
- output({ txHash, blockNumber, chain: flags.chain, registered: registeredOnChain }, true);
831
+ output({
832
+ txHash,
833
+ blockNumber,
834
+ chain: flags.chain,
835
+ registered: registeredOnChain,
836
+ updated: hadExistingRegistration
837
+ }, true);
835
838
  } else {
836
- if (txHash) {
837
- console.log(`TX: ${txHash}`);
838
- console.log(`Confirmed in block ${blockNumber}`);
839
- } else {
840
- console.log("ECDH public key was already registered on-chain.");
839
+ console.log(`TX: ${txHash}`);
840
+ console.log(`Confirmed in block ${blockNumber}`);
841
+ if (hadExistingRegistration) {
842
+ console.log("ECDH public key updated on-chain.");
843
+ console.log("Note: existing private-topic key grants encrypted to the old public key may need to be regranted.");
841
844
  }
842
845
  }
843
846
  }
@@ -1411,7 +1414,7 @@ async function resolveTopicId(client, {
1411
1414
  }
1412
1415
 
1413
1416
  // src/cli/index.ts
1414
- var VERSION = "0.12.8";
1417
+ var VERSION = "0.12.9";
1415
1418
  var HELP = `
1416
1419
  clawntenna v${VERSION}
1417
1420
  Encrypted on-chain coordination for wallets, apps, and agents
@@ -1483,7 +1486,7 @@ var HELP = `
1483
1486
  schema publish <schemaId> "<body>" Publish new schema version
1484
1487
 
1485
1488
  ECDH / Private Topics:
1486
- keys register Register ECDH public key on-chain
1489
+ keys register [--force] Register ECDH public key on-chain
1487
1490
  keys check <address> Check if address has public key
1488
1491
  keys grant <topicId> <address> Grant key access to user
1489
1492
  keys revoke <topicId> <address> Revoke key access
@@ -1540,14 +1543,68 @@ var HELP = `
1540
1543
  Docs: https://clawntenna.com/docs
1541
1544
  `;
1542
1545
  var COMMAND_HELP = {
1546
+ init: "Usage: clawntenna init\n Creates wallet credentials, state, and synced skill files.",
1547
+ whoami: "Usage: clawntenna whoami [appId]\nOptions: --chain <name> --json\n Shows wallet, balance, nickname/member/agent info, and ECDH status.",
1543
1548
  send: 'Usage: clawntenna send <topicId> "<message>"\n clawntenna send --app "<app>" --topic "<topic>" "<message>"\nOptions: --reply-to <txHash> --mentions <addr,...> --no-wait --json --chain <name>',
1544
1549
  read: 'Usage: clawntenna read <topicId>\n clawntenna read --app "<app>" --topic "<topic>"\nOptions: --limit <N> --json --chain <name>',
1545
1550
  subscribe: 'Usage: clawntenna subscribe <topicId>\n clawntenna subscribe --app "<app>" --topic "<topic>"\nOptions: --json --chain <name>',
1546
1551
  "app info": 'Usage: clawntenna app info <appId>\n clawntenna app info --app "<name>"',
1547
1552
  "app create": 'Usage: clawntenna app create --name "<name>" [--description "<desc>"] [--url <url>] [--public]\n clawntenna app create "<name>" "<desc>" [--url <url>] [--public]',
1553
+ "app update-url": 'Usage: clawntenna app update-url <appId> "<url>"',
1554
+ "app transfer-ownership": "Usage: clawntenna app transfer-ownership <appId> <newOwner>",
1555
+ "app accept-ownership": "Usage: clawntenna app accept-ownership <appId>",
1556
+ "app cancel-transfer": "Usage: clawntenna app cancel-transfer <appId>",
1557
+ "app pending-owner": "Usage: clawntenna app pending-owner <appId>",
1548
1558
  "topic info": 'Usage: clawntenna topic info <topicId>\n clawntenna topic info --app "<app>" --topic "<name>"',
1549
1559
  "topic create": 'Usage: clawntenna topic create --app "<app>" --name "<name>" [--description "<desc>"] [--access public|limited|private]\n clawntenna topic create <appId> "<name>" "<desc>" [--access public|limited|private]',
1550
- topics: 'Usage: clawntenna topics <appId>\n clawntenna topics --app "<name>"'
1560
+ "nickname set": 'Usage: clawntenna nickname set <appId> "<name>"',
1561
+ "nickname get": "Usage: clawntenna nickname get <appId> <address>",
1562
+ "nickname clear": "Usage: clawntenna nickname clear <appId>",
1563
+ members: "Usage: clawntenna members <appId>",
1564
+ "member info": "Usage: clawntenna member info <appId> <address>",
1565
+ "member add": 'Usage: clawntenna member add <appId> <address> "<nick>" [--roles N]',
1566
+ "member remove": "Usage: clawntenna member remove <appId> <address>",
1567
+ "member roles": "Usage: clawntenna member roles <appId> <address> <roles>",
1568
+ "permission set": "Usage: clawntenna permission set <topicId> <address> <level>",
1569
+ "permission get": "Usage: clawntenna permission get <topicId> <address>",
1570
+ "access check": "Usage: clawntenna access check <topicId> <address>",
1571
+ "agent register": "Usage: clawntenna agent register <appId> <tokenId>",
1572
+ "agent clear": "Usage: clawntenna agent clear <appId>",
1573
+ "agent info": "Usage: clawntenna agent info <appId> <address>",
1574
+ "schema create": 'Usage: clawntenna schema create <appId> "<name>" "<desc>" "<body>"',
1575
+ "schema info": "Usage: clawntenna schema info <schemaId>",
1576
+ "schema list": "Usage: clawntenna schema list <appId>",
1577
+ "schema bind": "Usage: clawntenna schema bind <topicId> <schemaId> <version>",
1578
+ "schema unbind": "Usage: clawntenna schema unbind <topicId>",
1579
+ "schema topic": "Usage: clawntenna schema topic <topicId>",
1580
+ "schema version": "Usage: clawntenna schema version <schemaId> <version>",
1581
+ "schema publish": 'Usage: clawntenna schema publish <schemaId> "<body>"',
1582
+ "keys register": "Usage: clawntenna keys register [--force]\n Registers your ECDH public key. Use --force to overwrite an existing on-chain key.",
1583
+ "keys check": "Usage: clawntenna keys check <address>",
1584
+ "keys grant": "Usage: clawntenna keys grant <topicId> <address>",
1585
+ "keys revoke": "Usage: clawntenna keys revoke <topicId> <address>",
1586
+ "keys rotate": "Usage: clawntenna keys rotate <topicId>",
1587
+ "keys has": "Usage: clawntenna keys has <topicId> <address>",
1588
+ "keys pending": "Usage: clawntenna keys pending <topicId>",
1589
+ topics: 'Usage: clawntenna topics <appId>\n clawntenna topics --app "<name>"',
1590
+ "fee topic-creation": "Usage: clawntenna fee topic-creation set <appId> <token> <amount>",
1591
+ "fee message": "Usage: clawntenna fee message set <topicId> <token> <amount>\n clawntenna fee message get <topicId>",
1592
+ "escrow inbox": "Usage: clawntenna escrow inbox <topicId>",
1593
+ "escrow enable": "Usage: clawntenna escrow enable <topicId> <timeout>",
1594
+ "escrow disable": "Usage: clawntenna escrow disable <topicId>",
1595
+ "escrow status": "Usage: clawntenna escrow status <topicId>",
1596
+ "escrow deposits": "Usage: clawntenna escrow deposits <topicId>",
1597
+ "escrow deposit": "Usage: clawntenna escrow deposit <depositId>",
1598
+ "escrow respond": "Usage: clawntenna escrow respond <topicId> <id1> [id2...] --payload 0x...",
1599
+ "escrow release": "Usage: clawntenna escrow release <depositId> [--ref N]",
1600
+ "escrow release-batch": "Usage: clawntenna escrow release-batch <id1> <id2> ...",
1601
+ "escrow refund": "Usage: clawntenna escrow refund <depositId>",
1602
+ "escrow refund-batch": "Usage: clawntenna escrow refund-batch <id1> <id2> ...",
1603
+ "escrow stats": "Usage: clawntenna escrow stats <address>",
1604
+ skill: "Usage: clawntenna skill\n Prints skill.md.",
1605
+ heartbeat: "Usage: clawntenna heartbeat\n Prints heartbeat.md.",
1606
+ "skill-json": "Usage: clawntenna skill-json\n Prints skill.json.",
1607
+ "state init": "Usage: clawntenna state init\n Initializes ~/.config/clawntenna/state.json."
1551
1608
  };
1552
1609
  function printCommandHelp(command, subcommand) {
1553
1610
  const key = subcommand ? `${command} ${subcommand}` : command;
@@ -1569,7 +1626,7 @@ function parseArgs(argv) {
1569
1626
  flags[key] = "true";
1570
1627
  i++;
1571
1628
  }
1572
- } else if (arg === "-h") {
1629
+ } else if (arg === "-h" || arg === "help") {
1573
1630
  flags["help"] = "true";
1574
1631
  i++;
1575
1632
  } else if (arg === "-v") {
@@ -1585,6 +1642,15 @@ function parseArgs(argv) {
1585
1642
  async function main() {
1586
1643
  const { command, args, flags } = parseArgs(process.argv.slice(2));
1587
1644
  const json = flags.json === "true";
1645
+ if (command === "help") {
1646
+ if (args.length === 0) {
1647
+ console.log(HELP);
1648
+ return;
1649
+ }
1650
+ const subcommand = args[1];
1651
+ printCommandHelp(args[0], subcommand);
1652
+ return;
1653
+ }
1588
1654
  if (flags.version) {
1589
1655
  console.log(VERSION);
1590
1656
  return;
@@ -1597,9 +1663,17 @@ async function main() {
1597
1663
  try {
1598
1664
  switch (command) {
1599
1665
  case "init":
1666
+ if (flags.help) {
1667
+ printCommandHelp("init");
1668
+ return;
1669
+ }
1600
1670
  await init(json);
1601
1671
  break;
1602
1672
  case "whoami": {
1673
+ if (flags.help) {
1674
+ printCommandHelp("whoami");
1675
+ return;
1676
+ }
1603
1677
  const appId = args[0] ? parseInt(args[0], 10) : null;
1604
1678
  await whoami(appId, cf);
1605
1679
  break;
@@ -1765,6 +1839,10 @@ async function main() {
1765
1839
  // --- Nicknames ---
1766
1840
  case "nickname": {
1767
1841
  const sub = args[0];
1842
+ if (flags.help) {
1843
+ printCommandHelp("nickname", sub);
1844
+ return;
1845
+ }
1768
1846
  if (sub === "set") {
1769
1847
  const appId = parseInt(args[1], 10);
1770
1848
  const name = args[2];
@@ -1786,6 +1864,10 @@ async function main() {
1786
1864
  }
1787
1865
  // --- Members ---
1788
1866
  case "members": {
1867
+ if (flags.help) {
1868
+ printCommandHelp("members");
1869
+ return;
1870
+ }
1789
1871
  const appId = parseInt(args[0], 10);
1790
1872
  if (isNaN(appId)) outputError("Usage: clawntenna members <appId>", json);
1791
1873
  await membersList(appId, cf);
@@ -1793,6 +1875,10 @@ async function main() {
1793
1875
  }
1794
1876
  case "member": {
1795
1877
  const sub = args[0];
1878
+ if (flags.help) {
1879
+ printCommandHelp("member", sub);
1880
+ return;
1881
+ }
1796
1882
  if (sub === "info") {
1797
1883
  const appId = parseInt(args[1], 10);
1798
1884
  const address = args[2];
@@ -1824,6 +1910,10 @@ async function main() {
1824
1910
  // --- Permissions ---
1825
1911
  case "permission": {
1826
1912
  const sub = args[0];
1913
+ if (flags.help) {
1914
+ printCommandHelp("permission", sub);
1915
+ return;
1916
+ }
1827
1917
  if (sub === "set") {
1828
1918
  const topicId = parseInt(args[1], 10);
1829
1919
  const address = args[2];
@@ -1842,6 +1932,10 @@ async function main() {
1842
1932
  }
1843
1933
  case "access": {
1844
1934
  const sub = args[0];
1935
+ if (flags.help) {
1936
+ printCommandHelp("access", sub);
1937
+ return;
1938
+ }
1845
1939
  if (sub === "check") {
1846
1940
  const topicId = parseInt(args[1], 10);
1847
1941
  const address = args[2];
@@ -1855,6 +1949,10 @@ async function main() {
1855
1949
  // --- Agent Identity ---
1856
1950
  case "agent": {
1857
1951
  const sub = args[0];
1952
+ if (flags.help) {
1953
+ printCommandHelp("agent", sub);
1954
+ return;
1955
+ }
1858
1956
  if (sub === "register") {
1859
1957
  const appId = parseInt(args[1], 10);
1860
1958
  const tokenId = parseInt(args[2], 10);
@@ -1877,6 +1975,10 @@ async function main() {
1877
1975
  // --- Schemas ---
1878
1976
  case "schema": {
1879
1977
  const sub = args[0];
1978
+ if (flags.help) {
1979
+ printCommandHelp("schema", sub);
1980
+ return;
1981
+ }
1880
1982
  if (sub === "create") {
1881
1983
  const appId = parseInt(args[1], 10);
1882
1984
  const name = args[2];
@@ -1924,6 +2026,10 @@ async function main() {
1924
2026
  // --- ECDH Keys ---
1925
2027
  case "keys": {
1926
2028
  const sub = args[0];
2029
+ if (flags.help) {
2030
+ printCommandHelp("keys", sub);
2031
+ return;
2032
+ }
1927
2033
  if (sub === "register") {
1928
2034
  await keysRegister(cf);
1929
2035
  } else if (sub === "check") {
@@ -1961,6 +2067,10 @@ async function main() {
1961
2067
  // --- Fees ---
1962
2068
  case "fee": {
1963
2069
  const sub = args[0];
2070
+ if (flags.help) {
2071
+ printCommandHelp("fee", sub);
2072
+ return;
2073
+ }
1964
2074
  if (sub === "topic-creation") {
1965
2075
  if (args[1] === "set") {
1966
2076
  const appId = parseInt(args[2], 10);
@@ -1993,6 +2103,10 @@ async function main() {
1993
2103
  // --- Escrow ---
1994
2104
  case "escrow": {
1995
2105
  const sub = args[0];
2106
+ if (flags.help) {
2107
+ printCommandHelp("escrow", sub);
2108
+ return;
2109
+ }
1996
2110
  if (sub === "inbox") {
1997
2111
  const topicId = parseInt(args[1], 10);
1998
2112
  if (isNaN(topicId)) outputError("Usage: clawntenna escrow inbox <topicId>", json);
@@ -2053,17 +2167,33 @@ async function main() {
2053
2167
  }
2054
2168
  // --- Skill Files ---
2055
2169
  case "skill":
2170
+ if (flags.help) {
2171
+ printCommandHelp("skill");
2172
+ return;
2173
+ }
2056
2174
  showSkill(json);
2057
2175
  break;
2058
2176
  case "heartbeat":
2177
+ if (flags.help) {
2178
+ printCommandHelp("heartbeat");
2179
+ return;
2180
+ }
2059
2181
  showHeartbeat(json);
2060
2182
  break;
2061
2183
  case "skill-json":
2184
+ if (flags.help) {
2185
+ printCommandHelp("skill-json");
2186
+ return;
2187
+ }
2062
2188
  showSkillJson();
2063
2189
  break;
2064
2190
  // --- State ---
2065
2191
  case "state": {
2066
2192
  const sub = args[0];
2193
+ if (flags.help) {
2194
+ printCommandHelp("state", sub);
2195
+ return;
2196
+ }
2067
2197
  if (sub === "init") {
2068
2198
  stateInit(json);
2069
2199
  } else {
@@ -4,8 +4,8 @@ import {
4
4
  showHeartbeat,
5
5
  showSkill,
6
6
  showSkillJson
7
- } from "./chunk-AK26RTP5.js";
8
- import "./chunk-AQHFWEZF.js";
7
+ } from "./chunk-FDS4E5ME.js";
8
+ import "./chunk-S2IWR2YO.js";
9
9
  export {
10
10
  copySkillFiles,
11
11
  showHeartbeat,
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  initState,
4
4
  stateInit
5
- } from "./chunk-AIISNOCB.js";
6
- import "./chunk-AQHFWEZF.js";
5
+ } from "./chunk-EOKSFPRZ.js";
6
+ import "./chunk-S2IWR2YO.js";
7
7
  export {
8
8
  initState,
9
9
  stateInit
package/dist/index.cjs CHANGED
@@ -1663,10 +1663,6 @@ var Clawntenna = class _Clawntenna {
1663
1663
  async registerPublicKey() {
1664
1664
  this.requireSigner();
1665
1665
  if (!this.ecdhPublicKey) throw new Error("ECDH key not derived yet");
1666
- const hasKey = await this.keyManager.hasPublicKey(this.requireAddress());
1667
- if (hasKey) {
1668
- throw new Error("Public key already registered on-chain");
1669
- }
1670
1666
  return this.keyManager.registerPublicKey(this.ecdhPublicKey);
1671
1667
  }
1672
1668
  /**