@sherwoodagent/cli 0.65.2 → 0.72.3
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/dist/{abis-4HWN2E3H.js → abis-KP7M4IPM.js} +4 -2
- package/dist/addresses-YDPUPGWQ.js +45 -0
- package/dist/{agent-AETROOEW.js → agent-6IRZUPFT.js} +10 -10
- package/dist/{agent-AETROOEW.js.map → agent-6IRZUPFT.js.map} +1 -1
- package/dist/{chat-JSSTSE4K.js → chat-G5M3OK6M.js} +37 -36
- package/dist/chat-G5M3OK6M.js.map +1 -0
- package/dist/{chunk-IL43IMOC.js → chunk-3NMJ4LUL.js} +23 -18
- package/dist/chunk-3NMJ4LUL.js.map +1 -0
- package/dist/{chunk-UBAX22KA.js → chunk-52U76TRE.js} +4 -4
- package/dist/chunk-52U76TRE.js.map +1 -0
- package/dist/{chunk-W2ZUPR3W.js → chunk-5DWB5Y7G.js} +9 -9
- package/dist/chunk-5DWB5Y7G.js.map +1 -0
- package/dist/{chunk-YZHZSBES.js → chunk-BQMOE4FJ.js} +144 -37
- package/dist/chunk-BQMOE4FJ.js.map +1 -0
- package/dist/{chunk-VYF2TXPX.js → chunk-D4SPHYXA.js} +6 -6
- package/dist/{chunk-UCQEEF3Z.js → chunk-FOAX5PGR.js} +6 -6
- package/dist/chunk-FOAX5PGR.js.map +1 -0
- package/dist/chunk-FOS47623.js +127 -0
- package/dist/chunk-FOS47623.js.map +1 -0
- package/dist/{chunk-2W4KGGPU.js → chunk-GSC7PVEO.js} +27 -27
- package/dist/chunk-GSC7PVEO.js.map +1 -0
- package/dist/chunk-HYUUR6SC.js +111 -0
- package/dist/chunk-HYUUR6SC.js.map +1 -0
- package/dist/{chunk-RO26TXXE.js → chunk-NWY2U753.js} +2 -2
- package/dist/chunk-RAITRCM7.js +308 -0
- package/dist/chunk-RAITRCM7.js.map +1 -0
- package/dist/{chunk-A6TOJEUD.js → chunk-S6XA7PK4.js} +124 -128
- package/dist/chunk-S6XA7PK4.js.map +1 -0
- package/dist/{chunk-O4G3SBCI.js → chunk-UUHWD7Y3.js} +109 -129
- package/dist/chunk-UUHWD7Y3.js.map +1 -0
- package/dist/{chunk-YJSCIQUZ.js → chunk-WECQ6NVS.js} +6 -6
- package/dist/chunk-WECQ6NVS.js.map +1 -0
- package/dist/{chunk-RHRLYVKM.js → chunk-ZYXFKVYF.js} +25 -12
- package/dist/chunk-ZYXFKVYF.js.map +1 -0
- package/dist/{client-KBBFAMEI.js → client-QN6SA76M.js} +4 -4
- package/dist/{config-REASKDIK.js → config-FAQO37S7.js} +10 -10
- package/dist/{cron-EOULYO3R.js → cron-QMLRWDJG.js} +19 -17
- package/dist/cron-QMLRWDJG.js.map +1 -0
- package/dist/{eas-K4ZBACYN.js → eas-HM2AUOEY.js} +7 -7
- package/dist/{governor-2CDSMSG7.js → governor-RRBTDGDX.js} +17 -13
- package/dist/index.js +2026 -1222
- package/dist/index.js.map +1 -1
- package/dist/{ipfs-FAYWUCS2.js → ipfs-VGWTUORE.js} +2 -2
- package/dist/{network-3ZU7UBDU.js → network-L6JKNYOJ.js} +7 -7
- package/dist/{price-LCTECRQP.js → price-AJ4JMHCT.js} +6 -6
- package/dist/{research-FUQOQWKK.js → research-6VEEPEPP.js} +22 -22
- package/dist/research-6VEEPEPP.js.map +1 -0
- package/dist/research-7Z6SFPPX.js +14 -0
- package/dist/{session-FJB2RV2X.js → session-PURMITWE.js} +28 -28
- package/dist/session-PURMITWE.js.map +1 -0
- package/dist/{session-XAW5UIXP.js → session-XBQY7SBJ.js} +2 -2
- package/dist/{trade-U7H5IFH6.js → trade-YTGLGCRQ.js} +34 -34
- package/dist/trade-YTGLGCRQ.js.map +1 -0
- package/dist/vault-NIPA5JV4.js +54 -0
- package/dist/vault-NIPA5JV4.js.map +1 -0
- package/dist/{xmtp-6NJ4PW6L.js → xmtp-M32JSE4I.js} +13 -12
- package/dist/xmtp-M32JSE4I.js.map +1 -0
- package/package.json +4 -3
- package/dist/addresses-J2LMGUCT.js +0 -35
- package/dist/chat-JSSTSE4K.js.map +0 -1
- package/dist/chunk-2LRC7I33.js +0 -186
- package/dist/chunk-2LRC7I33.js.map +0 -1
- package/dist/chunk-2W4KGGPU.js.map +0 -1
- package/dist/chunk-A6TOJEUD.js.map +0 -1
- package/dist/chunk-GWMTAW6A.js +0 -494
- package/dist/chunk-GWMTAW6A.js.map +0 -1
- package/dist/chunk-IL43IMOC.js.map +0 -1
- package/dist/chunk-O4G3SBCI.js.map +0 -1
- package/dist/chunk-RHRLYVKM.js.map +0 -1
- package/dist/chunk-UBAX22KA.js.map +0 -1
- package/dist/chunk-UCQEEF3Z.js.map +0 -1
- package/dist/chunk-W2ZUPR3W.js.map +0 -1
- package/dist/chunk-YJSCIQUZ.js.map +0 -1
- package/dist/chunk-YZHZSBES.js.map +0 -1
- package/dist/cron-EOULYO3R.js.map +0 -1
- package/dist/research-FUQOQWKK.js.map +0 -1
- package/dist/research-XEXTHDT3.js +0 -14
- package/dist/session-FJB2RV2X.js.map +0 -1
- package/dist/trade-U7H5IFH6.js.map +0 -1
- package/dist/xmtp-6NJ4PW6L.js.map +0 -1
- /package/dist/{abis-4HWN2E3H.js.map → abis-KP7M4IPM.js.map} +0 -0
- /package/dist/{addresses-J2LMGUCT.js.map → addresses-YDPUPGWQ.js.map} +0 -0
- /package/dist/{chunk-VYF2TXPX.js.map → chunk-D4SPHYXA.js.map} +0 -0
- /package/dist/{chunk-RO26TXXE.js.map → chunk-NWY2U753.js.map} +0 -0
- /package/dist/{client-KBBFAMEI.js.map → client-QN6SA76M.js.map} +0 -0
- /package/dist/{config-REASKDIK.js.map → config-FAQO37S7.js.map} +0 -0
- /package/dist/{eas-K4ZBACYN.js.map → eas-HM2AUOEY.js.map} +0 -0
- /package/dist/{governor-2CDSMSG7.js.map → governor-RRBTDGDX.js.map} +0 -0
- /package/dist/{ipfs-FAYWUCS2.js.map → ipfs-VGWTUORE.js.map} +0 -0
- /package/dist/{network-3ZU7UBDU.js.map → network-L6JKNYOJ.js.map} +0 -0
- /package/dist/{price-LCTECRQP.js.map → price-AJ4JMHCT.js.map} +0 -0
- /package/dist/{research-XEXTHDT3.js.map → research-7Z6SFPPX.js.map} +0 -0
- /package/dist/{session-XAW5UIXP.js.map → session-XBQY7SBJ.js.map} +0 -0
|
@@ -3,11 +3,11 @@ import {
|
|
|
3
3
|
pinJSON,
|
|
4
4
|
resolveMetadataSummary,
|
|
5
5
|
uploadMetadata
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ZYXFKVYF.js";
|
|
7
7
|
export {
|
|
8
8
|
fetchMetadata,
|
|
9
9
|
pinJSON,
|
|
10
10
|
resolveMetadataSummary,
|
|
11
11
|
uploadMetadata
|
|
12
12
|
};
|
|
13
|
-
//# sourceMappingURL=ipfs-
|
|
13
|
+
//# sourceMappingURL=ipfs-VGWTUORE.js.map
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CHAIN_REGISTRY,
|
|
3
|
+
DEFAULT_NETWORK,
|
|
3
4
|
VALID_NETWORKS,
|
|
5
|
+
applyChainIdOverride,
|
|
4
6
|
getChain,
|
|
5
7
|
getChainConfig,
|
|
6
8
|
getExplorerUrl,
|
|
7
9
|
getNetwork,
|
|
8
10
|
getRpcUrl,
|
|
9
11
|
getRpcUrls,
|
|
10
|
-
hyperevm,
|
|
11
|
-
hyperevmTestnet,
|
|
12
12
|
isTestnet,
|
|
13
13
|
robinhoodTestnet,
|
|
14
14
|
setNetwork,
|
|
15
15
|
withNetwork
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-HYUUR6SC.js";
|
|
17
|
+
import "./chunk-GSC7PVEO.js";
|
|
18
18
|
export {
|
|
19
19
|
CHAIN_REGISTRY,
|
|
20
|
+
DEFAULT_NETWORK,
|
|
20
21
|
VALID_NETWORKS,
|
|
22
|
+
applyChainIdOverride,
|
|
21
23
|
getChain,
|
|
22
24
|
getChainConfig,
|
|
23
25
|
getExplorerUrl,
|
|
24
26
|
getNetwork,
|
|
25
27
|
getRpcUrl,
|
|
26
28
|
getRpcUrls,
|
|
27
|
-
hyperevm,
|
|
28
|
-
hyperevmTestnet,
|
|
29
29
|
isTestnet,
|
|
30
30
|
robinhoodTestnet,
|
|
31
31
|
setNetwork,
|
|
32
32
|
withNetwork
|
|
33
33
|
};
|
|
34
|
-
//# sourceMappingURL=network-
|
|
34
|
+
//# sourceMappingURL=network-L6JKNYOJ.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SYNTHRA,
|
|
3
3
|
UNISWAP
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RAITRCM7.js";
|
|
5
5
|
import {
|
|
6
6
|
getPublicClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WECQ6NVS.js";
|
|
8
8
|
import {
|
|
9
9
|
getNetwork
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-HYUUR6SC.js";
|
|
11
|
+
import "./chunk-GSC7PVEO.js";
|
|
12
12
|
import {
|
|
13
13
|
UNISWAP_QUOTER_V2_ABI
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BQMOE4FJ.js";
|
|
15
15
|
|
|
16
16
|
// src/lib/price.ts
|
|
17
17
|
import { encodeFunctionData, decodeFunctionResult, parseUnits, formatUnits } from "viem";
|
|
@@ -155,4 +155,4 @@ export {
|
|
|
155
155
|
getTokenPriceInAsset,
|
|
156
156
|
getTokenPricesInAsset
|
|
157
157
|
};
|
|
158
|
-
//# sourceMappingURL=price-
|
|
158
|
+
//# sourceMappingURL=price-AJ4JMHCT.js.map
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
MESSARI_COST_ESTIMATE,
|
|
3
3
|
NANSEN_COST_ESTIMATE,
|
|
4
4
|
getResearchProvider
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-NWY2U753.js";
|
|
6
6
|
import {
|
|
7
7
|
formatContractError,
|
|
8
8
|
getAccount
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-WECQ6NVS.js";
|
|
10
|
+
import "./chunk-HYUUR6SC.js";
|
|
11
|
+
import "./chunk-GSC7PVEO.js";
|
|
12
12
|
|
|
13
13
|
// src/commands/research.ts
|
|
14
14
|
import chalk from "chalk";
|
|
@@ -16,7 +16,7 @@ import ora from "ora";
|
|
|
16
16
|
import { confirm } from "@inquirer/prompts";
|
|
17
17
|
import { isAddress } from "viem";
|
|
18
18
|
async function loadXmtp() {
|
|
19
|
-
return import("./xmtp-
|
|
19
|
+
return import("./xmtp-M32JSE4I.js");
|
|
20
20
|
}
|
|
21
21
|
var COST_ESTIMATES = {
|
|
22
22
|
messari: MESSARI_COST_ESTIMATE,
|
|
@@ -81,9 +81,9 @@ function formatValue(value) {
|
|
|
81
81
|
}
|
|
82
82
|
return String(value);
|
|
83
83
|
}
|
|
84
|
-
async function postResearch(
|
|
85
|
-
const { pinJSON } = await import("./ipfs-
|
|
86
|
-
const { createResearchAttestation, getEasScanUrl } = await import("./eas-
|
|
84
|
+
async function postResearch(fundName, result, prompt) {
|
|
85
|
+
const { pinJSON } = await import("./ipfs-VGWTUORE.js");
|
|
86
|
+
const { createResearchAttestation, getEasScanUrl } = await import("./eas-HM2AUOEY.js");
|
|
87
87
|
const xmtp = await loadXmtp();
|
|
88
88
|
const pinSpinner = ora("Pinning research result to IPFS...").start();
|
|
89
89
|
let resultUri;
|
|
@@ -112,8 +112,8 @@ async function postResearch(syndicateName, result, prompt) {
|
|
|
112
112
|
const easSpinner = ora("Creating EAS attestation...").start();
|
|
113
113
|
let attestationUid;
|
|
114
114
|
try {
|
|
115
|
-
const { getChainContracts } = await import("./config-
|
|
116
|
-
const { getChain } = await import("./network-
|
|
115
|
+
const { getChainContracts } = await import("./config-FAQO37S7.js");
|
|
116
|
+
const { getChain } = await import("./network-L6JKNYOJ.js");
|
|
117
117
|
const vaultRecipient = getChainContracts(getChain().id).vault;
|
|
118
118
|
const { uid } = await createResearchAttestation(
|
|
119
119
|
result.provider,
|
|
@@ -134,9 +134,9 @@ async function postResearch(syndicateName, result, prompt) {
|
|
|
134
134
|
);
|
|
135
135
|
return;
|
|
136
136
|
}
|
|
137
|
-
const chatSpinner = ora("Posting to
|
|
137
|
+
const chatSpinner = ora("Posting to fund chat...").start();
|
|
138
138
|
try {
|
|
139
|
-
const group = await xmtp.getGroup("",
|
|
139
|
+
const group = await xmtp.getGroup("", fundName);
|
|
140
140
|
await xmtp.sendEnvelope(group, {
|
|
141
141
|
type: "X402_RESEARCH",
|
|
142
142
|
from: getAccount().address,
|
|
@@ -151,7 +151,7 @@ async function postResearch(syndicateName, result, prompt) {
|
|
|
151
151
|
},
|
|
152
152
|
timestamp: result.timestamp
|
|
153
153
|
});
|
|
154
|
-
chatSpinner.succeed("Posted to
|
|
154
|
+
chatSpinner.succeed("Posted to fund chat");
|
|
155
155
|
} catch (err) {
|
|
156
156
|
chatSpinner.fail("Failed to post to chat");
|
|
157
157
|
console.error(
|
|
@@ -167,8 +167,8 @@ function registerResearchCommands(program) {
|
|
|
167
167
|
"--provider <name>",
|
|
168
168
|
"Research provider (messari, nansen)"
|
|
169
169
|
).option(
|
|
170
|
-
"--post <
|
|
171
|
-
"Post result to
|
|
170
|
+
"--post <fund>",
|
|
171
|
+
"Post result to fund chat (pin to IPFS + attest to EAS)"
|
|
172
172
|
).option("--yes", "Skip cost confirmation prompt", false).action(async (target, opts) => {
|
|
173
173
|
const ok = await confirmCost(opts.provider, "token", target, opts.yes);
|
|
174
174
|
if (!ok) {
|
|
@@ -198,8 +198,8 @@ function registerResearchCommands(program) {
|
|
|
198
198
|
"--provider <name>",
|
|
199
199
|
"Research provider (messari, nansen)"
|
|
200
200
|
).option(
|
|
201
|
-
"--post <
|
|
202
|
-
"Post result to
|
|
201
|
+
"--post <fund>",
|
|
202
|
+
"Post result to fund chat (pin to IPFS + attest to EAS)"
|
|
203
203
|
).option("--yes", "Skip cost confirmation prompt", false).action(async (asset, opts) => {
|
|
204
204
|
const ok = await confirmCost(opts.provider, "market", asset, opts.yes);
|
|
205
205
|
if (!ok) {
|
|
@@ -231,8 +231,8 @@ function registerResearchCommands(program) {
|
|
|
231
231
|
"--provider <name>",
|
|
232
232
|
"Research provider (messari, nansen)"
|
|
233
233
|
).option(
|
|
234
|
-
"--post <
|
|
235
|
-
"Post result to
|
|
234
|
+
"--post <fund>",
|
|
235
|
+
"Post result to fund chat (pin to IPFS + attest to EAS)"
|
|
236
236
|
).option("--yes", "Skip cost confirmation prompt", false).action(async (opts) => {
|
|
237
237
|
const ok = await confirmCost(opts.provider, "smart-money", opts.token, opts.yes);
|
|
238
238
|
if (!ok) {
|
|
@@ -274,8 +274,8 @@ function registerResearchCommands(program) {
|
|
|
274
274
|
"--provider <name>",
|
|
275
275
|
"Research provider (messari, nansen)"
|
|
276
276
|
).option(
|
|
277
|
-
"--post <
|
|
278
|
-
"Post result to
|
|
277
|
+
"--post <fund>",
|
|
278
|
+
"Post result to fund chat (pin to IPFS + attest to EAS)"
|
|
279
279
|
).option("--yes", "Skip cost confirmation prompt", false).action(async (address, opts) => {
|
|
280
280
|
if (!isAddress(address)) {
|
|
281
281
|
console.error(chalk.red(`Invalid wallet address: ${address}`));
|
|
@@ -312,4 +312,4 @@ function registerResearchCommands(program) {
|
|
|
312
312
|
export {
|
|
313
313
|
registerResearchCommands
|
|
314
314
|
};
|
|
315
|
-
//# sourceMappingURL=research-
|
|
315
|
+
//# sourceMappingURL=research-6VEEPEPP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/research.ts"],"sourcesContent":["/**\n * Research commands — sherwood research <subcommand>\n *\n * Query DeFi research providers (Messari, Nansen) using x402 micropayments.\n * Agent pays per-query with USDC from its own wallet — no vault interaction needed.\n *\n * --post <fund>: pins result to IPFS, creates EAS attestation, posts\n * lightweight notification to fund XMTP chat (not the full result).\n *\n * --yes: skip the cost confirmation prompt (for non-interactive / agent use).\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { isAddress } from \"viem\";\nimport { getAccount, formatContractError } from \"../lib/client.js\";\nimport type { MessageType } from \"../lib/types.js\";\nimport { getResearchProvider } from \"../providers/research/index.js\";\nimport type { ResearchResult } from \"../providers/research/index.js\";\nimport { MESSARI_COST_ESTIMATE } from \"../providers/research/messari.js\";\nimport { NANSEN_COST_ESTIMATE } from \"../providers/research/nansen.js\";\n\n// Lazy-load XMTP to avoid breaking non-chat commands when @xmtp/cli is missing\nasync function loadXmtp() {\n return import(\"../lib/xmtp.js\");\n}\n\n// ── Cost estimates ──\n\nconst COST_ESTIMATES: Record<string, Record<string, string>> = {\n messari: MESSARI_COST_ESTIMATE,\n nansen: NANSEN_COST_ESTIMATE,\n};\n\nfunction getEstimatedCost(provider: string, queryType: string): string {\n return COST_ESTIMATES[provider]?.[queryType] ?? \"unknown\";\n}\n\n/**\n * Confirm cost with the user before executing the x402 query.\n * Skipped when --yes is passed (non-interactive / agent mode).\n */\nasync function confirmCost(\n provider: string,\n queryType: string,\n target: string,\n skipConfirm: boolean,\n): Promise<boolean> {\n const estimate = getEstimatedCost(provider, queryType);\n\n console.log();\n console.log(chalk.bold(`Research Query`));\n console.log(chalk.dim(\"─\".repeat(40)));\n console.log(` Provider: ${provider}`);\n console.log(` Type: ${queryType}`);\n console.log(` Target: ${target}`);\n console.log(` Est. cost: ${chalk.yellow(estimate + \" USDC\")} (x402 micropayment)`);\n console.log();\n\n if (skipConfirm) return true;\n\n return confirm({\n message: `Pay ${estimate} USDC to ${provider} for this query?`,\n default: true,\n });\n}\n\n// ── Output formatting ──\n\nfunction formatResearchResult(result: ResearchResult): void {\n console.log();\n console.log(\n chalk.bold(`Research: ${result.queryType} ${result.target} (${result.provider})`),\n );\n console.log(chalk.dim(\"─\".repeat(50)));\n\n // Flatten the top-level data keys into a readable summary\n const data = result.data;\n for (const [key, value] of Object.entries(data)) {\n if (value === null || value === undefined) continue;\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n // Nested object — show as sub-section\n console.log(chalk.bold(`\\n ${key}`));\n for (const [subKey, subValue] of Object.entries(\n value as Record<string, unknown>,\n )) {\n console.log(` ${subKey}: ${formatValue(subValue)}`);\n }\n } else if (Array.isArray(value)) {\n console.log(` ${key}: ${chalk.dim(`[${value.length} items]`)}`);\n } else {\n console.log(` ${key}: ${formatValue(value)}`);\n }\n }\n\n console.log();\n console.log(\n chalk.dim(\n ` Cost: $${result.costUsdc} USDC • Provider: ${result.provider}`,\n ),\n );\n console.log();\n}\n\nfunction formatValue(value: unknown): string {\n if (typeof value === \"number\") {\n // Format large numbers with commas\n return value.toLocaleString(\"en-US\", { maximumFractionDigits: 4 });\n }\n if (typeof value === \"bigint\") {\n return value.toLocaleString(\"en-US\");\n }\n return String(value);\n}\n\n// ── Post flow: IPFS → EAS → XMTP ──\n\nasync function postResearch(\n fundName: string,\n result: ResearchResult,\n prompt: string,\n): Promise<void> {\n const { pinJSON } = await import(\"../lib/ipfs.js\");\n const { createResearchAttestation, getEasScanUrl } = await import(\n \"../lib/eas.js\"\n );\n const xmtp = await loadXmtp();\n\n // 1. Pin full research result to IPFS\n const pinSpinner = ora(\"Pinning research result to IPFS...\").start();\n let resultUri: string;\n try {\n resultUri = await pinJSON(\n {\n schema: \"sherwood/research/v1\",\n provider: result.provider,\n queryType: result.queryType,\n target: result.target,\n prompt,\n costUsdc: result.costUsdc,\n data: result.data,\n timestamp: result.timestamp,\n } as Record<string, unknown>,\n `sherwood-research-${result.provider}-${result.queryType}-${Date.now()}`,\n );\n pinSpinner.succeed(`Pinned to IPFS: ${chalk.dim(resultUri)}`);\n } catch (err) {\n pinSpinner.fail(\"Failed to pin to IPFS\");\n console.error(\n chalk.red(formatContractError(err)),\n );\n return;\n }\n\n // 2. Create EAS attestation with prompt, cost, provider, and IPFS URI\n // Recipient is vault so dashboard can display it under the fund\n const easSpinner = ora(\"Creating EAS attestation...\").start();\n let attestationUid: string;\n try {\n const { getChainContracts } = await import(\"../lib/config.js\");\n const { getChain } = await import(\"../lib/network.js\");\n const vaultRecipient = getChainContracts(getChain().id).vault as `0x${string}` | undefined;\n const { uid } = await createResearchAttestation(\n result.provider,\n result.queryType,\n prompt,\n result.costUsdc,\n resultUri,\n vaultRecipient,\n );\n attestationUid = uid;\n easSpinner.succeed(\n `Attested: ${chalk.dim(getEasScanUrl(uid))}`,\n );\n } catch (err) {\n easSpinner.fail(\"Failed to create EAS attestation\");\n console.error(\n chalk.red(formatContractError(err)),\n );\n return;\n }\n\n // 3. Post lightweight notification to XMTP chat\n const chatSpinner = ora(\"Posting to fund chat...\").start();\n try {\n const group = await xmtp.getGroup(\"\", fundName);\n await xmtp.sendEnvelope(group, {\n type: \"X402_RESEARCH\" as MessageType,\n from: getAccount().address,\n text: `Ran ${result.provider} ${result.queryType} on ${result.target} ($${result.costUsdc} USDC)`,\n data: {\n provider: result.provider,\n queryType: result.queryType,\n target: result.target,\n costUsdc: result.costUsdc,\n resultUri,\n attestationUid,\n },\n timestamp: result.timestamp,\n });\n chatSpinner.succeed(\"Posted to fund chat\");\n } catch (err) {\n chatSpinner.fail(\"Failed to post to chat\");\n console.error(\n chalk.red(formatContractError(err)),\n );\n }\n}\n\n// ── Command registration ──\n\nexport function registerResearchCommands(program: Command): void {\n const research = program\n .command(\"research\")\n .description(\n \"Query DeFi research providers via x402 micropayments (USDC on Base)\",\n );\n\n // ── research token <target> ──\n\n research\n .command(\"token <target>\")\n .description(\"Token report — profile, market data, on-chain metrics\")\n .requiredOption(\n \"--provider <name>\",\n \"Research provider (messari, nansen)\",\n )\n .option(\n \"--post <fund>\",\n \"Post result to fund chat (pin to IPFS + attest to EAS)\",\n )\n .option(\"--yes\", \"Skip cost confirmation prompt\", false)\n .action(async (target: string, opts: { provider: string; post?: string; yes: boolean }) => {\n const ok = await confirmCost(opts.provider, \"token\", target, opts.yes);\n if (!ok) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n\n const spinner = ora(\n `Querying ${opts.provider} for token ${target}...`,\n ).start();\n\n try {\n const provider = getResearchProvider(opts.provider);\n const result = await provider.query({ type: \"token\", target });\n spinner.succeed(`Token data received from ${opts.provider}`);\n formatResearchResult(result);\n\n if (opts.post) {\n await postResearch(opts.post, result, `token ${target}`);\n }\n } catch (err) {\n spinner.fail(`Token query failed`);\n console.error(\n chalk.red(formatContractError(err)),\n );\n process.exit(1);\n }\n });\n\n // ── research market <asset> ──\n\n research\n .command(\"market <asset>\")\n .description(\"Market overview — price, volume, market cap, ROI, ATH\")\n .requiredOption(\n \"--provider <name>\",\n \"Research provider (messari, nansen)\",\n )\n .option(\n \"--post <fund>\",\n \"Post result to fund chat (pin to IPFS + attest to EAS)\",\n )\n .option(\"--yes\", \"Skip cost confirmation prompt\", false)\n .action(async (asset: string, opts: { provider: string; post?: string; yes: boolean }) => {\n const ok = await confirmCost(opts.provider, \"market\", asset, opts.yes);\n if (!ok) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n\n const spinner = ora(\n `Querying ${opts.provider} for ${asset} market data...`,\n ).start();\n\n try {\n const provider = getResearchProvider(opts.provider);\n const result = await provider.query({ type: \"market\", target: asset });\n spinner.succeed(`Market data received from ${opts.provider}`);\n formatResearchResult(result);\n\n if (opts.post) {\n await postResearch(opts.post, result, `market ${asset}`);\n }\n } catch (err) {\n spinner.fail(`Market query failed`);\n console.error(\n chalk.red(formatContractError(err)),\n );\n process.exit(1);\n }\n });\n\n // ── research smart-money ──\n\n research\n .command(\"smart-money\")\n .description(\n \"Smart money flows — net flow, DEX trades, holdings from labeled wallets\",\n )\n .requiredOption(\"--token <symbol>\", \"Token symbol to analyze (e.g. WETH)\")\n .requiredOption(\n \"--provider <name>\",\n \"Research provider (messari, nansen)\",\n )\n .option(\n \"--post <fund>\",\n \"Post result to fund chat (pin to IPFS + attest to EAS)\",\n )\n .option(\"--yes\", \"Skip cost confirmation prompt\", false)\n .action(async (opts: { token: string; provider: string; post?: string; yes: boolean }) => {\n const ok = await confirmCost(opts.provider, \"smart-money\", opts.token, opts.yes);\n if (!ok) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n\n const spinner = ora(\n `Querying ${opts.provider} for ${opts.token} smart money flows...`,\n ).start();\n\n try {\n const provider = getResearchProvider(opts.provider);\n const result = await provider.query({\n type: \"smart-money\",\n target: opts.token,\n options: { token: opts.token },\n });\n spinner.succeed(\n `Smart money data received from ${opts.provider}`,\n );\n formatResearchResult(result);\n\n if (opts.post) {\n await postResearch(\n opts.post,\n result,\n `smart-money --token ${opts.token}`,\n );\n }\n } catch (err) {\n spinner.fail(`Smart money query failed`);\n console.error(\n chalk.red(formatContractError(err)),\n );\n process.exit(1);\n }\n });\n\n // ── research wallet <address> ──\n\n research\n .command(\"wallet <address>\")\n .description(\n \"Wallet due diligence — PnL history, transaction patterns, counterparties\",\n )\n .requiredOption(\n \"--provider <name>\",\n \"Research provider (messari, nansen)\",\n )\n .option(\n \"--post <fund>\",\n \"Post result to fund chat (pin to IPFS + attest to EAS)\",\n )\n .option(\"--yes\", \"Skip cost confirmation prompt\", false)\n .action(async (address: string, opts: { provider: string; post?: string; yes: boolean }) => {\n if (!isAddress(address)) {\n console.error(chalk.red(`Invalid wallet address: ${address}`));\n process.exit(1);\n }\n\n const ok = await confirmCost(opts.provider, \"wallet\", address, opts.yes);\n if (!ok) {\n console.log(chalk.dim(\"Cancelled.\"));\n return;\n }\n\n const spinner = ora(\n `Querying ${opts.provider} for wallet ${address.slice(0, 8)}...`,\n ).start();\n\n try {\n const provider = getResearchProvider(opts.provider);\n const result = await provider.query({\n type: \"wallet\",\n target: address,\n });\n spinner.succeed(`Wallet data received from ${opts.provider}`);\n formatResearchResult(result);\n\n if (opts.post) {\n await postResearch(opts.post, result, `wallet ${address}`);\n }\n } catch (err) {\n spinner.fail(`Wallet query failed`);\n console.error(\n chalk.red(formatContractError(err)),\n );\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MessariProvider,
|
|
3
|
+
NansenProvider,
|
|
4
|
+
getResearchProvider
|
|
5
|
+
} from "./chunk-NWY2U753.js";
|
|
6
|
+
import "./chunk-WECQ6NVS.js";
|
|
7
|
+
import "./chunk-HYUUR6SC.js";
|
|
8
|
+
import "./chunk-GSC7PVEO.js";
|
|
9
|
+
export {
|
|
10
|
+
MessariProvider,
|
|
11
|
+
NansenProvider,
|
|
12
|
+
getResearchProvider
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=research-7Z6SFPPX.js.map
|
|
@@ -3,30 +3,30 @@ import {
|
|
|
3
3
|
getSession,
|
|
4
4
|
resetSession,
|
|
5
5
|
updateSession
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5DWB5Y7G.js";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
} from "./chunk-
|
|
8
|
+
resolveFund
|
|
9
|
+
} from "./chunk-FOS47623.js";
|
|
10
|
+
import "./chunk-UUHWD7Y3.js";
|
|
10
11
|
import {
|
|
11
12
|
PROPOSAL_STATES,
|
|
13
|
+
getGovernorOf,
|
|
12
14
|
getProposal
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import
|
|
15
|
-
SHERWOOD
|
|
16
|
-
} from "./chunk-GWMTAW6A.js";
|
|
15
|
+
} from "./chunk-S6XA7PK4.js";
|
|
16
|
+
import "./chunk-RAITRCM7.js";
|
|
17
17
|
import {
|
|
18
18
|
getPublicClient
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-WECQ6NVS.js";
|
|
20
|
+
import "./chunk-HYUUR6SC.js";
|
|
21
21
|
import {
|
|
22
22
|
loadConfig
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-GSC7PVEO.js";
|
|
24
24
|
import {
|
|
25
25
|
SYNDICATE_VAULT_ABI
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-BQMOE4FJ.js";
|
|
27
27
|
import {
|
|
28
28
|
resolveMetadataSummary
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-ZYXFKVYF.js";
|
|
30
30
|
|
|
31
31
|
// src/commands/session.ts
|
|
32
32
|
import chalk from "chalk";
|
|
@@ -128,7 +128,7 @@ var PROPOSAL_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
128
128
|
"ProposalSettled",
|
|
129
129
|
"ProposalCancelled"
|
|
130
130
|
]);
|
|
131
|
-
async function enrichProposalEvents(events, metadataCache) {
|
|
131
|
+
async function enrichProposalEvents(vault, events, metadataCache) {
|
|
132
132
|
const cache = metadataCache ?? /* @__PURE__ */ new Map();
|
|
133
133
|
const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));
|
|
134
134
|
if (proposalEvents.length === 0) return events;
|
|
@@ -147,7 +147,7 @@ async function enrichProposalEvents(events, metadataCache) {
|
|
|
147
147
|
await Promise.all(
|
|
148
148
|
Array.from(idsNeedingLookup).map(async (pid) => {
|
|
149
149
|
try {
|
|
150
|
-
const p = await getProposal(BigInt(pid));
|
|
150
|
+
const p = await getProposal(vault, BigInt(pid));
|
|
151
151
|
proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });
|
|
152
152
|
} catch {
|
|
153
153
|
}
|
|
@@ -187,7 +187,7 @@ async function enrichProposalEvents(events, metadataCache) {
|
|
|
187
187
|
|
|
188
188
|
// src/commands/session.ts
|
|
189
189
|
async function loadXmtp() {
|
|
190
|
-
return import("./xmtp-
|
|
190
|
+
return import("./xmtp-M32JSE4I.js");
|
|
191
191
|
}
|
|
192
192
|
async function resolveGovernor(vaultAddress) {
|
|
193
193
|
const client = getPublicClient();
|
|
@@ -199,7 +199,7 @@ async function resolveGovernor(vaultAddress) {
|
|
|
199
199
|
});
|
|
200
200
|
return governor;
|
|
201
201
|
} catch {
|
|
202
|
-
return
|
|
202
|
+
return getGovernorOf(vaultAddress);
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
function toSessionMessage(msg) {
|
|
@@ -223,8 +223,8 @@ function toSessionMessage(msg) {
|
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
225
|
async function handleCheck(name, stream, noXmtp) {
|
|
226
|
-
const
|
|
227
|
-
const vaultAddress =
|
|
226
|
+
const fund = await resolveFund(name);
|
|
227
|
+
const vaultAddress = fund.vault;
|
|
228
228
|
const governorAddress = await resolveGovernor(vaultAddress);
|
|
229
229
|
const session = getSession(name);
|
|
230
230
|
const currentBlock = await getCurrentBlock();
|
|
@@ -260,12 +260,12 @@ async function handleCheck(name, stream, noXmtp) {
|
|
|
260
260
|
);
|
|
261
261
|
events = [...vaultEvents, ...govEvents].sort((a, b) => a.block - b.block);
|
|
262
262
|
try {
|
|
263
|
-
events = await enrichProposalEvents(events);
|
|
263
|
+
events = await enrichProposalEvents(vaultAddress, events);
|
|
264
264
|
} catch {
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
const result = {
|
|
268
|
-
|
|
268
|
+
fund: name,
|
|
269
269
|
messages,
|
|
270
270
|
events,
|
|
271
271
|
meta: {
|
|
@@ -342,7 +342,7 @@ async function startStream(name, vaultAddress, governorAddress, noXmtp) {
|
|
|
342
342
|
(a, b) => a.block - b.block
|
|
343
343
|
);
|
|
344
344
|
try {
|
|
345
|
-
events = await enrichProposalEvents(events, metadataCache);
|
|
345
|
+
events = await enrichProposalEvents(vaultAddress, events, metadataCache);
|
|
346
346
|
} catch {
|
|
347
347
|
}
|
|
348
348
|
for (const event of events) {
|
|
@@ -434,16 +434,16 @@ function registerSessionCommands(program) {
|
|
|
434
434
|
}
|
|
435
435
|
);
|
|
436
436
|
session.command("cron <name>").description("Manage participation crons (OpenClaw agents)").option("--remove", "Remove participation crons", false).option("--status", "Show cron status", false).action(async (name, opts) => {
|
|
437
|
-
const { isOpenClaw,
|
|
438
|
-
const { isTestnet } = await import("./network-
|
|
439
|
-
const { getNotifyTo } = await import("./config-
|
|
437
|
+
const { isOpenClaw, registerFundCrons, unregisterFundCrons, getFundCronStatus } = await import("./cron-QMLRWDJG.js");
|
|
438
|
+
const { isTestnet } = await import("./network-L6JKNYOJ.js");
|
|
439
|
+
const { getNotifyTo } = await import("./config-FAQO37S7.js");
|
|
440
440
|
if (!isOpenClaw()) {
|
|
441
441
|
console.log(chalk.yellow("Not running on OpenClaw \u2014 cron commands unavailable"));
|
|
442
442
|
console.log(chalk.dim(` Set up your own scheduler: sherwood session check ${name} --stream`));
|
|
443
443
|
return;
|
|
444
444
|
}
|
|
445
445
|
if (opts.status) {
|
|
446
|
-
const status =
|
|
446
|
+
const status = getFundCronStatus(name, isTestnet());
|
|
447
447
|
if (status.crons.length === 0) {
|
|
448
448
|
console.log(chalk.dim("No participation crons found for " + name));
|
|
449
449
|
return;
|
|
@@ -458,7 +458,7 @@ function registerSessionCommands(program) {
|
|
|
458
458
|
return;
|
|
459
459
|
}
|
|
460
460
|
if (opts.remove) {
|
|
461
|
-
const result2 =
|
|
461
|
+
const result2 = unregisterFundCrons(name, isTestnet());
|
|
462
462
|
if (result2.removed) {
|
|
463
463
|
console.log(chalk.green("Participation crons removed"));
|
|
464
464
|
} else {
|
|
@@ -466,7 +466,7 @@ function registerSessionCommands(program) {
|
|
|
466
466
|
}
|
|
467
467
|
return;
|
|
468
468
|
}
|
|
469
|
-
const result =
|
|
469
|
+
const result = registerFundCrons(name, isTestnet(), getNotifyTo());
|
|
470
470
|
if (result.registered) {
|
|
471
471
|
console.log(chalk.green("Participation crons registered: " + result.cronNames.join(", ")));
|
|
472
472
|
} else {
|
|
@@ -477,4 +477,4 @@ function registerSessionCommands(program) {
|
|
|
477
477
|
export {
|
|
478
478
|
registerSessionCommands
|
|
479
479
|
};
|
|
480
|
-
//# sourceMappingURL=session-
|
|
480
|
+
//# sourceMappingURL=session-PURMITWE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/session.ts","../src/lib/events.ts"],"sourcesContent":["/**\n * Session commands — sherwood session check|status|reset\n *\n * Provides agent awareness: catch up on XMTP messages and on-chain events\n * since the last session. Supports one-shot polling (default) and persistent\n * streaming (--stream).\n *\n * Usage:\n * sherwood session check <name> — one-shot catch-up (JSON to stdout)\n * sherwood session check <name> --stream — persistent stream (JSON lines to stdout)\n * sherwood session check <name> --no-xmtp — skip XMTP entirely (on-chain events only)\n * sherwood session status [name] — show session cursor positions\n * sherwood session reset <name> [--full] — reset session cursors\n *\n * Env: SHERWOOD_SKIP_XMTP=1 is equivalent to --no-xmtp.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport type { Address } from \"viem\";\nimport { resolveFund } from \"../lib/ens.js\";\nimport { getPublicClient } from \"../lib/client.js\";\nimport { getGovernorOf } from \"../lib/governor.js\";\nimport { SYNDICATE_VAULT_ABI } from \"../lib/abis.js\";\nimport {\n getSession,\n updateSession,\n resetSession,\n getAllSessions,\n} from \"../lib/session.js\";\nimport {\n getVaultEvents,\n getGovernorEvents,\n getCurrentBlock,\n enrichProposalEvents,\n type ChainEvent,\n} from \"../lib/events.js\";\nimport type { ChatEnvelope } from \"../lib/types.js\";\nimport { loadConfig } from \"../lib/config.js\";\n\n// Lazy-load XMTP to avoid breaking session commands when @xmtp/cli is missing\nasync function loadXmtp() {\n return import(\"../lib/xmtp.js\");\n}\n\n// ── Output types ──\n\ninterface SessionMessage {\n source: \"xmtp\";\n id: string;\n from: string;\n type: string;\n text: string;\n sentAt: string; // ISO 8601\n}\n\ninterface SessionCheckResult {\n fund: string;\n messages: SessionMessage[];\n events: ChainEvent[];\n meta: {\n newMessages: number;\n newEvents: number;\n blocksScanned: number;\n lastCheckAt: string; // ISO 8601\n };\n}\n\n// ── Helpers ──\n\n/** Resolve the per-vault governor address from the vault contract. */\nasync function resolveGovernor(vaultAddress: Address): Promise<Address> {\n const client = getPublicClient();\n try {\n const governor = await client.readContract({\n address: vaultAddress,\n abi: SYNDICATE_VAULT_ABI,\n functionName: \"governor\",\n });\n return governor as Address;\n } catch {\n // Vault didn't answer — fall back to the factory's per-vault mapping.\n return getGovernorOf(vaultAddress);\n }\n}\n\n/** Convert an XMTP message to session output format. */\nfunction toSessionMessage(msg: {\n id: string;\n senderInboxId: string;\n content: string;\n sentAt: Date;\n}): SessionMessage {\n let type = \"MESSAGE\";\n let text = msg.content;\n let from = msg.senderInboxId;\n\n try {\n const envelope: ChatEnvelope = JSON.parse(msg.content);\n type = envelope.type;\n text = envelope.text || envelope.type;\n from = envelope.from || msg.senderInboxId;\n } catch {\n // Plain text message\n }\n\n return {\n source: \"xmtp\",\n id: msg.id,\n from,\n type,\n text,\n sentAt: msg.sentAt.toISOString(),\n };\n}\n\n// ── Command handlers ──\n\nasync function handleCheck(\n name: string,\n stream: boolean,\n noXmtp: boolean,\n): Promise<void> {\n // Resolve fund\n const fund = await resolveFund(name);\n const vaultAddress = fund.vault;\n const governorAddress = await resolveGovernor(vaultAddress);\n\n // Load or initialize session\n const session = getSession(name);\n const currentBlock = await getCurrentBlock();\n\n // On first run: look back ~1000 blocks (~8 min on Base)\n const fromBlock = session?.lastBlockNumber\n ? BigInt(session.lastBlockNumber) + 1n\n : currentBlock > 1000n\n ? currentBlock - 1000n\n : 0n;\n\n const lastMessageTimestamp = session?.lastMessageTimestamp || 0;\n\n // ── Fetch XMTP messages ──\n // Skipped entirely when noXmtp is true — used by callers that own XMTP\n // themselves (e.g. the sherwood-monitor Hermes plugin via its bundled\n // sidecar) or when the local @xmtp/node-bindings load would fail.\n let messages: SessionMessage[] = [];\n if (!noXmtp) {\n try {\n const xmtp = await loadXmtp();\n const groupId = await xmtp.getGroup(\"\", name);\n const recent = await xmtp.getRecentMessages(groupId, 100);\n\n // Filter to messages after our cursor, excluding our own messages\n const cursorMs = lastMessageTimestamp * 1000;\n const ownInboxId = loadConfig().xmtpInboxId;\n const newMessages = recent.filter(\n (m) =>\n m.sentAt.getTime() > cursorMs &&\n (!ownInboxId || m.senderInboxId !== ownInboxId),\n );\n messages = newMessages.map(toSessionMessage);\n } catch {\n // XMTP not available or group not found — skip messages\n }\n }\n\n // ── Fetch on-chain events ──\n let events: ChainEvent[] = [];\n if (fromBlock <= currentBlock) {\n const vaultEvents = await getVaultEvents(\n vaultAddress,\n fromBlock,\n currentBlock,\n );\n const govEvents = await getGovernorEvents(\n governorAddress,\n vaultAddress,\n fromBlock,\n currentBlock,\n );\n events = [...vaultEvents, ...govEvents].sort((a, b) => a.block - b.block);\n\n // Enrich proposal events with IPFS metadata (name, description, state)\n try {\n events = await enrichProposalEvents(vaultAddress, events);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\n }\n }\n\n // ── Output initial catch-up result ──\n const result: SessionCheckResult = {\n fund: name,\n messages,\n events,\n meta: {\n newMessages: messages.length,\n newEvents: events.length,\n blocksScanned: Number(currentBlock - fromBlock),\n lastCheckAt: session?.lastCheckAt\n ? new Date(session.lastCheckAt * 1000).toISOString()\n : \"never\",\n },\n };\n\n process.stdout.write(JSON.stringify(result) + \"\\n\");\n\n // ── Update session state ──\n // Find the newest message timestamp (messages may not be sorted)\n // Use ceil to ensure we don't re-fetch the same message due to sub-second precision\n let newestTimestamp = lastMessageTimestamp;\n let newestMessageId = session?.lastMessageId || \"\";\n for (const msg of messages) {\n const ts = Math.ceil(new Date(msg.sentAt).getTime() / 1000);\n if (ts > newestTimestamp) {\n newestTimestamp = ts;\n newestMessageId = msg.id;\n }\n }\n\n updateSession(name, {\n vault: vaultAddress,\n governor: governorAddress,\n lastBlockNumber: Number(currentBlock),\n lastCheckAt: Math.floor(Date.now() / 1000),\n lastMessageId: newestMessageId,\n lastMessageTimestamp: newestTimestamp,\n totalMessagesProcessed:\n (session?.totalMessagesProcessed || 0) + messages.length,\n totalEventsProcessed:\n (session?.totalEventsProcessed || 0) + events.length,\n });\n\n // ── If --stream, stay alive ──\n if (stream) {\n await startStream(name, vaultAddress, governorAddress, noXmtp);\n }\n}\n\nasync function startStream(\n name: string,\n vaultAddress: Address,\n governorAddress: Address,\n noXmtp: boolean,\n): Promise<void> {\n // Cache for proposal metadata — immutable once pinned, safe to reuse across polls\n const metadataCache = new Map<string, { name: string; description: string }>();\n\n // Start XMTP message stream\n // Skipped entirely when noXmtp is true — see handleCheck for the rationale.\n // xmtpCleanup stays undefined in that case; the on-exit cleanup does\n // `xmtpCleanup?.()` which is a no-op on undefined, so teardown is unaffected.\n let xmtpCleanup: (() => void) | undefined;\n if (!noXmtp) {\n try {\n const xmtp = await loadXmtp();\n const groupId = await xmtp.getGroup(\"\", name);\n\n const streamOwnInboxId = loadConfig().xmtpInboxId;\n xmtpCleanup = await xmtp.streamMessages(groupId, (msg) => {\n // Skip own messages to prevent self-replies\n if (streamOwnInboxId && msg.senderInboxId === streamOwnInboxId) return;\n\n const sessionMsg = toSessionMessage(msg);\n process.stdout.write(JSON.stringify(sessionMsg) + \"\\n\");\n\n // Update session state incrementally\n updateSession(name, {\n lastMessageId: msg.id,\n lastMessageTimestamp: Math.floor(msg.sentAt.getTime() / 1000),\n lastCheckAt: Math.floor(Date.now() / 1000),\n totalMessagesProcessed:\n (getSession(name)?.totalMessagesProcessed || 0) + 1,\n });\n });\n } catch {\n // XMTP not available — continue with event polling only\n }\n }\n\n // Start on-chain event polling (~30s interval)\n const pollInterval = setInterval(async () => {\n try {\n const session = getSession(name);\n const fromBlock = BigInt(session?.lastBlockNumber || 0) + 1n;\n const toBlock = await getCurrentBlock();\n\n if (fromBlock > toBlock) return; // No new blocks\n\n const vaultEvents = await getVaultEvents(\n vaultAddress,\n fromBlock,\n toBlock,\n );\n const govEvents = await getGovernorEvents(\n governorAddress,\n vaultAddress,\n fromBlock,\n toBlock,\n );\n\n let events = [...vaultEvents, ...govEvents].sort(\n (a, b) => a.block - b.block,\n );\n\n // Enrich proposal events with IPFS metadata (reuse cache across polls)\n try {\n events = await enrichProposalEvents(vaultAddress, events, metadataCache);\n } catch {\n // IPFS/RPC unreachable — continue with raw events\n }\n\n for (const event of events) {\n process.stdout.write(JSON.stringify(event) + \"\\n\");\n }\n\n updateSession(name, {\n lastBlockNumber: Number(toBlock),\n lastCheckAt: Math.floor(Date.now() / 1000),\n totalEventsProcessed:\n (getSession(name)?.totalEventsProcessed || 0) + events.length,\n });\n } catch {\n // RPC error — skip this poll cycle\n }\n }, 30_000);\n\n // Clean up on exit\n const cleanup = () => {\n clearInterval(pollInterval);\n xmtpCleanup?.();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", cleanup);\n process.on(\"SIGTERM\", cleanup);\n\n // Keep alive\n await new Promise(() => {});\n}\n\nasync function handleStatus(name?: string): Promise<void> {\n const sessions = getAllSessions();\n\n if (name) {\n const session = sessions[name];\n if (!session) {\n console.log(\n chalk.dim(`No session found for \"${name}\". Run \"sherwood session check ${name}\" first.`),\n );\n return;\n }\n console.log(JSON.stringify({ [name]: formatSessionStatus(session) }, null, 2));\n return;\n }\n\n // Show all sessions\n if (Object.keys(sessions).length === 0) {\n console.log(chalk.dim(\"No sessions found. Run \\\"sherwood session check <name>\\\" to start.\"));\n return;\n }\n\n const output: Record<string, ReturnType<typeof formatSessionStatus>> = {};\n for (const [subdomain, session] of Object.entries(sessions)) {\n output[subdomain] = formatSessionStatus(session);\n }\n console.log(JSON.stringify(output, null, 2));\n}\n\nfunction formatSessionStatus(session: {\n lastCheckAt: number;\n lastBlockNumber: number;\n totalMessagesProcessed: number;\n totalEventsProcessed: number;\n}) {\n return {\n lastCheckAt: session.lastCheckAt\n ? new Date(session.lastCheckAt * 1000).toISOString()\n : \"never\",\n lastBlockNumber: session.lastBlockNumber,\n totalMessagesProcessed: session.totalMessagesProcessed,\n totalEventsProcessed: session.totalEventsProcessed,\n };\n}\n\nasync function handleReset(\n name: string,\n sinceBlock?: string,\n full?: boolean,\n): Promise<void> {\n if (full || !sinceBlock) {\n resetSession(name);\n console.log(chalk.green(`Session for \"${name}\" has been reset.`));\n } else {\n const block = parseInt(sinceBlock, 10);\n if (isNaN(block)) {\n console.error(chalk.red(\"--since-block must be a number\"));\n process.exit(1);\n }\n resetSession(name, block);\n console.log(\n chalk.green(`Block cursor for \"${name}\" reset to ${block}.`),\n );\n }\n}\n\n// ── Command Registration ──\n\nexport function registerSessionCommands(program: Command): void {\n const session = program\n .command(\"session\")\n .description(\"Agent session — catch up on messages + on-chain events\");\n\n session\n .command(\"check <name>\")\n .description(\"Fetch new XMTP messages and on-chain events since last check\")\n .option(\"--stream\", \"Stay alive streaming messages and polling events\", false)\n .option(\n \"--no-xmtp\",\n \"Skip XMTP catch-up and streaming. Use when XMTP bindings are unavailable or when an external process owns XMTP (e.g. the sherwood-monitor Hermes plugin's bundled sidecar). Also honors SHERWOOD_SKIP_XMTP=1.\",\n false,\n )\n .action(\n async (name: string, opts: { stream: boolean; noXmtp: boolean }) => {\n const skipXmtp =\n opts.noXmtp || process.env.SHERWOOD_SKIP_XMTP === \"1\";\n await handleCheck(name, opts.stream, skipXmtp);\n },\n );\n\n session\n .command(\"status [name]\")\n .description(\"Show session cursor positions\")\n .action(async (name?: string) => {\n await handleStatus(name);\n });\n\n session\n .command(\"reset <name>\")\n .description(\"Reset session cursors\")\n .option(\"--since-block <n>\", \"Reset block cursor to a specific block\")\n .option(\"--full\", \"Reset everything (messages + events)\", false)\n .action(\n async (\n name: string,\n opts: { sinceBlock?: string; full: boolean },\n ) => {\n await handleReset(name, opts.sinceBlock, opts.full);\n },\n );\n\n session\n .command(\"cron <name>\")\n .description(\"Manage participation crons (OpenClaw agents)\")\n .option(\"--remove\", \"Remove participation crons\", false)\n .option(\"--status\", \"Show cron status\", false)\n .action(async (name: string, opts: { remove: boolean; status: boolean }) => {\n const { isOpenClaw, registerFundCrons, unregisterFundCrons, getFundCronStatus } =\n await import(\"../lib/cron.js\");\n const { isTestnet } = await import(\"../lib/network.js\");\n const { getNotifyTo } = await import(\"../lib/config.js\");\n\n if (!isOpenClaw()) {\n console.log(chalk.yellow(\"Not running on OpenClaw — cron commands unavailable\"));\n console.log(chalk.dim(` Set up your own scheduler: sherwood session check ${name} --stream`));\n return;\n }\n\n if (opts.status) {\n const status = getFundCronStatus(name, isTestnet());\n if (status.crons.length === 0) {\n console.log(chalk.dim(\"No participation crons found for \" + name));\n return;\n }\n console.log();\n console.log(chalk.bold(`Participation Crons — ${name}`));\n console.log(chalk.dim(\"─\".repeat(50)));\n for (const cron of status.crons) {\n console.log(` ${chalk.green(cron.name)} every ${cron.every}${cron.lastRun ? ` last: ${cron.lastRun}` : \"\"}`);\n }\n console.log();\n return;\n }\n\n if (opts.remove) {\n const result = unregisterFundCrons(name, isTestnet());\n if (result.removed) {\n console.log(chalk.green(\"Participation crons removed\"));\n } else {\n console.log(chalk.dim(\"No crons found to remove\"));\n }\n return;\n }\n\n // Register/update\n const result = registerFundCrons(name, isTestnet(), getNotifyTo());\n if (result.registered) {\n console.log(chalk.green(\"Participation crons registered: \" + result.cronNames.join(\", \")));\n } else {\n console.log(chalk.dim(\"Crons already registered\"));\n }\n });\n}\n","/**\n * On-chain event reader — fetches vault and governor events via viem getLogs.\n *\n * Uses HTTP RPC (no WebSocket needed). Block ranges are capped at 10,000\n * per call to avoid RPC timeouts (~83 minutes on Base at 2 blocks/sec).\n */\n\nimport type { Address, Log } from \"viem\";\nimport { parseAbiItem } from \"viem\";\nimport { getPublicClient } from \"./client.js\";\nimport { getProposal, PROPOSAL_STATES } from \"./governor.js\";\nimport { resolveMetadataSummary } from \"./ipfs.js\";\n\nconst MAX_BLOCK_RANGE = 10_000n;\n\n// ── Event signatures (parseAbiItem format for getLogs) ──\n\nconst VAULT_EVENTS = [\n parseAbiItem(\"event AgentRegistered(uint256 indexed agentId, address indexed agentAddress)\"),\n parseAbiItem(\"event AgentRemoved(address indexed agentAddress)\"),\n parseAbiItem(\"event DepositorApproved(address indexed depositor)\"),\n parseAbiItem(\"event DepositorRemoved(address indexed depositor)\"),\n parseAbiItem(\"event RedemptionsLockedEvent()\"),\n parseAbiItem(\"event RedemptionsUnlockedEvent()\"),\n] as const;\n\nconst GOVERNOR_EVENTS = [\n parseAbiItem(\"event ProposalCreated(uint256 indexed proposalId, address indexed proposer, address indexed vault, uint256 performanceFeeBps, uint256 strategyDuration, uint256 executeCallCount, uint256 settlementCallCount, string metadataURI)\"),\n parseAbiItem(\"event VoteCast(uint256 indexed proposalId, address indexed voter, uint8 support, uint256 weight)\"),\n parseAbiItem(\"event ProposalExecuted(uint256 indexed proposalId, address indexed vault, uint256 capitalSnapshot)\"),\n parseAbiItem(\"event ProposalSettled(uint256 indexed proposalId, address indexed vault, int256 pnl, uint256 performanceFee, uint256 duration)\"),\n parseAbiItem(\"event ProposalCancelled(uint256 indexed proposalId, address indexed cancelledBy)\"),\n] as const;\n\n/** Normalized event returned by the session check. */\nexport interface ChainEvent {\n source: \"chain\";\n type: string;\n block: number;\n tx: string;\n args: Record<string, string>;\n}\n\nfunction logToChainEvent(log: Log, eventName: string): ChainEvent {\n const args: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoded = (log as any).args;\n if (decoded) {\n for (const [key, value] of Object.entries(decoded)) {\n args[key] = String(value);\n }\n }\n\n return {\n source: \"chain\",\n type: eventName,\n block: Number(log.blockNumber),\n tx: log.transactionHash || \"\",\n args,\n };\n}\n\n/**\n * Fetch events in chunks to stay within RPC limits.\n * Returns all logs from `fromBlock` to `toBlock` inclusive.\n */\nasync function getLogsChunked(params: {\n address: Address;\n events: readonly ReturnType<typeof parseAbiItem>[];\n fromBlock: bigint;\n toBlock: bigint;\n}): Promise<Log[]> {\n const client = getPublicClient();\n const { address, events, fromBlock, toBlock } = params;\n\n const allLogs: Log[] = [];\n let cursor = fromBlock;\n\n while (cursor <= toBlock) {\n const end =\n cursor + MAX_BLOCK_RANGE - 1n > toBlock\n ? toBlock\n : cursor + MAX_BLOCK_RANGE - 1n;\n\n const logs = await client.getLogs({\n address,\n events: events as never,\n fromBlock: cursor,\n toBlock: end,\n });\n\n allLogs.push(...logs);\n cursor = end + 1n;\n }\n\n return allLogs;\n}\n\n/** Fetch vault events (AgentRegistered, Ragequit, etc.) */\nexport async function getVaultEvents(\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n const logs = await getLogsChunked({\n address: vaultAddress,\n events: VAULT_EVENTS,\n fromBlock,\n toBlock,\n });\n\n return logs.map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownVaultEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Fetch governor events filtered to a specific vault. */\nexport async function getGovernorEvents(\n governorAddress: Address,\n vaultAddress: Address,\n fromBlock: bigint,\n toBlock: bigint,\n): Promise<ChainEvent[]> {\n if (governorAddress === \"0x0000000000000000000000000000000000000000\") {\n return []; // Governor not deployed yet\n }\n\n const logs = await getLogsChunked({\n address: governorAddress,\n events: GOVERNOR_EVENTS,\n fromBlock,\n toBlock,\n });\n\n // Filter governor events to only those involving our vault\n return logs\n .filter((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const args = (log as any).args;\n if (!args) return true;\n // ProposalCreated, ProposalExecuted, ProposalSettled have `vault` in args\n if (args.vault) {\n return (args.vault as string).toLowerCase() === vaultAddress.toLowerCase();\n }\n // VoteCast, ProposalCancelled don't have vault — include them\n // (agents care about all votes/cancellations on their governor)\n return true;\n })\n .map((log) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventName = (log as any).eventName || \"UnknownGovernorEvent\";\n return logToChainEvent(log, eventName);\n });\n}\n\n/** Get current block number from the RPC. */\nexport async function getCurrentBlock(): Promise<bigint> {\n const client = getPublicClient();\n return client.getBlockNumber();\n}\n\n// ── Proposal event enrichment ──\n\nconst PROPOSAL_EVENT_TYPES = new Set([\n \"ProposalCreated\",\n \"VoteCast\",\n \"ProposalExecuted\",\n \"ProposalSettled\",\n \"ProposalCancelled\",\n]);\n\n/**\n * Enrich proposal-related events with IPFS metadata (name, description)\n * and current on-chain state. Best-effort — events are returned un-enriched\n * if RPC or IPFS calls fail.\n *\n * `vault` identifies which per-vault governor to read proposal state from\n * (proposal IDs are scoped to a vault's governor in the per-vault design).\n *\n * An optional metadataCache avoids redundant IPFS fetches across poll cycles\n * in streaming mode (proposal metadata is immutable once pinned).\n */\nexport async function enrichProposalEvents(\n vault: Address,\n events: ChainEvent[],\n metadataCache?: Map<string, { name: string; description: string }>,\n): Promise<ChainEvent[]> {\n const cache = metadataCache ?? new Map<string, { name: string; description: string }>();\n\n const proposalEvents = events.filter((e) => PROPOSAL_EVENT_TYPES.has(e.type));\n if (proposalEvents.length === 0) return events;\n\n // Collect unique proposalIds and their metadata sources\n const idsNeedingLookup = new Set<string>();\n const createdURIs = new Map<string, string>(); // proposalId → metadataURI from event args\n\n for (const event of proposalEvents) {\n const pid = event.args.proposalId;\n if (!pid) continue;\n\n if (event.type === \"ProposalCreated\" && event.args.metadataURI) {\n createdURIs.set(pid, event.args.metadataURI);\n } else if (!cache.has(pid)) {\n idsNeedingLookup.add(pid);\n }\n }\n\n // Fetch on-chain proposal data for non-Created events (parallel, deduplicated)\n const proposalData = new Map<string, { metadataURI: string; state: number }>();\n\n await Promise.all(\n Array.from(idsNeedingLookup).map(async (pid) => {\n try {\n const p = await getProposal(vault, BigInt(pid));\n proposalData.set(pid, { metadataURI: p.metadataURI, state: p.state });\n } catch {\n // RPC failure — skip enrichment for this proposalId\n }\n }),\n );\n\n // Resolve IPFS metadata (parallel, deduplicated, uses cache)\n const allURIs = new Map<string, string>();\n for (const [pid, uri] of createdURIs) allURIs.set(pid, uri);\n for (const [pid, data] of proposalData) {\n if (!allURIs.has(pid)) allURIs.set(pid, data.metadataURI);\n }\n\n await Promise.all(\n Array.from(allURIs.entries()).map(async ([pid, uri]) => {\n if (cache.has(pid) || !uri) return;\n const summary = await resolveMetadataSummary(uri);\n if (summary) cache.set(pid, summary);\n }),\n );\n\n // Inject enrichment fields into event args\n return events.map((event) => {\n if (!PROPOSAL_EVENT_TYPES.has(event.type)) return event;\n const pid = event.args.proposalId;\n if (!pid) return event;\n\n const meta = cache.get(pid);\n const pData = proposalData.get(pid);\n const enrichedArgs = { ...event.args };\n\n if (meta) {\n enrichedArgs.proposalName = meta.name;\n enrichedArgs.proposalDescription = meta.description;\n }\n\n if (event.type === \"ProposalCreated\") {\n enrichedArgs.proposalState = \"Pending\";\n } else if (pData) {\n enrichedArgs.proposalState = PROPOSAL_STATES[pData.state] || \"Unknown\";\n }\n\n return { ...event, args: enrichedArgs };\n });\n}\n"],"mappings":"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","names":["result"]}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resetSession,
|
|
6
6
|
saveSessionState,
|
|
7
7
|
updateSession
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5DWB5Y7G.js";
|
|
9
9
|
export {
|
|
10
10
|
getAllSessions,
|
|
11
11
|
getSession,
|
|
@@ -14,4 +14,4 @@ export {
|
|
|
14
14
|
saveSessionState,
|
|
15
15
|
updateSession
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=session-
|
|
17
|
+
//# sourceMappingURL=session-XBQY7SBJ.js.map
|