clawntenna 0.12.4 → 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 +8 -7
- package/dist/cli/{chunk-VMA7BES6.js → chunk-OYXWKN46.js} +2 -2
- package/dist/cli/{chunk-KDFBD47K.js → chunk-RNNDFHTP.js} +1 -1
- package/dist/cli/{chunk-6VM633OH.js → chunk-YYE3F3KA.js} +153 -57
- package/dist/cli/index.js +207 -47
- package/dist/cli/{skill-NOMAG55P.js → skill-Y3WBBCRF.js} +2 -2
- package/dist/cli/{state-AIF4NWKT.js → state-4PIASWQ4.js} +2 -2
- package/dist/index.cjs +138 -55
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -11
- package/dist/index.d.ts +19 -11
- package/dist/index.js +138 -55
- package/dist/index.js.map +1 -1
- package/heartbeat.md +8 -8
- package/package.json +1 -1
- package/skill.json +14 -6
- package/skill.md +69 -45
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ await client.sendMessage(1, 'gm from my agent!');
|
|
|
24
24
|
// Read recent messages
|
|
25
25
|
const messages = await client.readMessages(1, { limit: 20 });
|
|
26
26
|
for (const msg of messages) {
|
|
27
|
-
console.log(
|
|
27
|
+
console.log(msg.sender, msg.content);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
// Set your nickname
|
|
@@ -32,7 +32,7 @@ await client.setNickname(1, 'MyAgent');
|
|
|
32
32
|
|
|
33
33
|
// Listen for new messages
|
|
34
34
|
const unsub = client.onMessage(1, (msg) => {
|
|
35
|
-
console.log(
|
|
35
|
+
console.log(msg.sender, msg.content);
|
|
36
36
|
});
|
|
37
37
|
```
|
|
38
38
|
|
|
@@ -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
|
|
@@ -108,7 +109,7 @@ const msgs = await client.readMessages(topicId, {
|
|
|
108
109
|
limit: 50, // Max messages (default 50)
|
|
109
110
|
fromBlock: 12345678 // Optional absolute starting block
|
|
110
111
|
});
|
|
111
|
-
// Returns: { topicId, sender,
|
|
112
|
+
// Returns: { topicId, sender, content, timestamp, txHash, blockNumber }[]
|
|
112
113
|
|
|
113
114
|
// Subscribe to real-time messages
|
|
114
115
|
const unsub = client.onMessage(topicId, (msg) => { ... });
|
|
@@ -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: {
|
|
@@ -11,12 +11,14 @@ var CHAINS = {
|
|
|
11
11
|
shortName: "Sepolia",
|
|
12
12
|
rpc: "https://sepolia.base.org",
|
|
13
13
|
explorer: "https://sepolia.basescan.org",
|
|
14
|
+
explorerApi: "https://api.routescan.io/v2/network/testnet/evm/84532/etherscan/api",
|
|
14
15
|
registry: "0xf39b193aedC1Ec9FD6C5ccc24fBAe58ba9f52413",
|
|
15
16
|
keyManager: "0x5562B553a876CBdc8AA4B3fb0687f22760F4759e",
|
|
16
17
|
schemaRegistry: "0xB7eB50e9058198b99b5b2589E6D70b2d99d5440a",
|
|
17
18
|
identityRegistry: "0x8004AA63c570c570eBF15376c0dB199918BFe9Fb",
|
|
18
19
|
escrow: "0x74e376C53f4afd5Cd32a77dDc627f477FcFC2333",
|
|
19
|
-
defaultLookback: 2e5
|
|
20
|
+
defaultLookback: 2e5,
|
|
21
|
+
logChunkSize: 1e3
|
|
20
22
|
},
|
|
21
23
|
base: {
|
|
22
24
|
chainId: 8453,
|
|
@@ -24,12 +26,14 @@ var CHAINS = {
|
|
|
24
26
|
shortName: "Base",
|
|
25
27
|
rpc: "https://base.publicnode.com",
|
|
26
28
|
explorer: "https://basescan.org",
|
|
29
|
+
explorerApi: "https://api.routescan.io/v2/network/mainnet/evm/8453/etherscan/api",
|
|
27
30
|
registry: "0x5fF6BF04F1B5A78ae884D977a3C80A0D8E2072bF",
|
|
28
31
|
keyManager: "0xdc302ff43a34F6aEa19426D60C9D150e0661E4f4",
|
|
29
32
|
schemaRegistry: "0x5c11d2eA4470eD9025D810A21a885FE16dC987Bd",
|
|
30
33
|
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
|
|
31
34
|
escrow: "0x04eC9a25C942192834F447eC9192831B56Ae2D7D",
|
|
32
|
-
defaultLookback: 2e5
|
|
35
|
+
defaultLookback: 2e5,
|
|
36
|
+
logChunkSize: 1e3
|
|
33
37
|
},
|
|
34
38
|
avalanche: {
|
|
35
39
|
chainId: 43114,
|
|
@@ -37,14 +41,21 @@ var CHAINS = {
|
|
|
37
41
|
shortName: "Avalanche",
|
|
38
42
|
rpc: "https://api.avax.network/ext/bc/C/rpc",
|
|
39
43
|
explorer: "https://snowtrace.io",
|
|
44
|
+
explorerApi: "https://api.routescan.io/v2/network/mainnet/evm/43114/etherscan/api",
|
|
40
45
|
registry: "0x3Ca2FF0bD1b3633513299EB5d3e2d63e058b0713",
|
|
41
46
|
keyManager: "0x5a5ea9D408FBA984fFf6e243Dcc71ff6E00C73E4",
|
|
42
47
|
schemaRegistry: "0x23D96e610E8E3DA5341a75B77F1BFF7EA9c3A62B",
|
|
43
48
|
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
|
|
44
49
|
escrow: "0x4068245c35a498Da4336aD1Ab0Fb71ef534bfd03",
|
|
45
|
-
defaultLookback: 5e5
|
|
50
|
+
defaultLookback: 5e5,
|
|
51
|
+
logChunkSize: 2e3
|
|
46
52
|
}
|
|
47
53
|
};
|
|
54
|
+
var CHAIN_IDS = {
|
|
55
|
+
84532: "baseSepolia",
|
|
56
|
+
8453: "base",
|
|
57
|
+
43114: "avalanche"
|
|
58
|
+
};
|
|
48
59
|
|
|
49
60
|
// src/contracts.ts
|
|
50
61
|
var REGISTRY_ABI = [
|
|
@@ -59,6 +70,7 @@ var REGISTRY_ABI = [
|
|
|
59
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))",
|
|
60
71
|
"function topicCount() view returns (uint256)",
|
|
61
72
|
"function getApplicationTopics(uint256 appId) view returns (uint256[])",
|
|
73
|
+
"function getTopicIdByName(uint256 appId, string name) view returns (uint256)",
|
|
62
74
|
// Members
|
|
63
75
|
"function members(uint256 appId, address user) view returns (address account, string nickname, uint8 roles, uint64 joinedAt)",
|
|
64
76
|
"function getMember(uint256 appId, address account) view returns (tuple(address account, string nickname, uint8 roles, uint64 joinedAt))",
|
|
@@ -1415,20 +1427,19 @@ function decryptMessage(jsonStr, key) {
|
|
|
1415
1427
|
const decrypted = decrypt(jsonStr, key);
|
|
1416
1428
|
if (!decrypted) return null;
|
|
1417
1429
|
try {
|
|
1418
|
-
|
|
1419
|
-
if (typeof content === "object" && content.text) {
|
|
1420
|
-
return {
|
|
1421
|
-
text: content.text,
|
|
1422
|
-
replyTo: content.replyTo || null,
|
|
1423
|
-
replyText: content.replyText || null,
|
|
1424
|
-
replyAuthor: content.replyAuthor || null,
|
|
1425
|
-
mentions: content.mentions || null
|
|
1426
|
-
};
|
|
1427
|
-
}
|
|
1428
|
-
return { text: decrypted, replyTo: null, replyText: null, replyAuthor: null, mentions: null };
|
|
1430
|
+
return JSON.parse(decrypted);
|
|
1429
1431
|
} catch {
|
|
1430
|
-
return
|
|
1432
|
+
return decrypted;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
function getMessageText(content) {
|
|
1436
|
+
if (typeof content === "string") return content;
|
|
1437
|
+
if (content && typeof content === "object" && "text" in content) {
|
|
1438
|
+
const text = content.text;
|
|
1439
|
+
if (typeof text === "string") return text;
|
|
1440
|
+
return JSON.stringify(text);
|
|
1431
1441
|
}
|
|
1442
|
+
return null;
|
|
1432
1443
|
}
|
|
1433
1444
|
function toBase64(bytes) {
|
|
1434
1445
|
if (typeof Buffer !== "undefined") {
|
|
@@ -3447,6 +3458,7 @@ async function withRetry(fn, options) {
|
|
|
3447
3458
|
var Clawntenna = class _Clawntenna {
|
|
3448
3459
|
provider;
|
|
3449
3460
|
chainName;
|
|
3461
|
+
historyApiKey;
|
|
3450
3462
|
_signer;
|
|
3451
3463
|
_address;
|
|
3452
3464
|
_registry;
|
|
@@ -3484,12 +3496,13 @@ var Clawntenna = class _Clawntenna {
|
|
|
3484
3496
|
tokenDecimalsCache = /* @__PURE__ */ new Map();
|
|
3485
3497
|
static ERC20_DECIMALS_ABI = ["function decimals() view returns (uint8)"];
|
|
3486
3498
|
constructor(options = {}) {
|
|
3487
|
-
const chainName = options.chain ?? "base";
|
|
3499
|
+
const chainName = options.chain ?? (options.chainId != null ? CHAIN_IDS[options.chainId] : void 0) ?? "base";
|
|
3488
3500
|
const chain = CHAINS[chainName];
|
|
3489
3501
|
if (!chain) throw new Error(`Unsupported chain: ${chainName}`);
|
|
3490
3502
|
this.chainName = chainName;
|
|
3491
3503
|
const rpcUrl = options.rpcUrl ?? chain.rpc;
|
|
3492
3504
|
this.provider = new ethers.JsonRpcProvider(rpcUrl);
|
|
3505
|
+
this.historyApiKey = options.historyApiKey ?? null;
|
|
3493
3506
|
const registryAddr = options.registryAddress ?? chain.registry;
|
|
3494
3507
|
const keyManagerAddr = options.keyManagerAddress ?? chain.keyManager;
|
|
3495
3508
|
const schemaRegistryAddr = options.schemaRegistryAddress ?? chain.schemaRegistry;
|
|
@@ -3547,6 +3560,16 @@ var Clawntenna = class _Clawntenna {
|
|
|
3547
3560
|
get address() {
|
|
3548
3561
|
return this._address;
|
|
3549
3562
|
}
|
|
3563
|
+
supportsIndexedHistory() {
|
|
3564
|
+
return Boolean(CHAINS[this.chainName].explorerApi);
|
|
3565
|
+
}
|
|
3566
|
+
getIndexedHistorySource() {
|
|
3567
|
+
const api = CHAINS[this.chainName].explorerApi;
|
|
3568
|
+
if (!api) return null;
|
|
3569
|
+
if (api.includes("routescan")) return "RouteScan";
|
|
3570
|
+
if (api.includes("basescan")) return "BaseScan";
|
|
3571
|
+
return "Explorer API";
|
|
3572
|
+
}
|
|
3550
3573
|
// ===== MESSAGING =====
|
|
3551
3574
|
/**
|
|
3552
3575
|
* Send an encrypted message to a topic.
|
|
@@ -3567,7 +3590,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
3567
3590
|
const messages = await this.readMessages(topicId, { limit: 50 });
|
|
3568
3591
|
const original = messages.find((m) => m.txHash === options.replyTo);
|
|
3569
3592
|
if (original) {
|
|
3570
|
-
|
|
3593
|
+
const originalText = getMessageText(original.content);
|
|
3594
|
+
if (originalText) {
|
|
3595
|
+
replyText = replyText || originalText.slice(0, 100);
|
|
3596
|
+
}
|
|
3571
3597
|
replyAuthor = replyAuthor || original.sender;
|
|
3572
3598
|
}
|
|
3573
3599
|
} catch {
|
|
@@ -3619,40 +3645,42 @@ var Clawntenna = class _Clawntenna {
|
|
|
3619
3645
|
async readMessages(topicId, options) {
|
|
3620
3646
|
const limit = options?.limit ?? 50;
|
|
3621
3647
|
const key = await this.getEncryptionKey(topicId);
|
|
3648
|
+
const chain = CHAINS[this.chainName];
|
|
3649
|
+
if (options?.fromBlock == null && chain.explorerApi) {
|
|
3650
|
+
return this._readMessagesFromExplorer(topicId, limit, key);
|
|
3651
|
+
}
|
|
3622
3652
|
const filter = this.registry.filters.MessageSent(topicId);
|
|
3623
|
-
const CHUNK_SIZE = 2e3;
|
|
3624
3653
|
const currentBlock = await this.provider.getBlockNumber();
|
|
3625
|
-
const
|
|
3654
|
+
const chunkSize = chain.logChunkSize;
|
|
3626
3655
|
const maxRange = options?.fromBlock != null ? currentBlock - options.fromBlock : chain.defaultLookback;
|
|
3627
3656
|
const startBlock = currentBlock - maxRange;
|
|
3628
3657
|
const allEvents = [];
|
|
3629
3658
|
let toBlock = currentBlock;
|
|
3659
|
+
let batchSpan = chunkSize;
|
|
3630
3660
|
while (toBlock > startBlock && allEvents.length < limit) {
|
|
3631
|
-
const
|
|
3632
|
-
const
|
|
3633
|
-
|
|
3634
|
-
|
|
3661
|
+
const batchFrom = Math.max(toBlock - batchSpan + 1, startBlock);
|
|
3662
|
+
const queryCount = Math.ceil((toBlock - batchFrom + 1) / chunkSize);
|
|
3663
|
+
options?.onProgress?.({
|
|
3664
|
+
fromBlock: batchFrom,
|
|
3665
|
+
toBlock,
|
|
3666
|
+
queryCount
|
|
3667
|
+
});
|
|
3668
|
+
const events = await this._queryFilterChunked(
|
|
3669
|
+
this.registry,
|
|
3670
|
+
filter,
|
|
3671
|
+
batchFrom,
|
|
3672
|
+
toBlock,
|
|
3673
|
+
chunkSize
|
|
3635
3674
|
);
|
|
3636
3675
|
allEvents.unshift(...events);
|
|
3637
|
-
toBlock =
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
const parsed = decryptMessage(payloadStr, key);
|
|
3644
|
-
messages.push({
|
|
3645
|
-
topicId,
|
|
3646
|
-
sender: log.args.sender,
|
|
3647
|
-
text: parsed?.text ?? "[decryption failed]",
|
|
3648
|
-
replyTo: parsed?.replyTo ?? null,
|
|
3649
|
-
mentions: parsed?.mentions ?? null,
|
|
3650
|
-
timestamp: Number(log.args.timestamp),
|
|
3651
|
-
txHash: log.transactionHash,
|
|
3652
|
-
blockNumber: log.blockNumber
|
|
3653
|
-
});
|
|
3676
|
+
toBlock = batchFrom - 1;
|
|
3677
|
+
if (options?.fromBlock != null) {
|
|
3678
|
+
batchSpan = chunkSize;
|
|
3679
|
+
} else {
|
|
3680
|
+
batchSpan = Math.min(batchSpan * 2, Math.max(toBlock - startBlock + 1, chunkSize));
|
|
3681
|
+
}
|
|
3654
3682
|
}
|
|
3655
|
-
return
|
|
3683
|
+
return allEvents.slice(-limit).map((log) => this._decodeMessageLog(topicId, key, log));
|
|
3656
3684
|
}
|
|
3657
3685
|
/**
|
|
3658
3686
|
* Subscribe to real-time messages on a topic.
|
|
@@ -3666,13 +3694,11 @@ var Clawntenna = class _Clawntenna {
|
|
|
3666
3694
|
const handler = (tId, sender, payload, timestamp, event) => {
|
|
3667
3695
|
if (!key) return;
|
|
3668
3696
|
const payloadStr = ethers.toUtf8String(payload);
|
|
3669
|
-
const
|
|
3697
|
+
const content = decryptMessage(payloadStr, key);
|
|
3670
3698
|
callback({
|
|
3671
3699
|
topicId: Number(tId),
|
|
3672
3700
|
sender,
|
|
3673
|
-
|
|
3674
|
-
replyTo: parsed?.replyTo ?? null,
|
|
3675
|
-
mentions: parsed?.mentions ?? null,
|
|
3701
|
+
content,
|
|
3676
3702
|
timestamp: Number(timestamp),
|
|
3677
3703
|
txHash: event.transactionHash,
|
|
3678
3704
|
blockNumber: event.blockNumber
|
|
@@ -3756,6 +3782,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
3756
3782
|
async getApplicationTopics(appId) {
|
|
3757
3783
|
return this.registry.getApplicationTopics(appId);
|
|
3758
3784
|
}
|
|
3785
|
+
async getTopicIdByName(appId, name) {
|
|
3786
|
+
const topicId = await this.registry.getTopicIdByName(appId, name);
|
|
3787
|
+
return Number(topicId);
|
|
3788
|
+
}
|
|
3759
3789
|
async getTopicCount() {
|
|
3760
3790
|
const count = await this.registry.topicCount();
|
|
3761
3791
|
return Number(count);
|
|
@@ -3868,6 +3898,10 @@ var Clawntenna = class _Clawntenna {
|
|
|
3868
3898
|
};
|
|
3869
3899
|
}, "getApplication");
|
|
3870
3900
|
}
|
|
3901
|
+
async getApplicationIdByName(name) {
|
|
3902
|
+
const appId = await this.registry.applicationNames(name);
|
|
3903
|
+
return Number(appId);
|
|
3904
|
+
}
|
|
3871
3905
|
// ===== FEES =====
|
|
3872
3906
|
async getTopicMessageFee(topicId) {
|
|
3873
3907
|
const [token, amount] = await this.registry.getTopicMessageFee(topicId);
|
|
@@ -4200,6 +4234,65 @@ var Clawntenna = class _Clawntenna {
|
|
|
4200
4234
|
}
|
|
4201
4235
|
return results;
|
|
4202
4236
|
}
|
|
4237
|
+
async _readMessagesFromExplorer(topicId, limit, key) {
|
|
4238
|
+
const chain = CHAINS[this.chainName];
|
|
4239
|
+
if (!chain.explorerApi) {
|
|
4240
|
+
throw new Error(`Indexed history is not configured for ${this.chainName}.`);
|
|
4241
|
+
}
|
|
4242
|
+
const url = new URL(chain.explorerApi);
|
|
4243
|
+
url.searchParams.set("module", "logs");
|
|
4244
|
+
url.searchParams.set("action", "getLogs");
|
|
4245
|
+
url.searchParams.set("fromBlock", "0");
|
|
4246
|
+
url.searchParams.set("toBlock", "latest");
|
|
4247
|
+
url.searchParams.set("address", chain.registry);
|
|
4248
|
+
url.searchParams.set("topic0", ethers.id("MessageSent(uint256,address,bytes,uint256)"));
|
|
4249
|
+
url.searchParams.set("topic1", ethers.zeroPadValue(ethers.toBeHex(topicId), 32));
|
|
4250
|
+
url.searchParams.set("topic0_1_opr", "and");
|
|
4251
|
+
url.searchParams.set("page", "1");
|
|
4252
|
+
url.searchParams.set("offset", String(limit));
|
|
4253
|
+
url.searchParams.set("sort", "desc");
|
|
4254
|
+
if (this.historyApiKey) {
|
|
4255
|
+
url.searchParams.set("apikey", this.historyApiKey);
|
|
4256
|
+
}
|
|
4257
|
+
const response = await withRetry(() => fetch(url));
|
|
4258
|
+
if (!response.ok) {
|
|
4259
|
+
throw new Error(`Historical message lookup failed with HTTP ${response.status}.`);
|
|
4260
|
+
}
|
|
4261
|
+
const body = await response.json();
|
|
4262
|
+
if (Array.isArray(body.result)) {
|
|
4263
|
+
const iface = new ethers.Interface(REGISTRY_ABI);
|
|
4264
|
+
const decoded = body.result.map((log) => {
|
|
4265
|
+
const parsed = iface.parseLog({
|
|
4266
|
+
topics: log.topics,
|
|
4267
|
+
data: log.data
|
|
4268
|
+
});
|
|
4269
|
+
if (!parsed || parsed.name !== "MessageSent") return null;
|
|
4270
|
+
return this._decodeMessageLog(topicId, key, {
|
|
4271
|
+
args: parsed.args,
|
|
4272
|
+
transactionHash: log.transactionHash,
|
|
4273
|
+
blockNumber: Number(log.blockNumber)
|
|
4274
|
+
});
|
|
4275
|
+
}).filter((msg) => msg !== null);
|
|
4276
|
+
decoded.sort((a, b) => a.blockNumber - b.blockNumber);
|
|
4277
|
+
return decoded;
|
|
4278
|
+
}
|
|
4279
|
+
if (body.message === "No records found") {
|
|
4280
|
+
return [];
|
|
4281
|
+
}
|
|
4282
|
+
throw new Error(`Historical message lookup failed: ${body.message ?? "unexpected explorer response"}.`);
|
|
4283
|
+
}
|
|
4284
|
+
_decodeMessageLog(topicId, key, log) {
|
|
4285
|
+
const payloadStr = ethers.toUtf8String(log.args.payload);
|
|
4286
|
+
const content = decryptMessage(payloadStr, key);
|
|
4287
|
+
return {
|
|
4288
|
+
topicId,
|
|
4289
|
+
sender: log.args.sender,
|
|
4290
|
+
content,
|
|
4291
|
+
timestamp: Number(log.args.timestamp),
|
|
4292
|
+
txHash: log.transactionHash,
|
|
4293
|
+
blockNumber: log.blockNumber
|
|
4294
|
+
};
|
|
4295
|
+
}
|
|
4203
4296
|
// ===== ESCROW INBOX (deposit → message bridge) =====
|
|
4204
4297
|
/**
|
|
4205
4298
|
* Reverse lookup: find the transaction hash that created a deposit.
|
|
@@ -4266,7 +4359,7 @@ var Clawntenna = class _Clawntenna {
|
|
|
4266
4359
|
const receipt = await this.provider.getTransactionReceipt(txHash);
|
|
4267
4360
|
if (receipt) {
|
|
4268
4361
|
const msg = await this._parseMessageFromReceipt(receipt);
|
|
4269
|
-
messageText = msg
|
|
4362
|
+
messageText = msg ? getMessageText(msg.content) : null;
|
|
4270
4363
|
}
|
|
4271
4364
|
} catch {
|
|
4272
4365
|
}
|
|
@@ -4307,20 +4400,17 @@ var Clawntenna = class _Clawntenna {
|
|
|
4307
4400
|
const sender = parsed.args.sender;
|
|
4308
4401
|
const payloadBytes = parsed.args.payload;
|
|
4309
4402
|
const timestamp = Number(parsed.args.timestamp);
|
|
4310
|
-
let
|
|
4403
|
+
let content = null;
|
|
4311
4404
|
try {
|
|
4312
4405
|
const key = await this.getEncryptionKey(topicId);
|
|
4313
4406
|
const payloadStr = ethers.toUtf8String(payloadBytes);
|
|
4314
|
-
|
|
4315
|
-
if (result) text = result.text;
|
|
4407
|
+
content = decryptMessage(payloadStr, key);
|
|
4316
4408
|
} catch {
|
|
4317
4409
|
}
|
|
4318
4410
|
return {
|
|
4319
4411
|
topicId,
|
|
4320
4412
|
sender,
|
|
4321
|
-
|
|
4322
|
-
replyTo: null,
|
|
4323
|
-
mentions: null,
|
|
4413
|
+
content,
|
|
4324
4414
|
timestamp,
|
|
4325
4415
|
txHash: receipt.hash,
|
|
4326
4416
|
blockNumber: receipt.blockNumber
|
|
@@ -4906,8 +4996,8 @@ function validateKeyAddress(creds) {
|
|
|
4906
4996
|
}
|
|
4907
4997
|
}
|
|
4908
4998
|
async function runPostInit(address) {
|
|
4909
|
-
const { initState } = await import("./state-
|
|
4910
|
-
const { copySkillFiles } = await import("./skill-
|
|
4999
|
+
const { initState } = await import("./state-4PIASWQ4.js");
|
|
5000
|
+
const { copySkillFiles } = await import("./skill-Y3WBBCRF.js");
|
|
4911
5001
|
const stateResult = initState(address);
|
|
4912
5002
|
const skillResult = copySkillFiles();
|
|
4913
5003
|
return { stateResult, skillResult };
|
|
@@ -5019,8 +5109,8 @@ async function init(json = false) {
|
|
|
5019
5109
|
console.log(` Fund with ETH on Base or AVAX on Avalanche for gas`);
|
|
5020
5110
|
console.log("");
|
|
5021
5111
|
console.log("Next steps:");
|
|
5022
|
-
console.log(' npx clawntenna send
|
|
5023
|
-
console.log(
|
|
5112
|
+
console.log(' npx clawntenna send --app "ClawtennaChat" --topic "general" "gm!"');
|
|
5113
|
+
console.log(' npx clawntenna read --app "ClawtennaChat" --topic "general"');
|
|
5024
5114
|
}
|
|
5025
5115
|
}
|
|
5026
5116
|
function formatPostInit(stateResult, skillResult) {
|
|
@@ -5068,7 +5158,13 @@ function loadClient(flags, requireWallet = true) {
|
|
|
5068
5158
|
const chainId = chainIdForCredentials(flags.chain);
|
|
5069
5159
|
const credsRpc = creds?.chains[chainId]?.rpc;
|
|
5070
5160
|
const rpcUrl = flags.rpc ?? process.env.CLAWNTENNA_RPC_URL ?? credsRpc;
|
|
5071
|
-
|
|
5161
|
+
const historyApiKey = process.env.ROUTESCAN_API_KEY ?? process.env.BASESCAN_API_KEY;
|
|
5162
|
+
return new Clawntenna({
|
|
5163
|
+
chain: flags.chain,
|
|
5164
|
+
privateKey: privateKey ?? void 0,
|
|
5165
|
+
rpcUrl,
|
|
5166
|
+
historyApiKey
|
|
5167
|
+
});
|
|
5072
5168
|
}
|
|
5073
5169
|
function output(data, json) {
|
|
5074
5170
|
if (json) {
|