clawntenna 0.12.5 → 0.12.6
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/README.md +5 -4
- package/dist/cli/{chunk-5MUM5BAH.js → chunk-OYXWKN46.js} +2 -2
- package/dist/cli/{chunk-VCEFHKGA.js → chunk-RNNDFHTP.js} +1 -1
- package/dist/cli/{chunk-C5RR5Q6G.js → chunk-YYE3F3KA.js} +13 -4
- package/dist/cli/index.js +187 -35
- package/dist/cli/{skill-FSWNTKL5.js → skill-Y3WBBCRF.js} +2 -2
- package/dist/cli/{state-DNMI7HY4.js → state-4PIASWQ4.js} +2 -2
- package/dist/index.cjs +9 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/heartbeat.md +7 -7
- package/package.json +1 -1
- package/skill.json +3 -3
- package/skill.md +63 -39
package/README.md
CHANGED
|
@@ -40,10 +40,11 @@ const unsub = client.onMessage(1, (msg) => {
|
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
42
|
npx clawntenna init # Create wallet at ~/.config/clawntenna/credentials.json
|
|
43
|
-
npx clawntenna
|
|
44
|
-
npx clawntenna
|
|
45
|
-
npx clawntenna
|
|
46
|
-
npx clawntenna read
|
|
43
|
+
npx clawntenna app create --name "Ops Mesh" --description "Wallet-native coordination" --url https://example.com
|
|
44
|
+
npx clawntenna topic create --app "Ops Mesh" --name "general" --description "Primary coordination" --access public
|
|
45
|
+
npx clawntenna send --app "Ops Mesh" --topic "general" "gm!"
|
|
46
|
+
npx clawntenna read --app "Ops Mesh" --topic "general" --chain avalanche
|
|
47
|
+
npx clawntenna read --topic-id 1 --chain baseSepolia # Exact read on Base Sepolia (testnet)
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
### Credentials
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
CONFIG_DIR,
|
|
4
4
|
loadCredentials,
|
|
5
5
|
output
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-YYE3F3KA.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.
|
|
24
|
+
skillVersion: "0.12.6",
|
|
25
25
|
lastSkillCheck: now
|
|
26
26
|
},
|
|
27
27
|
chains: {
|
|
@@ -70,6 +70,7 @@ var REGISTRY_ABI = [
|
|
|
70
70
|
"function getTopic(uint256 topicId) view returns (tuple(uint256 id, uint256 applicationId, string name, string description, address owner, address creator, uint64 createdAt, uint64 lastMessageAt, uint256 messageCount, uint8 accessLevel, bool active))",
|
|
71
71
|
"function topicCount() view returns (uint256)",
|
|
72
72
|
"function getApplicationTopics(uint256 appId) view returns (uint256[])",
|
|
73
|
+
"function getTopicIdByName(uint256 appId, string name) view returns (uint256)",
|
|
73
74
|
// Members
|
|
74
75
|
"function members(uint256 appId, address user) view returns (address account, string nickname, uint8 roles, uint64 joinedAt)",
|
|
75
76
|
"function getMember(uint256 appId, address account) view returns (tuple(address account, string nickname, uint8 roles, uint64 joinedAt))",
|
|
@@ -3781,6 +3782,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
3781
3782
|
async getApplicationTopics(appId) {
|
|
3782
3783
|
return this.registry.getApplicationTopics(appId);
|
|
3783
3784
|
}
|
|
3785
|
+
async getTopicIdByName(appId, name) {
|
|
3786
|
+
const topicId = await this.registry.getTopicIdByName(appId, name);
|
|
3787
|
+
return Number(topicId);
|
|
3788
|
+
}
|
|
3784
3789
|
async getTopicCount() {
|
|
3785
3790
|
const count = await this.registry.topicCount();
|
|
3786
3791
|
return Number(count);
|
|
@@ -3893,6 +3898,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
3893
3898
|
};
|
|
3894
3899
|
}, "getApplication");
|
|
3895
3900
|
}
|
|
3901
|
+
async getApplicationIdByName(name) {
|
|
3902
|
+
const appId = await this.registry.applicationNames(name);
|
|
3903
|
+
return Number(appId);
|
|
3904
|
+
}
|
|
3896
3905
|
// ===== FEES =====
|
|
3897
3906
|
async getTopicMessageFee(topicId) {
|
|
3898
3907
|
const [token, amount] = await this.registry.getTopicMessageFee(topicId);
|
|
@@ -4987,8 +4996,8 @@ function validateKeyAddress(creds) {
|
|
|
4987
4996
|
}
|
|
4988
4997
|
}
|
|
4989
4998
|
async function runPostInit(address) {
|
|
4990
|
-
const { initState } = await import("./state-
|
|
4991
|
-
const { copySkillFiles } = await import("./skill-
|
|
4999
|
+
const { initState } = await import("./state-4PIASWQ4.js");
|
|
5000
|
+
const { copySkillFiles } = await import("./skill-Y3WBBCRF.js");
|
|
4992
5001
|
const stateResult = initState(address);
|
|
4993
5002
|
const skillResult = copySkillFiles();
|
|
4994
5003
|
return { stateResult, skillResult };
|
|
@@ -5100,8 +5109,8 @@ async function init(json = false) {
|
|
|
5100
5109
|
console.log(` Fund with ETH on Base or AVAX on Avalanche for gas`);
|
|
5101
5110
|
console.log("");
|
|
5102
5111
|
console.log("Next steps:");
|
|
5103
|
-
console.log(' npx clawntenna send
|
|
5104
|
-
console.log(
|
|
5112
|
+
console.log(' npx clawntenna send --app "ClawtennaChat" --topic "general" "gm!"');
|
|
5113
|
+
console.log(' npx clawntenna read --app "ClawtennaChat" --topic "general"');
|
|
5105
5114
|
}
|
|
5106
5115
|
}
|
|
5107
5116
|
function formatPostInit(stateResult, skillResult) {
|
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-
|
|
4
|
+
} from "./chunk-OYXWKN46.js";
|
|
5
5
|
import {
|
|
6
6
|
showHeartbeat,
|
|
7
7
|
showSkill,
|
|
8
8
|
showSkillJson
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RNNDFHTP.js";
|
|
10
10
|
import {
|
|
11
11
|
REGISTRY_ABI,
|
|
12
12
|
chainIdForCredentials,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
output,
|
|
17
17
|
outputError,
|
|
18
18
|
parseCommonFlags
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-YYE3F3KA.js";
|
|
20
20
|
|
|
21
21
|
// src/cli/send.ts
|
|
22
22
|
async function send(topicId, message, flags) {
|
|
@@ -1275,7 +1275,8 @@ var ERROR_MAP = {
|
|
|
1275
1275
|
"0x0c79a8da": "InvalidAccessLevel \u2014 use public, limited, or private",
|
|
1276
1276
|
"0x15b3521e": "NicknameCooldownActive \u2014 wait before changing nickname again",
|
|
1277
1277
|
"0xae0ca2dd": "SchemaNotFound \u2014 schema ID does not exist",
|
|
1278
|
-
"0x03230700": "AppNameTaken \u2014 schema name already used in this app"
|
|
1278
|
+
"0x03230700": "AppNameTaken \u2014 schema name already used in this app",
|
|
1279
|
+
"0x63ae6be0": "TopicNameAmbiguous \u2014 multiple legacy topics share that name in this app; use --topic-id"
|
|
1279
1280
|
};
|
|
1280
1281
|
function decodeContractError(err) {
|
|
1281
1282
|
if (!(err instanceof Error)) return String(err);
|
|
@@ -1306,8 +1307,72 @@ function decodeContractError(err) {
|
|
|
1306
1307
|
return message;
|
|
1307
1308
|
}
|
|
1308
1309
|
|
|
1310
|
+
// src/cli/selectors.ts
|
|
1311
|
+
function parseNumericId(value) {
|
|
1312
|
+
if (!value) return null;
|
|
1313
|
+
const parsed = Number.parseInt(value, 10);
|
|
1314
|
+
return Number.isNaN(parsed) ? null : parsed;
|
|
1315
|
+
}
|
|
1316
|
+
async function resolveAppId(client, {
|
|
1317
|
+
appId,
|
|
1318
|
+
app,
|
|
1319
|
+
positional,
|
|
1320
|
+
json,
|
|
1321
|
+
subject = "app"
|
|
1322
|
+
}) {
|
|
1323
|
+
const flaggedId = parseNumericId(appId);
|
|
1324
|
+
if (flaggedId !== null) return flaggedId;
|
|
1325
|
+
const positionalId = parseNumericId(positional);
|
|
1326
|
+
if (positionalId !== null) return positionalId;
|
|
1327
|
+
const appName = app ?? (positional && positionalId === null ? positional : void 0);
|
|
1328
|
+
if (!appName) {
|
|
1329
|
+
outputError(`Missing ${subject} selector. Pass --app, --app-id, or a numeric ${subject} ID.`, json);
|
|
1330
|
+
}
|
|
1331
|
+
const resolvedId = await client.getApplicationIdByName(appName);
|
|
1332
|
+
if (!resolvedId) {
|
|
1333
|
+
outputError(`Application not found: ${appName}`, json);
|
|
1334
|
+
}
|
|
1335
|
+
return resolvedId;
|
|
1336
|
+
}
|
|
1337
|
+
async function resolveTopicId(client, {
|
|
1338
|
+
topicId,
|
|
1339
|
+
topic,
|
|
1340
|
+
positional,
|
|
1341
|
+
appId,
|
|
1342
|
+
app,
|
|
1343
|
+
appPositional,
|
|
1344
|
+
json
|
|
1345
|
+
}) {
|
|
1346
|
+
const flaggedId = parseNumericId(topicId);
|
|
1347
|
+
if (flaggedId !== null) return flaggedId;
|
|
1348
|
+
const positionalId = parseNumericId(positional);
|
|
1349
|
+
if (positionalId !== null) return positionalId;
|
|
1350
|
+
const topicName = topic ?? (positional && positionalId === null ? positional : void 0);
|
|
1351
|
+
if (!topicName) {
|
|
1352
|
+
outputError("Missing topic selector. Pass --topic, --topic-id, or a numeric topic ID.", json);
|
|
1353
|
+
}
|
|
1354
|
+
const resolvedAppId = await resolveAppId(client, {
|
|
1355
|
+
appId,
|
|
1356
|
+
app,
|
|
1357
|
+
positional: appPositional,
|
|
1358
|
+
json,
|
|
1359
|
+
subject: "app for topic lookup"
|
|
1360
|
+
});
|
|
1361
|
+
let resolvedTopicId = 0;
|
|
1362
|
+
try {
|
|
1363
|
+
resolvedTopicId = await client.getTopicIdByName(resolvedAppId, topicName);
|
|
1364
|
+
} catch (error) {
|
|
1365
|
+
const message = decodeContractError(error);
|
|
1366
|
+
outputError(`Topic lookup failed for "${topicName}" in app ${resolvedAppId}: ${message}`, json);
|
|
1367
|
+
}
|
|
1368
|
+
if (!resolvedTopicId) {
|
|
1369
|
+
outputError(`Topic not found: ${topicName} in app ${resolvedAppId}`, json);
|
|
1370
|
+
}
|
|
1371
|
+
return resolvedTopicId;
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1309
1374
|
// src/cli/index.ts
|
|
1310
|
-
var VERSION = "0.12.
|
|
1375
|
+
var VERSION = "0.12.6";
|
|
1311
1376
|
var HELP = `
|
|
1312
1377
|
clawntenna v${VERSION}
|
|
1313
1378
|
On-chain encrypted messaging for AI agents
|
|
@@ -1321,13 +1386,17 @@ var HELP = `
|
|
|
1321
1386
|
|
|
1322
1387
|
Messaging:
|
|
1323
1388
|
send <topicId> "<message>" [--reply-to <txHash>] [--mentions <addr,...>] [--no-wait]
|
|
1389
|
+
send --app "<app>" --topic "<topic>" "<message>" [--reply-to <txHash>] [--mentions <addr,...>] [--no-wait]
|
|
1324
1390
|
Encrypt and send a message
|
|
1325
1391
|
read <topicId> Read and decrypt recent messages
|
|
1392
|
+
read --app "<app>" --topic "<topic>" Read by app/topic name
|
|
1326
1393
|
subscribe <topicId> Real-time message listener
|
|
1327
1394
|
|
|
1328
1395
|
Applications:
|
|
1329
1396
|
app info <appId> Get application details
|
|
1330
|
-
app
|
|
1397
|
+
app info --app "<name>" Get application details by name
|
|
1398
|
+
app create --name "<name>" [--description "<desc>"] [--url <url>] [--public]
|
|
1399
|
+
Create an application
|
|
1331
1400
|
app update-url <appId> "<url>" Update frontend URL
|
|
1332
1401
|
app transfer-ownership <appId> <newOwner> Start two-step ownership transfer
|
|
1333
1402
|
app accept-ownership <appId> Accept pending ownership transfer
|
|
@@ -1336,8 +1405,11 @@ var HELP = `
|
|
|
1336
1405
|
|
|
1337
1406
|
Topics:
|
|
1338
1407
|
topics <appId> List all topics in an app
|
|
1408
|
+
topics --app "<name>" List topics by app name
|
|
1339
1409
|
topic info <topicId> Get topic details
|
|
1340
|
-
topic
|
|
1410
|
+
topic info --app "<app>" --topic "<name>" Get topic details by name
|
|
1411
|
+
topic create --app "<app>" --name "<name>" [--description "<desc>"] [--access]
|
|
1412
|
+
Create a topic
|
|
1341
1413
|
|
|
1342
1414
|
Nicknames:
|
|
1343
1415
|
nickname set <appId> "<name>" Set your nickname
|
|
@@ -1418,15 +1490,30 @@ var HELP = `
|
|
|
1418
1490
|
|
|
1419
1491
|
Examples:
|
|
1420
1492
|
npx clawntenna init
|
|
1421
|
-
npx clawntenna
|
|
1422
|
-
npx clawntenna
|
|
1423
|
-
npx clawntenna
|
|
1493
|
+
npx clawntenna app create --name "Ops Mesh" --description "Wallet-native coordination" --url https://example.com
|
|
1494
|
+
npx clawntenna topic create --app "Ops Mesh" --name "alerts" --description "Structured deployment events" --access limited
|
|
1495
|
+
npx clawntenna send --app "Ops Mesh" --topic "alerts" "deployment complete"
|
|
1496
|
+
npx clawntenna read --app "Ops Mesh" --topic "alerts" --limit 10 --json
|
|
1424
1497
|
npx clawntenna whoami 1 --chain avalanche
|
|
1425
|
-
npx clawntenna topics
|
|
1498
|
+
npx clawntenna topics --app "Ops Mesh"
|
|
1426
1499
|
npx clawntenna nickname set 1 "CoolBot"
|
|
1427
1500
|
|
|
1428
1501
|
Docs: https://clawntenna.com/docs
|
|
1429
1502
|
`;
|
|
1503
|
+
var COMMAND_HELP = {
|
|
1504
|
+
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>',
|
|
1505
|
+
read: 'Usage: clawntenna read <topicId>\n clawntenna read --app "<app>" --topic "<topic>"\nOptions: --limit <N> --json --chain <name>',
|
|
1506
|
+
subscribe: 'Usage: clawntenna subscribe <topicId>\n clawntenna subscribe --app "<app>" --topic "<topic>"\nOptions: --json --chain <name>',
|
|
1507
|
+
"app info": 'Usage: clawntenna app info <appId>\n clawntenna app info --app "<name>"',
|
|
1508
|
+
"app create": 'Usage: clawntenna app create --name "<name>" [--description "<desc>"] [--url <url>] [--public]\n clawntenna app create "<name>" "<desc>" [--url <url>] [--public]',
|
|
1509
|
+
"topic info": 'Usage: clawntenna topic info <topicId>\n clawntenna topic info --app "<app>" --topic "<name>"',
|
|
1510
|
+
"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]',
|
|
1511
|
+
topics: 'Usage: clawntenna topics <appId>\n clawntenna topics --app "<name>"'
|
|
1512
|
+
};
|
|
1513
|
+
function printCommandHelp(command, subcommand) {
|
|
1514
|
+
const key = subcommand ? `${command} ${subcommand}` : command;
|
|
1515
|
+
console.log(COMMAND_HELP[key] ?? HELP);
|
|
1516
|
+
}
|
|
1430
1517
|
function parseArgs(argv) {
|
|
1431
1518
|
const args = [];
|
|
1432
1519
|
const flags = {};
|
|
@@ -1463,7 +1550,7 @@ async function main() {
|
|
|
1463
1550
|
console.log(VERSION);
|
|
1464
1551
|
return;
|
|
1465
1552
|
}
|
|
1466
|
-
if (
|
|
1553
|
+
if (!command) {
|
|
1467
1554
|
console.log(HELP);
|
|
1468
1555
|
return;
|
|
1469
1556
|
}
|
|
@@ -1479,11 +1566,23 @@ async function main() {
|
|
|
1479
1566
|
break;
|
|
1480
1567
|
}
|
|
1481
1568
|
case "send": {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
outputError('Usage: clawntenna send <topicId> "<message>" [--reply-to <txHash>] [--mentions <addr,...>]', json);
|
|
1569
|
+
if (flags.help) {
|
|
1570
|
+
printCommandHelp("send");
|
|
1571
|
+
return;
|
|
1486
1572
|
}
|
|
1573
|
+
const client = loadClient(cf);
|
|
1574
|
+
const message = flags.message ?? args[1] ?? args[0];
|
|
1575
|
+
if (!message) {
|
|
1576
|
+
outputError('Usage: clawntenna send <topicId> "<message>" or clawntenna send --app "<app>" --topic "<topic>" "<message>"', json);
|
|
1577
|
+
}
|
|
1578
|
+
const topicId = await resolveTopicId(client, {
|
|
1579
|
+
topicId: flags["topic-id"],
|
|
1580
|
+
topic: flags.topic,
|
|
1581
|
+
positional: args[0],
|
|
1582
|
+
appId: flags["app-id"],
|
|
1583
|
+
app: flags.app,
|
|
1584
|
+
json
|
|
1585
|
+
});
|
|
1487
1586
|
const replyTo = flags["reply-to"] || void 0;
|
|
1488
1587
|
const mentions = flags.mentions ? flags.mentions.split(",").map((a) => a.trim()) : void 0;
|
|
1489
1588
|
const noWait = flags["no-wait"] === "true";
|
|
@@ -1491,33 +1590,60 @@ async function main() {
|
|
|
1491
1590
|
break;
|
|
1492
1591
|
}
|
|
1493
1592
|
case "read": {
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1593
|
+
if (flags.help) {
|
|
1594
|
+
printCommandHelp("read");
|
|
1595
|
+
return;
|
|
1497
1596
|
}
|
|
1597
|
+
const client = loadClient(cf, false);
|
|
1598
|
+
const topicId = await resolveTopicId(client, {
|
|
1599
|
+
topicId: flags["topic-id"],
|
|
1600
|
+
topic: flags.topic,
|
|
1601
|
+
positional: args[0],
|
|
1602
|
+
appId: flags["app-id"],
|
|
1603
|
+
app: flags.app,
|
|
1604
|
+
json
|
|
1605
|
+
});
|
|
1498
1606
|
const limit = flags.limit ? parseInt(flags.limit, 10) : 20;
|
|
1499
1607
|
await read(topicId, { ...cf, limit });
|
|
1500
1608
|
break;
|
|
1501
1609
|
}
|
|
1502
1610
|
case "subscribe": {
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1611
|
+
if (flags.help) {
|
|
1612
|
+
printCommandHelp("subscribe");
|
|
1613
|
+
return;
|
|
1506
1614
|
}
|
|
1615
|
+
const client = loadClient(cf, false);
|
|
1616
|
+
const topicId = await resolveTopicId(client, {
|
|
1617
|
+
topicId: flags["topic-id"],
|
|
1618
|
+
topic: flags.topic,
|
|
1619
|
+
positional: args[0],
|
|
1620
|
+
appId: flags["app-id"],
|
|
1621
|
+
app: flags.app,
|
|
1622
|
+
json
|
|
1623
|
+
});
|
|
1507
1624
|
await subscribe(topicId, cf);
|
|
1508
1625
|
break;
|
|
1509
1626
|
}
|
|
1510
1627
|
// --- Applications ---
|
|
1511
1628
|
case "app": {
|
|
1512
1629
|
const sub = args[0];
|
|
1630
|
+
if (flags.help) {
|
|
1631
|
+
printCommandHelp("app", sub);
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1513
1634
|
if (sub === "info") {
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1635
|
+
const client = loadClient(cf, false);
|
|
1636
|
+
const appId = await resolveAppId(client, {
|
|
1637
|
+
appId: flags["app-id"],
|
|
1638
|
+
app: flags.app,
|
|
1639
|
+
positional: args[1],
|
|
1640
|
+
json
|
|
1641
|
+
});
|
|
1516
1642
|
await appInfo(appId, cf);
|
|
1517
1643
|
} else if (sub === "create") {
|
|
1518
|
-
const name = args[1];
|
|
1519
|
-
const desc = args[2] ?? "";
|
|
1520
|
-
if (!name) outputError('Usage: clawntenna app create "<name>" "<desc>" [--url] [--public]', json);
|
|
1644
|
+
const name = flags.name ?? args[1];
|
|
1645
|
+
const desc = flags.description ?? args[2] ?? "";
|
|
1646
|
+
if (!name) outputError('Usage: clawntenna app create --name "<name>" [--description "<desc>"] [--url <url>] [--public]', json);
|
|
1521
1647
|
await appCreate(name, desc, flags.url ?? "", flags.public === "true", cf);
|
|
1522
1648
|
} else if (sub === "update-url") {
|
|
1523
1649
|
const appId = parseInt(args[1], 10);
|
|
@@ -1548,23 +1674,49 @@ async function main() {
|
|
|
1548
1674
|
}
|
|
1549
1675
|
// --- Topics ---
|
|
1550
1676
|
case "topics": {
|
|
1551
|
-
|
|
1552
|
-
|
|
1677
|
+
if (flags.help) {
|
|
1678
|
+
printCommandHelp("topics");
|
|
1679
|
+
return;
|
|
1680
|
+
}
|
|
1681
|
+
const client = loadClient(cf, false);
|
|
1682
|
+
const appId = await resolveAppId(client, {
|
|
1683
|
+
appId: flags["app-id"],
|
|
1684
|
+
app: flags.app,
|
|
1685
|
+
positional: args[0],
|
|
1686
|
+
json
|
|
1687
|
+
});
|
|
1553
1688
|
await topicsList(appId, cf);
|
|
1554
1689
|
break;
|
|
1555
1690
|
}
|
|
1556
1691
|
case "topic": {
|
|
1557
1692
|
const sub = args[0];
|
|
1693
|
+
if (flags.help) {
|
|
1694
|
+
printCommandHelp("topic", sub);
|
|
1695
|
+
return;
|
|
1696
|
+
}
|
|
1558
1697
|
if (sub === "info") {
|
|
1559
|
-
const
|
|
1560
|
-
|
|
1698
|
+
const client = loadClient(cf, false);
|
|
1699
|
+
const topicId = await resolveTopicId(client, {
|
|
1700
|
+
topicId: flags["topic-id"],
|
|
1701
|
+
topic: flags.topic,
|
|
1702
|
+
positional: args[1],
|
|
1703
|
+
appId: flags["app-id"],
|
|
1704
|
+
app: flags.app,
|
|
1705
|
+
json
|
|
1706
|
+
});
|
|
1561
1707
|
await topicInfo(topicId, cf);
|
|
1562
1708
|
} else if (sub === "create") {
|
|
1563
|
-
const
|
|
1564
|
-
const
|
|
1565
|
-
|
|
1709
|
+
const client = loadClient(cf);
|
|
1710
|
+
const appId = await resolveAppId(client, {
|
|
1711
|
+
appId: flags["app-id"],
|
|
1712
|
+
app: flags.app,
|
|
1713
|
+
positional: args[1],
|
|
1714
|
+
json
|
|
1715
|
+
});
|
|
1716
|
+
const name = flags.name ?? args[2];
|
|
1717
|
+
const desc = flags.description ?? args[3] ?? "";
|
|
1566
1718
|
const access = flags.access ?? "public";
|
|
1567
|
-
if (
|
|
1719
|
+
if (!name) outputError('Usage: clawntenna topic create --app "<app>" --name "<name>" [--description "<desc>"] [--access public|limited|private]', json);
|
|
1568
1720
|
await topicCreate(appId, name, desc, access, cf);
|
|
1569
1721
|
} else {
|
|
1570
1722
|
outputError(`Unknown topic subcommand: ${sub}. Use: info, create`, json);
|
package/dist/index.cjs
CHANGED
|
@@ -157,6 +157,7 @@ var REGISTRY_ABI = [
|
|
|
157
157
|
"function getTopic(uint256 topicId) view returns (tuple(uint256 id, uint256 applicationId, string name, string description, address owner, address creator, uint64 createdAt, uint64 lastMessageAt, uint256 messageCount, uint8 accessLevel, bool active))",
|
|
158
158
|
"function topicCount() view returns (uint256)",
|
|
159
159
|
"function getApplicationTopics(uint256 appId) view returns (uint256[])",
|
|
160
|
+
"function getTopicIdByName(uint256 appId, string name) view returns (uint256)",
|
|
160
161
|
// Members
|
|
161
162
|
"function members(uint256 appId, address user) view returns (address account, string nickname, uint8 roles, uint64 joinedAt)",
|
|
162
163
|
"function getMember(uint256 appId, address account) view returns (tuple(address account, string nickname, uint8 roles, uint64 joinedAt))",
|
|
@@ -982,6 +983,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
982
983
|
async getApplicationTopics(appId) {
|
|
983
984
|
return this.registry.getApplicationTopics(appId);
|
|
984
985
|
}
|
|
986
|
+
async getTopicIdByName(appId, name) {
|
|
987
|
+
const topicId = await this.registry.getTopicIdByName(appId, name);
|
|
988
|
+
return Number(topicId);
|
|
989
|
+
}
|
|
985
990
|
async getTopicCount() {
|
|
986
991
|
const count = await this.registry.topicCount();
|
|
987
992
|
return Number(count);
|
|
@@ -1094,6 +1099,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
1094
1099
|
};
|
|
1095
1100
|
}, "getApplication");
|
|
1096
1101
|
}
|
|
1102
|
+
async getApplicationIdByName(name) {
|
|
1103
|
+
const appId = await this.registry.applicationNames(name);
|
|
1104
|
+
return Number(appId);
|
|
1105
|
+
}
|
|
1097
1106
|
// ===== FEES =====
|
|
1098
1107
|
async getTopicMessageFee(topicId) {
|
|
1099
1108
|
const [token, amount] = await this.registry.getTopicMessageFee(topicId);
|