@varun-ai07/covenant-mcp 2.5.2 → 3.0.0
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 +24 -40
- package/dist/lib/verify.d.ts +12 -0
- package/dist/lib/verify.d.ts.map +1 -1
- package/dist/lib/verify.js +115 -13
- package/dist/lib/verify.js.map +1 -1
- package/dist/sdk.d.ts +1 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +9 -0
- package/dist/sdk.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/corven-agent.d.ts.map +1 -1
- package/dist/tools/corven-agent.js +82 -10
- package/dist/tools/corven-agent.js.map +1 -1
- package/dist/tools/corven-batch.d.ts.map +1 -1
- package/dist/tools/corven-batch.js +82 -2
- package/dist/tools/corven-batch.js.map +1 -1
- package/dist/tools/corven-encrypt.d.ts +3 -0
- package/dist/tools/corven-encrypt.d.ts.map +1 -0
- package/dist/tools/corven-encrypt.js +107 -0
- package/dist/tools/corven-encrypt.js.map +1 -0
- package/dist/tools/corven-ipfs.d.ts.map +1 -1
- package/dist/tools/corven-ipfs.js +85 -12
- package/dist/tools/corven-ipfs.js.map +1 -1
- package/dist/tools/corven-message.d.ts +1 -0
- package/dist/tools/corven-message.d.ts.map +1 -1
- package/dist/tools/corven-message.js +100 -12
- package/dist/tools/corven-message.js.map +1 -1
- package/dist/tools/corven-reputation.d.ts.map +1 -1
- package/dist/tools/corven-reputation.js +82 -5
- package/dist/tools/corven-reputation.js.map +1 -1
- package/dist/tools/corven-stats.d.ts.map +1 -1
- package/dist/tools/corven-stats.js +72 -10
- package/dist/tools/corven-stats.js.map +1 -1
- package/dist/tools/corven-task.d.ts.map +1 -1
- package/dist/tools/corven-task.js +188 -8
- package/dist/tools/corven-task.js.map +1 -1
- package/dist/tools/corven-version.d.ts +3 -0
- package/dist/tools/corven-version.d.ts.map +1 -0
- package/dist/tools/corven-version.js +129 -0
- package/dist/tools/corven-version.js.map +1 -0
- package/dist/tools/disputes.d.ts.map +1 -1
- package/dist/tools/disputes.js +82 -0
- package/dist/tools/disputes.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,13 +6,15 @@ import { parseEther, formatEther, keccak256, toBytes } from "viem";
|
|
|
6
6
|
import { getSDK, getAccount, getPublicClient } from "../config.js";
|
|
7
7
|
import { formatTxResult, formatReadResult } from "../handlers/transactions.js";
|
|
8
8
|
import { formatStructuredError, parseContractError } from "../lib/formatResponse.js";
|
|
9
|
+
import { loadStore, saveStore } from "../lib/store.js";
|
|
9
10
|
async function waitAndFormat(hash) {
|
|
10
11
|
const client = getPublicClient();
|
|
11
12
|
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
12
13
|
return { status: "success", txHash: hash, blockNumber: receipt.blockNumber, gasUsed: receipt.gasUsed };
|
|
13
14
|
}
|
|
15
|
+
const agentProfiles = loadStore('agent_profiles', {});
|
|
14
16
|
const schema = z.object({
|
|
15
|
-
action: z.enum(["register", "get", "list", "update", "deactivate", "stake", "find"]),
|
|
17
|
+
action: z.enum(["register", "get", "list", "update", "deactivate", "stake", "find", "search"]),
|
|
16
18
|
name: z.string().optional(),
|
|
17
19
|
capabilities: z.array(z.string()).optional(),
|
|
18
20
|
stake: z.string().optional().default("0.001"),
|
|
@@ -20,6 +22,9 @@ const schema = z.object({
|
|
|
20
22
|
capability: z.string().optional(),
|
|
21
23
|
bio: z.string().optional(),
|
|
22
24
|
confirm: z.boolean().optional().default(false).describe('NEVER set this yourself. ALWAYS ask the user first. Show the exact ETH cost and what will happen. Only set to true AFTER the user explicitly says yes.'),
|
|
25
|
+
query: z.string().optional(),
|
|
26
|
+
offset: z.number().optional(),
|
|
27
|
+
limit: z.number().optional(),
|
|
23
28
|
});
|
|
24
29
|
export function registerAgentTools(server) {
|
|
25
30
|
server.registerTool("corven_agent", {
|
|
@@ -27,12 +32,13 @@ export function registerAgentTools(server) {
|
|
|
27
32
|
description: "Manage AI agent identities on COVENANT — register, look up, update, and manage on-chain agent profiles.\n\n" +
|
|
28
33
|
"ACTIONS:\n" +
|
|
29
34
|
" register — Create on-chain identity with name, capabilities, and stake (0.001 ETH)\n" +
|
|
30
|
-
" get — Look up agent by address (reputation, stake, status)\n" +
|
|
31
|
-
" list — List all registered agents\n" +
|
|
35
|
+
" get — Look up agent by address (reputation, stake, status, capabilities)\n" +
|
|
36
|
+
" list — List all registered agents with pagination\n" +
|
|
32
37
|
" update — Update agent profile (name, capabilities, bio)\n" +
|
|
33
38
|
" deactivate — Withdraw stake and deactivate agent\n" +
|
|
34
39
|
" stake — Add more stake to existing agent\n" +
|
|
35
|
-
" find — Search agents by capability tag\n
|
|
40
|
+
" find — Search agents by capability tag (local index)\n" +
|
|
41
|
+
" search — Search agents by name, capability, or both\n\n" +
|
|
36
42
|
"WHEN TO USE: First step for any agent. Register before creating tasks.\n\n" +
|
|
37
43
|
"NEXT STEP: Create a task with corven_task({ action: 'create' })\n\n" +
|
|
38
44
|
"CRITICAL SAFETY: The AI must NEVER auto-set confirm=true. ALWAYS present the cost summary to the user first and wait for explicit approval. This is real money. Violating this is unacceptable.\n\n" +
|
|
@@ -59,37 +65,103 @@ export function registerAgentTools(server) {
|
|
|
59
65
|
}
|
|
60
66
|
const nameHash = keccak256(toBytes(args.name || "unnamed"));
|
|
61
67
|
const hash = await sdk.registerAgent(stakeWei, nameHash);
|
|
62
|
-
|
|
68
|
+
const result = await waitAndFormat(hash);
|
|
69
|
+
const addr = getAccount()?.address?.toLowerCase() || "";
|
|
70
|
+
if (addr) {
|
|
71
|
+
agentProfiles[addr] = {
|
|
72
|
+
address: addr,
|
|
73
|
+
name: args.name || "unnamed",
|
|
74
|
+
capabilities: args.capabilities || [],
|
|
75
|
+
registeredAt: Math.floor(Date.now() / 1000),
|
|
76
|
+
lastSeen: Math.floor(Date.now() / 1000),
|
|
77
|
+
};
|
|
78
|
+
saveStore('agent_profiles', agentProfiles);
|
|
79
|
+
}
|
|
80
|
+
return formatTxResult(result);
|
|
63
81
|
}
|
|
64
82
|
if (action === "get") {
|
|
65
83
|
const addr = (args.address || getAccount()?.address);
|
|
66
84
|
if (!addr)
|
|
67
85
|
return formatReadResult({ error: "No address provided and no wallet connected" }, "Error");
|
|
68
86
|
const agent = await sdk.getAgent(addr);
|
|
87
|
+
const profile = agentProfiles[addr.toLowerCase()];
|
|
88
|
+
if (profile) {
|
|
89
|
+
profile.lastSeen = Math.floor(Date.now() / 1000);
|
|
90
|
+
saveStore('agent_profiles', agentProfiles);
|
|
91
|
+
}
|
|
69
92
|
return formatReadResult({
|
|
70
93
|
address: addr,
|
|
94
|
+
name: profile?.name,
|
|
95
|
+
capabilities: profile?.capabilities || [],
|
|
71
96
|
reputation: agent.reputation,
|
|
72
97
|
stakedEth: formatEther(agent.stakedAmount),
|
|
73
98
|
isActive: agent.isActive,
|
|
74
99
|
tasksCompleted: agent.tasksCompleted,
|
|
75
100
|
tasksFailed: agent.tasksFailed,
|
|
101
|
+
registeredAt: profile?.registeredAt,
|
|
102
|
+
lastSeen: profile?.lastSeen,
|
|
76
103
|
}, "Agent");
|
|
77
104
|
}
|
|
78
105
|
if (action === "list") {
|
|
79
|
-
const
|
|
80
|
-
|
|
106
|
+
const allProfiles = Object.values(agentProfiles);
|
|
107
|
+
const offset = args.offset || 0;
|
|
108
|
+
const limit = args.limit || 20;
|
|
109
|
+
const paginated = allProfiles.slice(offset, offset + limit);
|
|
110
|
+
return formatReadResult({
|
|
111
|
+
total: allProfiles.length,
|
|
112
|
+
offset,
|
|
113
|
+
limit,
|
|
114
|
+
count: paginated.length,
|
|
115
|
+
agents: paginated.map(p => ({
|
|
116
|
+
address: p.address,
|
|
117
|
+
name: p.name,
|
|
118
|
+
capabilities: p.capabilities,
|
|
119
|
+
registeredAt: p.registeredAt,
|
|
120
|
+
lastSeen: p.lastSeen,
|
|
121
|
+
})),
|
|
122
|
+
}, "Agent Profiles");
|
|
81
123
|
}
|
|
82
124
|
if (action === "stake") {
|
|
83
125
|
return formatReadResult({ info: "Use increaseStake() on the CovenantIdentity contract directly" }, "Stake Info");
|
|
84
126
|
}
|
|
85
127
|
if (action === "find") {
|
|
86
|
-
const
|
|
128
|
+
const cap = (args.capability || "").toLowerCase();
|
|
129
|
+
const matches = Object.values(agentProfiles).filter(p => p.capabilities.some(c => c.toLowerCase().includes(cap)));
|
|
87
130
|
return formatReadResult({
|
|
88
131
|
query: args.capability,
|
|
89
|
-
found:
|
|
90
|
-
agents:
|
|
132
|
+
found: matches.length,
|
|
133
|
+
agents: matches.slice(0, 10).map(p => ({
|
|
134
|
+
address: p.address,
|
|
135
|
+
name: p.name,
|
|
136
|
+
capabilities: p.capabilities,
|
|
137
|
+
lastSeen: p.lastSeen,
|
|
138
|
+
})),
|
|
91
139
|
}, "Agent Search");
|
|
92
140
|
}
|
|
141
|
+
if (action === "search") {
|
|
142
|
+
const q = (args.query || "").toLowerCase();
|
|
143
|
+
const matches = Object.values(agentProfiles).filter(p => {
|
|
144
|
+
const nameMatch = p.name.toLowerCase().includes(q);
|
|
145
|
+
const capMatch = p.capabilities.some(c => c.toLowerCase().includes(q));
|
|
146
|
+
return nameMatch || capMatch;
|
|
147
|
+
});
|
|
148
|
+
const offset = args.offset || 0;
|
|
149
|
+
const limit = args.limit || 20;
|
|
150
|
+
const paginated = matches.slice(offset, offset + limit);
|
|
151
|
+
return formatReadResult({
|
|
152
|
+
query: args.query,
|
|
153
|
+
total: matches.length,
|
|
154
|
+
offset,
|
|
155
|
+
limit,
|
|
156
|
+
count: paginated.length,
|
|
157
|
+
agents: paginated.map(p => ({
|
|
158
|
+
address: p.address,
|
|
159
|
+
name: p.name,
|
|
160
|
+
capabilities: p.capabilities,
|
|
161
|
+
lastSeen: p.lastSeen,
|
|
162
|
+
})),
|
|
163
|
+
}, "Agent Search Results");
|
|
164
|
+
}
|
|
93
165
|
return formatReadResult({ error: "Unknown action" }, "Error");
|
|
94
166
|
}
|
|
95
167
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corven-agent.js","sourceRoot":"","sources":["../../src/tools/corven-agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAgB,SAAS,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"corven-agent.js","sourceRoot":"","sources":["../../src/tools/corven-agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAgB,SAAS,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIvD,KAAK,UAAU,aAAa,CAAC,IAAmB;IAC9C,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;AACzG,CAAC;AAUD,MAAM,aAAa,GAAG,SAAS,CAA+B,gBAAgB,EAAE,EAAE,CAAC,CAAC;AAEpF,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9F,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC;IAC7C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,wJAAwJ,CAAC;IACjN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,MAAiB;IAClD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,6GAA6G;YAC7G,YAAY;YACZ,wFAAwF;YACxF,8EAA8E;YAC9E,uDAAuD;YACvD,6DAA6D;YAC7D,sDAAsD;YACtD,8CAA8C;YAC9C,0DAA0D;YAC1D,2DAA2D;YAC3D,4EAA4E;YAC5E,qEAAqE;YACrE,qMAAqM;YACrM,iBAAiB;YACjB,mEAAmE;YACnE,gFAAgF;YAChF,kDAAkD;YAClD,2DAA2D;QAC7D,WAAW,EAAE,MAAM,CAAC,KAAK;KAC1B,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;YACrB,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;YAExB,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC;gBACnD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,gBAAgB,CAAC;wBACtB,oBAAoB,EAAE,IAAI;wBAC1B,MAAM,EAAE,yBAAyB;wBACjC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,MAAM;wBACpC,MAAM,EAAE,yDAAyD;wBACjE,SAAS,EAAE,4CAA4C;qBACxD,EAAE,uBAAuB,CAAC,CAAC;gBAC9B,CAAC;gBACD,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC;gBAC5D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;gBAEzC,MAAM,IAAI,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;gBACxD,IAAI,IAAI,EAAE,CAAC;oBACT,aAAa,CAAC,IAAI,CAAC,GAAG;wBACpB,OAAO,EAAE,IAAI;wBACb,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;wBAC5B,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,EAAE;wBACrC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;wBAC3C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;qBACxC,CAAC;oBACF,SAAS,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;gBAC7C,CAAC;gBAED,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;YAED,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE,EAAE,OAAO,CAAY,CAAC;gBAChE,IAAI,CAAC,IAAI;oBAAE,OAAO,gBAAgB,CAAC,EAAE,KAAK,EAAE,6CAA6C,EAAE,EAAE,OAAO,CAAC,CAAC;gBACtG,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAClD,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;oBACjD,SAAS,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;gBAC7C,CAAC;gBACD,OAAO,gBAAgB,CAAC;oBACtB,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,OAAO,EAAE,IAAI;oBACnB,YAAY,EAAE,OAAO,EAAE,YAAY,IAAI,EAAE;oBACzC,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,SAAS,EAAE,WAAW,CAAC,KAAK,CAAC,YAAY,CAAC;oBAC1C,QAAQ,EAAE,KAAK,CAAC,QAAQ;oBACxB,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,YAAY,EAAE,OAAO,EAAE,YAAY;oBACnC,QAAQ,EAAE,OAAO,EAAE,QAAQ;iBAC5B,EAAE,OAAO,CAAC,CAAC;YACd,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;gBACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;gBAC5D,OAAO,gBAAgB,CAAC;oBACtB,KAAK,EAAE,WAAW,CAAC,MAAM;oBACzB,MAAM;oBACN,KAAK;oBACL,KAAK,EAAE,SAAS,CAAC,MAAM;oBACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBAC1B,OAAO,EAAE,CAAC,CAAC,OAAO;wBAClB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC;iBACJ,EAAE,gBAAgB,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,OAAO,gBAAgB,CAAC,EAAE,IAAI,EAAE,+DAA+D,EAAE,EAAE,YAAY,CAAC,CAAC;YACnH,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;gBAClD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACtD,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CACxD,CAAC;gBACF,OAAO,gBAAgB,CAAC;oBACtB,KAAK,EAAE,IAAI,CAAC,UAAU;oBACtB,KAAK,EAAE,OAAO,CAAC,MAAM;oBACrB,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBACrC,OAAO,EAAE,CAAC,CAAC,OAAO;wBAClB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC;iBACJ,EAAE,cAAc,CAAC,CAAC;YACrB,CAAC;YAED,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;oBACtD,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACnD,MAAM,QAAQ,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;oBACvE,OAAO,SAAS,IAAI,QAAQ,CAAC;gBAC/B,CAAC,CAAC,CAAC;gBACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;gBAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;gBACxD,OAAO,gBAAgB,CAAC;oBACtB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,KAAK,EAAE,OAAO,CAAC,MAAM;oBACrB,MAAM;oBACN,KAAK;oBACL,KAAK,EAAE,SAAS,CAAC,MAAM;oBACvB,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;wBAC1B,OAAO,EAAE,CAAC,CAAC,OAAO;wBAClB,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,YAAY,EAAE,CAAC,CAAC,YAAY;wBAC5B,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC;iBACJ,EAAE,sBAAsB,CAAC,CAAC;YAC7B,CAAC;YAED,OAAO,gBAAgB,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,OAAO,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,MAAM,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;YACrC,OAAO,qBAAqB,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACzF,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corven-batch.d.ts","sourceRoot":"","sources":["../../src/tools/corven-batch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"corven-batch.d.ts","sourceRoot":"","sources":["../../src/tools/corven-batch.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwCzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyM1D"}
|
|
@@ -12,6 +12,7 @@ import { executeOrPrepare, readContract } from "../handlers/wallet.js";
|
|
|
12
12
|
import { formatTxResult, formatReadResult } from "../handlers/transactions.js";
|
|
13
13
|
import { formatStructuredError, parseContractError } from "../lib/formatResponse.js";
|
|
14
14
|
import { stringToBytes32, stringsToBytes32 } from "../utils.js";
|
|
15
|
+
import { loadStore, saveStore } from "../lib/store.js";
|
|
15
16
|
const ABI = loadAbi("ParallelTaskBatch");
|
|
16
17
|
const BATCH_STATUS = {
|
|
17
18
|
0: "Pending",
|
|
@@ -21,7 +22,7 @@ const BATCH_STATUS = {
|
|
|
21
22
|
4: "Failed",
|
|
22
23
|
};
|
|
23
24
|
const actionSchema = z.enum([
|
|
24
|
-
"create", "submit", "verify", "get", "check",
|
|
25
|
+
"create", "submit", "verify", "get", "check", "progress", "cancel",
|
|
25
26
|
]);
|
|
26
27
|
const schema = z.object({
|
|
27
28
|
action: actionSchema,
|
|
@@ -42,7 +43,9 @@ export function registerBatchTools(server) {
|
|
|
42
43
|
" submit — Worker submits deliverable for a batch subtask\n" +
|
|
43
44
|
" verify — Finalize batch by aggregating all results (requires batchId)\n" +
|
|
44
45
|
" get — Get batch details or total count (pass batchId for details, omit for count)\n" +
|
|
45
|
-
" check — Check if all subtasks are submitted (requires batchId)\n
|
|
46
|
+
" check — Check if all subtasks are submitted (requires batchId)\n" +
|
|
47
|
+
" progress — Get real-time batch progress with per-task status (requires batchId)\n" +
|
|
48
|
+
" cancel — Mark a batch as cancelled (requires batchId)\n\n" +
|
|
46
49
|
"WORKFLOW: create → workers execute → check (all submitted?) → verify (aggregate)\n" +
|
|
47
50
|
"FEE: 1% protocol fee per subtask. Max 50 workers per batch.\n\n" +
|
|
48
51
|
"WHEN TO USE: When you need to execute multiple related tasks in parallel and aggregate results.\n\n" +
|
|
@@ -84,22 +87,56 @@ export function registerBatchTools(server) {
|
|
|
84
87
|
descBytes32,
|
|
85
88
|
aggBytes32,
|
|
86
89
|
], totalPayment);
|
|
90
|
+
const batchStatusStore = loadStore("batch_status", {});
|
|
91
|
+
const txResult = result;
|
|
92
|
+
const newBatchId = txResult?.batchId ?? txResult?.receipt?.blockNumber?.toString() ?? String(Object.keys(batchStatusStore).length);
|
|
93
|
+
batchStatusStore[newBatchId] = {
|
|
94
|
+
tasks: args.workers.map((_, i) => ({
|
|
95
|
+
taskId: i,
|
|
96
|
+
status: "pending",
|
|
97
|
+
score: 0,
|
|
98
|
+
})),
|
|
99
|
+
createdAt: Date.now(),
|
|
100
|
+
completedAt: null,
|
|
101
|
+
cancelled: false,
|
|
102
|
+
};
|
|
103
|
+
saveStore("batch_status", batchStatusStore);
|
|
87
104
|
return formatTxResult(result);
|
|
88
105
|
}
|
|
89
106
|
if (action === "submit") {
|
|
90
107
|
if (args.batchId === undefined) {
|
|
91
108
|
return formatStructuredError("Missing required field.", "submit requires batchId.", "Provide the batchId.", false);
|
|
92
109
|
}
|
|
110
|
+
const batchStatusStore = loadStore("batch_status", {});
|
|
111
|
+
const rec = batchStatusStore[String(args.batchId)];
|
|
112
|
+
if (rec && !rec.cancelled) {
|
|
113
|
+
const pendingTask = rec.tasks.find(t => t.status === "pending");
|
|
114
|
+
if (pendingTask) {
|
|
115
|
+
pendingTask.status = "submitted";
|
|
116
|
+
}
|
|
117
|
+
saveStore("batch_status", batchStatusStore);
|
|
118
|
+
}
|
|
93
119
|
return formatReadResult({
|
|
94
120
|
info: "Batch subtask submission is not available in V5 ParallelTaskBatch.",
|
|
95
121
|
reason: "V5 batches use createBatch + aggregateResults. Individual subtask submission is handled differently.",
|
|
96
122
|
batchId: args.batchId,
|
|
123
|
+
trackedStatus: rec ? rec.tasks.map(t => ({ taskId: t.taskId, status: t.status })) : null,
|
|
97
124
|
}, "Batch Submit — Not Available");
|
|
98
125
|
}
|
|
99
126
|
if (action === "verify") {
|
|
100
127
|
if (args.batchId === undefined) {
|
|
101
128
|
return formatStructuredError("Missing required field.", "verify requires batchId.", "Provide the batchId.", false);
|
|
102
129
|
}
|
|
130
|
+
const batchStatusStore = loadStore("batch_status", {});
|
|
131
|
+
const rec = batchStatusStore[String(args.batchId)];
|
|
132
|
+
if (rec && !rec.cancelled) {
|
|
133
|
+
rec.tasks.forEach(t => {
|
|
134
|
+
t.status = "completed";
|
|
135
|
+
t.score = 100;
|
|
136
|
+
});
|
|
137
|
+
rec.completedAt = Date.now();
|
|
138
|
+
saveStore("batch_status", batchStatusStore);
|
|
139
|
+
}
|
|
103
140
|
const result = await executeOrPrepare(CONTRACTS.ParallelTaskBatch, ABI, "aggregateResults", [BigInt(args.batchId)], 0n);
|
|
104
141
|
return formatTxResult(result);
|
|
105
142
|
}
|
|
@@ -127,6 +164,49 @@ export function registerBatchTools(server) {
|
|
|
127
164
|
const status = BATCH_STATUS[batch.status] ?? "Unknown";
|
|
128
165
|
return formatReadResult({ batchId: args.batchId, status, allSubmitted: status === "Completed" || status === "Aggregated" }, `Batch #${args.batchId} Status`);
|
|
129
166
|
}
|
|
167
|
+
if (action === "progress") {
|
|
168
|
+
if (args.batchId === undefined) {
|
|
169
|
+
return formatStructuredError("Missing required field.", "progress requires batchId.", "Provide the batchId.", false);
|
|
170
|
+
}
|
|
171
|
+
const batchStatusStore = loadStore("batch_status", {});
|
|
172
|
+
const rec = batchStatusStore[String(args.batchId)];
|
|
173
|
+
if (!rec) {
|
|
174
|
+
return formatStructuredError("Batch not found.", "No tracked status for batch " + args.batchId, "Ensure the batch was created via corven_batch create.", false);
|
|
175
|
+
}
|
|
176
|
+
const completed = rec.tasks.filter(t => t.status === "completed").length;
|
|
177
|
+
const total = rec.tasks.length;
|
|
178
|
+
return formatReadResult({
|
|
179
|
+
batchId: args.batchId,
|
|
180
|
+
cancelled: rec.cancelled,
|
|
181
|
+
completed,
|
|
182
|
+
total,
|
|
183
|
+
percentage: total > 0 ? Math.round((completed / total) * 100) : 0,
|
|
184
|
+
createdAt: new Date(rec.createdAt).toISOString(),
|
|
185
|
+
completedAt: rec.completedAt ? new Date(rec.completedAt).toISOString() : null,
|
|
186
|
+
tasks: rec.tasks.map(t => ({ taskId: t.taskId, status: t.status, score: t.score })),
|
|
187
|
+
}, `Batch #${args.batchId} Progress`);
|
|
188
|
+
}
|
|
189
|
+
if (action === "cancel") {
|
|
190
|
+
if (args.batchId === undefined) {
|
|
191
|
+
return formatStructuredError("Missing required field.", "cancel requires batchId.", "Provide the batchId.", false);
|
|
192
|
+
}
|
|
193
|
+
const batchStatusStore = loadStore("batch_status", {});
|
|
194
|
+
const rec = batchStatusStore[String(args.batchId)];
|
|
195
|
+
if (!rec) {
|
|
196
|
+
return formatStructuredError("Batch not found.", "No tracked status for batch " + args.batchId, "Ensure the batch was created via corven_batch create.", false);
|
|
197
|
+
}
|
|
198
|
+
if (rec.cancelled) {
|
|
199
|
+
return formatReadResult({ batchId: args.batchId, alreadyCancelled: true }, `Batch #${args.batchId} Already Cancelled`);
|
|
200
|
+
}
|
|
201
|
+
rec.cancelled = true;
|
|
202
|
+
rec.tasks.forEach(t => { t.status = "cancelled"; });
|
|
203
|
+
saveStore("batch_status", batchStatusStore);
|
|
204
|
+
return formatReadResult({
|
|
205
|
+
batchId: args.batchId,
|
|
206
|
+
cancelled: true,
|
|
207
|
+
tasks: rec.tasks.map(t => ({ taskId: t.taskId, status: t.status })),
|
|
208
|
+
}, `Batch #${args.batchId} Cancelled`);
|
|
209
|
+
}
|
|
130
210
|
return formatReadResult({ error: "Unknown action" }, "Error");
|
|
131
211
|
}
|
|
132
212
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corven-batch.js","sourceRoot":"","sources":["../../src/tools/corven-batch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAA2B,MAAM,MAAM,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAc,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"corven-batch.js","sourceRoot":"","sources":["../../src/tools/corven-batch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corven-encrypt.d.ts","sourceRoot":"","sources":["../../src/tools/corven-encrypt.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkDzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyE5D"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* corven_encrypt — Encrypt and decrypt task content using AES-256-GCM.
|
|
3
|
+
*/
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { randomBytes, createCipheriv, createDecipheriv, createHash } from "crypto";
|
|
6
|
+
import { formatReadResult, formatError } from "../handlers/transactions.js";
|
|
7
|
+
const ALGORITHM = "aes-256-gcm";
|
|
8
|
+
const IV_LENGTH = 12;
|
|
9
|
+
const KEY_LENGTH = 32;
|
|
10
|
+
function deriveKey(sharedSecret) {
|
|
11
|
+
return createHash("sha256").update(sharedSecret).digest();
|
|
12
|
+
}
|
|
13
|
+
function encryptContent(plaintext, sharedSecret) {
|
|
14
|
+
const key = deriveKey(sharedSecret);
|
|
15
|
+
const iv = randomBytes(IV_LENGTH);
|
|
16
|
+
const cipher = createCipheriv(ALGORITHM, key, iv);
|
|
17
|
+
let encrypted = cipher.update(plaintext, "utf-8", "hex");
|
|
18
|
+
encrypted += cipher.final("hex");
|
|
19
|
+
const tag = cipher.getAuthTag().toString("hex");
|
|
20
|
+
return {
|
|
21
|
+
ciphertext: encrypted,
|
|
22
|
+
nonce: iv.toString("hex"),
|
|
23
|
+
tag,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function decryptContent(ciphertext, sharedSecret, nonce, tag) {
|
|
27
|
+
const key = deriveKey(sharedSecret);
|
|
28
|
+
const iv = Buffer.from(nonce, "hex");
|
|
29
|
+
const authTag = Buffer.from(tag, "hex");
|
|
30
|
+
const decipher = createDecipheriv(ALGORITHM, key, iv);
|
|
31
|
+
decipher.setAuthTag(authTag);
|
|
32
|
+
let decrypted = decipher.update(ciphertext, "hex", "utf-8");
|
|
33
|
+
decrypted += decipher.final("utf-8");
|
|
34
|
+
return decrypted;
|
|
35
|
+
}
|
|
36
|
+
const schema = z.object({
|
|
37
|
+
action: z
|
|
38
|
+
.enum(["encrypt", "decrypt"])
|
|
39
|
+
.describe("encrypt: encrypt content with a shared secret. decrypt: decrypt content using key + nonce."),
|
|
40
|
+
content: z.string().optional().describe("Plaintext content to encrypt (required for encrypt)"),
|
|
41
|
+
recipientPublicKey: z.string().optional().describe("Shared secret or public key for encryption (required for encrypt)"),
|
|
42
|
+
encryptedData: z.string().optional().describe("Encrypted ciphertext (required for decrypt)"),
|
|
43
|
+
nonce: z.string().optional().describe("Hex-encoded nonce/IV (required for decrypt)"),
|
|
44
|
+
key: z.string().optional().describe("Shared secret or decryption key (required for decrypt)"),
|
|
45
|
+
tag: z.string().optional().describe("Hex-encoded auth tag (required for decrypt)"),
|
|
46
|
+
});
|
|
47
|
+
export function registerEncryptTools(server) {
|
|
48
|
+
server.registerTool("corven_encrypt", {
|
|
49
|
+
title: "Encrypted Task Content",
|
|
50
|
+
description: "Encrypt and decrypt task content using AES-256-GCM symmetric encryption.\n\n" +
|
|
51
|
+
"ACTIONS:\n" +
|
|
52
|
+
" encrypt — Encrypt plaintext with a shared secret, returns ciphertext + nonce + tag\n" +
|
|
53
|
+
" decrypt — Decrypt ciphertext using key + nonce + tag, returns plaintext\n\n" +
|
|
54
|
+
"USE WHEN: You need to protect sensitive task content (API keys, secrets, PII)\n" +
|
|
55
|
+
"so only the intended recipient can read it on-chain or in IPFS.\n\n" +
|
|
56
|
+
"WORKFLOW: encrypt content → share ciphertext + nonce + tag + key securely → recipient decrypts\n\n" +
|
|
57
|
+
"OUTPUT RULES:\n" +
|
|
58
|
+
"- Present results as clean, readable text. Never show raw JSON.\n" +
|
|
59
|
+
"- On error: Explain in plain language what went wrong and suggest next step.",
|
|
60
|
+
inputSchema: schema.shape,
|
|
61
|
+
}, async (args) => {
|
|
62
|
+
try {
|
|
63
|
+
const { action } = args;
|
|
64
|
+
if (action === "encrypt") {
|
|
65
|
+
if (!args.content)
|
|
66
|
+
return formatError(new Error("content is required for encrypt action"));
|
|
67
|
+
if (!args.recipientPublicKey)
|
|
68
|
+
return formatError(new Error("recipientPublicKey (shared secret) is required for encrypt"));
|
|
69
|
+
const { ciphertext, nonce, tag } = encryptContent(args.content, args.recipientPublicKey);
|
|
70
|
+
return formatReadResult({
|
|
71
|
+
ciphertext,
|
|
72
|
+
nonce,
|
|
73
|
+
tag,
|
|
74
|
+
algorithm: ALGORITHM,
|
|
75
|
+
note: "Share ciphertext, nonce, tag, and the shared secret with the recipient separately.",
|
|
76
|
+
}, "Content Encrypted");
|
|
77
|
+
}
|
|
78
|
+
if (action === "decrypt") {
|
|
79
|
+
if (!args.encryptedData)
|
|
80
|
+
return formatError(new Error("encryptedData is required for decrypt action"));
|
|
81
|
+
if (!args.key)
|
|
82
|
+
return formatError(new Error("key (shared secret) is required for decrypt"));
|
|
83
|
+
if (!args.nonce)
|
|
84
|
+
return formatError(new Error("nonce is required for decrypt"));
|
|
85
|
+
if (!args.tag)
|
|
86
|
+
return formatError(new Error("tag is required for decrypt"));
|
|
87
|
+
try {
|
|
88
|
+
const plaintext = decryptContent(args.encryptedData, args.key, args.nonce, args.tag);
|
|
89
|
+
return formatReadResult({
|
|
90
|
+
content: plaintext,
|
|
91
|
+
algorithm: ALGORITHM,
|
|
92
|
+
decrypted: true,
|
|
93
|
+
}, "Content Decrypted");
|
|
94
|
+
}
|
|
95
|
+
catch (decErr) {
|
|
96
|
+
return formatError(new Error(`Decryption failed — wrong key, nonce, or tag. ` +
|
|
97
|
+
`Ensure all three match the encryption parameters. (${decErr instanceof Error ? decErr.message : String(decErr)})`));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return formatError(new Error(`Unknown action: ${action}`));
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
return formatError(e instanceof Error ? e : new Error(String(e)));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=corven-encrypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"corven-encrypt.js","sourceRoot":"","sources":["../../src/tools/corven-encrypt.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"corven-ipfs.d.ts","sourceRoot":"","sources":["../../src/tools/corven-ipfs.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"corven-ipfs.d.ts","sourceRoot":"","sources":["../../src/tools/corven-ipfs.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4DzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsG9D"}
|
|
@@ -1,22 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* corven_ipfs — Upload and read content on IPFS via Pinata
|
|
3
3
|
*/
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { formatReadResult, formatError } from "../handlers/transactions.js";
|
|
6
|
+
const IPFS_GATEWAYS = [
|
|
7
|
+
"https://gateway.pinata.cloud/ipfs",
|
|
8
|
+
"https://ipfs.io/ipfs",
|
|
9
|
+
"https://cloudflare-ipfs.com/ipfs",
|
|
10
|
+
];
|
|
11
|
+
function isCid(s) {
|
|
12
|
+
return /^Qm[1-9A-HJ-NP-Za-km-z]{44,}/.test(s) ||
|
|
13
|
+
/^(bafy[a-zA-Z2-7]{52,})/.test(s) ||
|
|
14
|
+
/^(b[ae][a-zA-Z2-7]{50,})/.test(s);
|
|
15
|
+
}
|
|
16
|
+
function isUrl(s) {
|
|
17
|
+
return /^https?:\/\//.test(s);
|
|
18
|
+
}
|
|
19
|
+
function extractCid(input) {
|
|
20
|
+
const httpMatch = input.match(/\/ipfs\/([a-zA-Z0-9]+)/);
|
|
21
|
+
if (httpMatch)
|
|
22
|
+
return httpMatch[1];
|
|
23
|
+
if (isCid(input))
|
|
24
|
+
return input;
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
async function fetchFromIpfs(cid, timeoutMs = 10000) {
|
|
28
|
+
let lastError = null;
|
|
29
|
+
for (const gw of IPFS_GATEWAYS) {
|
|
30
|
+
const url = `${gw}/${cid}`;
|
|
31
|
+
try {
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
34
|
+
const resp = await fetch(url, { signal: controller.signal });
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
if (!resp.ok) {
|
|
37
|
+
lastError = new Error(`HTTP ${resp.status} from ${gw}`);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const contentType = resp.headers.get("content-type") || "application/octet-stream";
|
|
41
|
+
if (contentType.includes("json") || contentType.includes("text")) {
|
|
42
|
+
const text = await resp.text();
|
|
43
|
+
return { content: text, size: text.length, contentType, resolvedFrom: url };
|
|
44
|
+
}
|
|
45
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
46
|
+
return { content: buf.toString("base64"), size: buf.length, contentType, resolvedFrom: url };
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
lastError = e instanceof Error ? e : new Error(String(e));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
throw lastError || new Error("All IPFS gateways failed");
|
|
53
|
+
}
|
|
6
54
|
const schema = z.object({
|
|
7
|
-
|
|
55
|
+
action: z.enum(["upload", "read"]).default("upload").describe("upload: store content on IPFS. read: fetch content from IPFS by CID or gateway URL."),
|
|
56
|
+
content: z.string().optional().describe("Content to upload (text, JSON, or base64). Required for upload action."),
|
|
57
|
+
cid: z.string().optional().describe("IPFS CID or gateway URL to fetch. Required for read action."),
|
|
8
58
|
name: z.string().optional().describe("Filename for the upload"),
|
|
9
59
|
type: z.enum(["text", "json", "base64"]).optional().default("text"),
|
|
10
60
|
});
|
|
11
61
|
export function registerIPFSUploadTool(server) {
|
|
12
|
-
server.registerTool("
|
|
13
|
-
title: "Upload
|
|
14
|
-
description: "Upload content to IPFS
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
62
|
+
server.registerTool("corven_ipfs", {
|
|
63
|
+
title: "IPFS Upload & Read",
|
|
64
|
+
description: "Upload content to IPFS or read/download content from IPFS on COVENANT.\n\n" +
|
|
65
|
+
"ACTIONS:\n" +
|
|
66
|
+
" upload — Store content on IPFS via Pinata, returns a CID\n" +
|
|
67
|
+
" read — Fetch content from IPFS by CID or gateway URL\n\n" +
|
|
68
|
+
"USE WHEN: You need to store task descriptions/deliverables on IPFS (upload) or retrieve stored IPFS content (read).\n" +
|
|
69
|
+
"REQUIRES: PINATA_API_KEY and PINATA_SECRET_KEY for upload. Read works without keys.\n" +
|
|
70
|
+
"RETURNS: IPFS CID + gateway URL (upload) or content + metadata (read)\n" +
|
|
18
71
|
"WORKFLOW: Upload description → create task with CID → worker uploads deliverable → verify\n\n" +
|
|
19
|
-
"WHEN TO USE: Before creating a task
|
|
72
|
+
"WHEN TO USE: Before creating a task (upload), or when resolving a task's descriptionHash/deliverableHash (read).\n\n" +
|
|
20
73
|
"NEXT STEP: Create a task with corven_task({ action: 'create', descriptionHash: '<CID>' })\n\n" +
|
|
21
74
|
"OUTPUT RULES:\n" +
|
|
22
75
|
"- Present results as clean, readable text. Never show raw JSON.\n" +
|
|
@@ -26,17 +79,37 @@ export function registerIPFSUploadTool(server) {
|
|
|
26
79
|
inputSchema: schema.shape,
|
|
27
80
|
}, async (args) => {
|
|
28
81
|
try {
|
|
82
|
+
if (args.action === "read") {
|
|
83
|
+
const input = args.cid || "";
|
|
84
|
+
if (!input)
|
|
85
|
+
return formatError(new Error("cid is required for read action"));
|
|
86
|
+
const cid = extractCid(input);
|
|
87
|
+
if (!cid)
|
|
88
|
+
return formatError(new Error(`Could not extract CID from: ${input}`));
|
|
89
|
+
const result = await fetchFromIpfs(cid);
|
|
90
|
+
const isBase64 = !result.contentType.includes("text") && !result.contentType.includes("json");
|
|
91
|
+
return formatReadResult({
|
|
92
|
+
cid,
|
|
93
|
+
size: result.size,
|
|
94
|
+
contentType: result.contentType,
|
|
95
|
+
encoding: isBase64 ? "base64" : "utf-8",
|
|
96
|
+
content: isBase64 ? result.content.substring(0, 2000) + (result.size > 2000 ? "..." : "") : result.content,
|
|
97
|
+
gateway: result.resolvedFrom,
|
|
98
|
+
truncated: result.size > 2000,
|
|
99
|
+
}, `IPFS Read: ${cid}`);
|
|
100
|
+
}
|
|
101
|
+
// upload action
|
|
29
102
|
const pinataApiKey = process.env.PINATA_API_KEY;
|
|
30
103
|
const pinataSecretKey = process.env.PINATA_SECRET_KEY;
|
|
31
104
|
if (!pinataApiKey || !pinataSecretKey) {
|
|
32
105
|
return formatError(new Error("Pinata not configured. Set PINATA_API_KEY and PINATA_SECRET_KEY in .env"));
|
|
33
106
|
}
|
|
34
|
-
let content = args.content;
|
|
107
|
+
let content = args.content || "";
|
|
35
108
|
if (args.type === "base64") {
|
|
36
|
-
content = Buffer.from(
|
|
109
|
+
content = Buffer.from(content, "base64").toString("utf-8");
|
|
37
110
|
}
|
|
38
111
|
else if (args.type === "json") {
|
|
39
|
-
JSON.parse(
|
|
112
|
+
JSON.parse(content);
|
|
40
113
|
}
|
|
41
114
|
const formData = new FormData();
|
|
42
115
|
const blob = new Blob([content], { type: "text/plain" });
|