@blindmarket/mcp-server 0.3.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 +90 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -0
- package/dist/crypto.d.ts +14 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +33 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +135 -0
- package/dist/index.js.map +1 -0
- package/dist/rent.d.ts +5 -0
- package/dist/rent.d.ts.map +1 -0
- package/dist/rent.js +353 -0
- package/dist/rent.js.map +1 -0
- package/dist/runtime.d.ts +7 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +73 -0
- package/dist/runtime.js.map +1 -0
- package/dist/state.d.ts +45 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +61 -0
- package/dist/state.js.map +1 -0
- package/dist/tools.d.ts +4 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +260 -0
- package/dist/tools.js.map +1 -0
- package/dist/wallet.d.ts +23 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +42 -0
- package/dist/wallet.js.map +1 -0
- package/package.json +35 -0
package/dist/rent.js
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { formatEther, parseEther } from 'ethers';
|
|
3
|
+
import { aesEncrypt, eciesEncrypt, generateAesKey, sha256Hex } from './crypto.js';
|
|
4
|
+
import { createQuote, consumeQuote, getSpend, putSpend, updateSpend } from './state.js';
|
|
5
|
+
/**
|
|
6
|
+
* Tier-2 spending tools: the CURRENT encrypted post/rent flow, executed
|
|
7
|
+
* entirely locally. This is a 1:1 port of the "Use from your agent" script
|
|
8
|
+
* (frontend/src/components/UseFromAgentModal.tsx buildScript):
|
|
9
|
+
*
|
|
10
|
+
* encrypt brief locally → POST /api/v1/storage/upload → ECIES-wrap the AES
|
|
11
|
+
* key to the provider pubkey(s) → POST /api/v1/tasks (unsigned escrow tx) →
|
|
12
|
+
* sign + send from the LOCAL wallet → POST /api/v1/a2a/tasks/index → poll
|
|
13
|
+
* GET /api/v1/a2a/tasks/posted for the result.
|
|
14
|
+
*
|
|
15
|
+
* Privacy: for privacy='private' (default) the platform only ever sees
|
|
16
|
+
* ciphertext and a hash. privacy='public' posts the brief in plaintext — no
|
|
17
|
+
* key handling at all, readable by every agent.
|
|
18
|
+
*
|
|
19
|
+
* Spend safety: two-step quote/confirm + a required idempotencyKey persisted
|
|
20
|
+
* in ~/.blindmarket/mcp-state.json with a created→funded→indexed stage
|
|
21
|
+
* machine, so retries resume instead of double-funding.
|
|
22
|
+
*/
|
|
23
|
+
const ZERO_TOKEN = '0x0000000000000000000000000000000000000000';
|
|
24
|
+
const GAS_LIMIT = 1000000n; // matches the canonical rent script
|
|
25
|
+
function ok(data) {
|
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
|
|
27
|
+
}
|
|
28
|
+
function fail(code, message) {
|
|
29
|
+
return { isError: true, content: [{ type: 'text', text: JSON.stringify({ error: { code, message } }) }] };
|
|
30
|
+
}
|
|
31
|
+
export function registerRentTools(server, cfg, walletCtx) {
|
|
32
|
+
async function api(method, path, body) {
|
|
33
|
+
const res = await fetch(`${cfg.apiBase}${path}`, {
|
|
34
|
+
method,
|
|
35
|
+
headers: { 'Content-Type': 'application/json', 'X-API-Key': cfg.apiKey },
|
|
36
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
37
|
+
});
|
|
38
|
+
const json = await res.json().catch(() => ({}));
|
|
39
|
+
if (!res.ok || !json.success) {
|
|
40
|
+
const err = new Error(`${path} failed: ${json.error?.message || res.status}`);
|
|
41
|
+
err.code = json.error?.code;
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
return json.data;
|
|
45
|
+
}
|
|
46
|
+
function requireWallet() {
|
|
47
|
+
if (!walletCtx) {
|
|
48
|
+
return { error: fail('NO_WALLET', 'Spending tools need a local funding wallet — set BLINDMARKET_PRIVATE_KEY (see wallet_status)') };
|
|
49
|
+
}
|
|
50
|
+
return walletCtx;
|
|
51
|
+
}
|
|
52
|
+
/** Fund escrow + index — the shared tail of rent_service and post_task.
|
|
53
|
+
* Resumable at every stage via the spend ledger. */
|
|
54
|
+
async function fundAndIndex(record) {
|
|
55
|
+
const ctx = walletCtx;
|
|
56
|
+
let { txHash } = record;
|
|
57
|
+
if (record.stage === 'created') {
|
|
58
|
+
const { unsignedTx } = await api('POST', '/api/v1/tasks', {
|
|
59
|
+
taskHash: record.taskHash,
|
|
60
|
+
token: ZERO_TOKEN,
|
|
61
|
+
amount: record.amountWei,
|
|
62
|
+
locationZone: 'global',
|
|
63
|
+
duration: String(record.durationSecs ?? 3600),
|
|
64
|
+
targetExecutorType: 'agent',
|
|
65
|
+
verificationMode: record.verificationMode,
|
|
66
|
+
verificationCriteria: record.verificationCriteria,
|
|
67
|
+
requiredCapabilities: record.requiredCapabilities ?? [],
|
|
68
|
+
rootHash: record.rootHash,
|
|
69
|
+
wrappedKeys: record.privacy === 'public' ? undefined : record.wrappedKeys,
|
|
70
|
+
});
|
|
71
|
+
const tx = await ctx.wallet.sendTransaction({
|
|
72
|
+
to: unsignedTx.to,
|
|
73
|
+
data: unsignedTx.data,
|
|
74
|
+
value: BigInt(record.amountWei),
|
|
75
|
+
gasLimit: GAS_LIMIT,
|
|
76
|
+
});
|
|
77
|
+
// Persist the tx hash BEFORE waiting: if we crash mid-confirmation the
|
|
78
|
+
// resume path re-runs /tasks/index with this hash instead of re-funding.
|
|
79
|
+
updateSpend(record.idempotencyKey, { stage: 'funded', txHash: tx.hash });
|
|
80
|
+
txHash = tx.hash;
|
|
81
|
+
await tx.wait();
|
|
82
|
+
}
|
|
83
|
+
// stage 'funded' (fresh or resumed): index against the verified receipt.
|
|
84
|
+
// /a2a/tasks/index itself polls for the receipt server-side.
|
|
85
|
+
await api('POST', '/api/v1/a2a/tasks/index', {
|
|
86
|
+
txHash,
|
|
87
|
+
taskHash: record.taskHash,
|
|
88
|
+
verificationMode: record.verificationMode,
|
|
89
|
+
verificationCriteria: record.verificationCriteria,
|
|
90
|
+
requiredCapabilities: record.requiredCapabilities ?? [],
|
|
91
|
+
rootHash: record.rootHash,
|
|
92
|
+
wrappedKeys: record.privacy === 'public' ? undefined : record.wrappedKeys,
|
|
93
|
+
targetExecutor: record.targetExecutor,
|
|
94
|
+
serviceId: record.serviceId,
|
|
95
|
+
privacy: record.privacy === 'public' ? 'public' : undefined,
|
|
96
|
+
publicBrief: record.privacy === 'public' ? record.publicBrief : undefined,
|
|
97
|
+
});
|
|
98
|
+
updateSpend(record.idempotencyKey, { stage: 'indexed' });
|
|
99
|
+
return { taskHash: record.taskHash, txHash: txHash };
|
|
100
|
+
}
|
|
101
|
+
async function pollPosted(taskHash, waitSeconds) {
|
|
102
|
+
const deadline = Date.now() + Math.min(60, Math.max(0, waitSeconds)) * 1000;
|
|
103
|
+
const hashLc = taskHash.toLowerCase();
|
|
104
|
+
for (;;) {
|
|
105
|
+
const { tasks } = await api('GET', '/api/v1/a2a/tasks/posted');
|
|
106
|
+
const t = tasks.find((x) => x.meta?.taskId?.toLowerCase() === hashLc);
|
|
107
|
+
const status = t?.state?.status ?? 'unknown';
|
|
108
|
+
if ((status === 'verified' || status === 'completed') && t.state.resultData) {
|
|
109
|
+
return { status, result: t.state.resultData, done: true };
|
|
110
|
+
}
|
|
111
|
+
if (status === 'failed') {
|
|
112
|
+
return { status, failedReason: t.state.failedReason ?? null, done: true, hint: 'The agent could not complete this task. If escrow is still Funded you can cancel for a refund.' };
|
|
113
|
+
}
|
|
114
|
+
if (Date.now() >= deadline) {
|
|
115
|
+
return { status, done: false, hint: 'Still running — call poll_task_result again.' };
|
|
116
|
+
}
|
|
117
|
+
await new Promise((r) => setTimeout(r, 4000));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ── rent_service ──────────────────────────────────────────────────────────
|
|
121
|
+
server.registerTool('rent_service', {
|
|
122
|
+
title: 'Rent an Agent Service',
|
|
123
|
+
description: 'Hire a listed agent service for one call: encrypts your prompt locally (unless privacy=public), funds escrow from your local wallet, and pins the task to the provider agent. TWO-STEP: first call returns a price quote + quoteId; re-call with confirm=true and that quoteId to actually spend. Requires a unique idempotencyKey (safe to retry with the same key — it resumes, never double-pays).',
|
|
124
|
+
inputSchema: {
|
|
125
|
+
serviceId: z.number().int().positive().describe('Service id from browse_services / get_service'),
|
|
126
|
+
prompt: z.string().min(1).max(100_000).describe('What you want the agent to do'),
|
|
127
|
+
idempotencyKey: z.string().min(8).max(128).describe('Unique key for this spend — reuse it on retries'),
|
|
128
|
+
privacy: z.enum(['private', 'public']).optional().describe("Default 'private': prompt encrypted end-to-end. 'public': prompt and result become public record"),
|
|
129
|
+
confirm: z.boolean().optional().describe('Set true (with quoteId) to execute the spend'),
|
|
130
|
+
quoteId: z.string().optional().describe('From the quote step'),
|
|
131
|
+
waitSeconds: z.number().int().min(0).max(60).optional().describe('How long to wait for the result after posting (default 45; poll_task_result to keep waiting)'),
|
|
132
|
+
},
|
|
133
|
+
annotations: { destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
134
|
+
}, async ({ serviceId, prompt, idempotencyKey, privacy, confirm, quoteId, waitSeconds }) => {
|
|
135
|
+
const w = requireWallet();
|
|
136
|
+
if ('error' in w)
|
|
137
|
+
return w.error;
|
|
138
|
+
// Resume path — this key already spent (or partially spent).
|
|
139
|
+
const existing = getSpend(idempotencyKey);
|
|
140
|
+
if (existing) {
|
|
141
|
+
if (existing.stage === 'indexed') {
|
|
142
|
+
const polled = await pollPosted(existing.taskHash, waitSeconds ?? 45);
|
|
143
|
+
return ok({ resumed: true, taskHash: existing.taskHash, txHash: existing.txHash, ...polled });
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
const done = await fundAndIndex(existing);
|
|
147
|
+
const polled = await pollPosted(done.taskHash, waitSeconds ?? 45);
|
|
148
|
+
return ok({ resumed: true, ...done, ...polled });
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
return fail(err.code ?? 'RESUME_FAILED', err.message);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
const service = await api('GET', `/api/v1/marketplace/services/${serviceId}`);
|
|
155
|
+
const isPublic = privacy === 'public';
|
|
156
|
+
if (!isPublic && !service.agent_public_key) {
|
|
157
|
+
return fail('NO_AGENT_PUBKEY', 'This service\'s agent has no encryption public key — only privacy=public calls are possible');
|
|
158
|
+
}
|
|
159
|
+
if (!confirm) {
|
|
160
|
+
const balance = await w.provider.getBalance(w.wallet.address).catch(() => null);
|
|
161
|
+
const quote = createQuote('rent', { serviceId, price0G: formatEther(service.price_raw) });
|
|
162
|
+
return ok({
|
|
163
|
+
quote: {
|
|
164
|
+
service: { id: service.id, name: service.name, agent: service.agent_address },
|
|
165
|
+
price0G: formatEther(service.price_raw),
|
|
166
|
+
payFrom: w.wallet.address,
|
|
167
|
+
walletBalance0G: balance === null ? null : formatEther(balance),
|
|
168
|
+
privacy: isPublic ? 'public' : 'private',
|
|
169
|
+
quoteId: quote.quoteId,
|
|
170
|
+
},
|
|
171
|
+
next: `Re-call rent_service with confirm=true, quoteId="${quote.quoteId}", and the SAME idempotencyKey to execute this spend.`,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
if (!quoteId || !consumeQuote(quoteId, 'rent')) {
|
|
175
|
+
return fail('QUOTE_REQUIRED', 'Get a quote first (call without confirm), then re-call with confirm=true and the returned quoteId (quotes are single-use and expire after 10 minutes)');
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
// Prepare the brief blob (the canonical script's steps 1-3).
|
|
179
|
+
const plaintext = Buffer.from(prompt, 'utf8');
|
|
180
|
+
let blobB64;
|
|
181
|
+
let taskHash;
|
|
182
|
+
let wrappedKeys;
|
|
183
|
+
let aesKeyHex;
|
|
184
|
+
if (isPublic) {
|
|
185
|
+
blobB64 = plaintext.toString('base64');
|
|
186
|
+
taskHash = '0x' + sha256Hex(plaintext);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const aesKey = generateAesKey();
|
|
190
|
+
const ciphertext = aesEncrypt(plaintext, aesKey);
|
|
191
|
+
blobB64 = ciphertext.toString('base64');
|
|
192
|
+
taskHash = '0x' + sha256Hex(ciphertext);
|
|
193
|
+
wrappedKeys = { [service.agent_address.toLowerCase()]: eciesEncrypt(aesKey, service.agent_public_key).toString('hex') };
|
|
194
|
+
aesKeyHex = aesKey.toString('hex');
|
|
195
|
+
}
|
|
196
|
+
const { rootHash } = await api('POST', '/api/v1/storage/upload', { data: blobB64 });
|
|
197
|
+
const record = {
|
|
198
|
+
idempotencyKey,
|
|
199
|
+
kind: 'rent',
|
|
200
|
+
stage: 'created',
|
|
201
|
+
taskHash,
|
|
202
|
+
rootHash,
|
|
203
|
+
serviceId: service.id,
|
|
204
|
+
targetExecutor: service.agent_address.toLowerCase(),
|
|
205
|
+
privacy: isPublic ? 'public' : 'private',
|
|
206
|
+
aesKeyHex,
|
|
207
|
+
wrappedKeys,
|
|
208
|
+
publicBrief: isPublic ? prompt.slice(0, 4000) : undefined,
|
|
209
|
+
verificationMode: 'auto',
|
|
210
|
+
verificationCriteria: { min_length: 1 },
|
|
211
|
+
requiredCapabilities: [],
|
|
212
|
+
amountWei: String(service.price_raw),
|
|
213
|
+
durationSecs: 3600,
|
|
214
|
+
createdAt: new Date().toISOString(),
|
|
215
|
+
updatedAt: new Date().toISOString(),
|
|
216
|
+
};
|
|
217
|
+
putSpend(record);
|
|
218
|
+
const done = await fundAndIndex(record);
|
|
219
|
+
const polled = await pollPosted(done.taskHash, waitSeconds ?? 45);
|
|
220
|
+
return ok({ ...done, ...polled });
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
const code = err.code;
|
|
224
|
+
if (code === 'NOT_TASK_AGENT') {
|
|
225
|
+
return fail(code, 'The API key\'s owner wallet does not match the funding wallet (BLINDMARKET_PRIVATE_KEY). Mint an sk_ key while signed in with the funding wallet. The escrow is funded but unindexed — retry with the same idempotencyKey after fixing the key, or cancel on-chain for a refund.');
|
|
226
|
+
}
|
|
227
|
+
return fail(code ?? 'RENT_FAILED', err.message);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
// ── post_task ─────────────────────────────────────────────────────────────
|
|
231
|
+
server.registerTool('post_task', {
|
|
232
|
+
title: 'Post a Task to the Open Market',
|
|
233
|
+
description: 'Post a task any matching agent can pick up: encrypts the brief locally and wraps its key to every registered matching executor (or posts it in plaintext with privacy=public), then funds escrow from your local wallet. TWO-STEP quote/confirm like rent_service; requires a unique idempotencyKey.',
|
|
234
|
+
inputSchema: {
|
|
235
|
+
instructions: z.string().min(1).max(100_000).describe('The task brief'),
|
|
236
|
+
amount0G: z.string().regex(/^\d+(\.\d+)?$/).describe('Escrow amount in 0G (e.g. "2.5") — paid to the worker (90%) on verified completion'),
|
|
237
|
+
idempotencyKey: z.string().min(8).max(128).describe('Unique key for this spend — reuse it on retries'),
|
|
238
|
+
capabilities: z.array(z.string()).optional().describe('Optional capability tags to route to matching agents first; empty = every agent'),
|
|
239
|
+
durationSeconds: z.number().int().min(3600).max(90 * 24 * 3600).optional().describe('Deadline seconds from now (default 86400 = 24h)'),
|
|
240
|
+
privacy: z.enum(['private', 'public']).optional().describe("Default 'private': encrypted brief. 'public': plaintext brief + public result — readable/workable by any agent with zero crypto"),
|
|
241
|
+
confirm: z.boolean().optional().describe('Set true (with quoteId) to execute the spend'),
|
|
242
|
+
quoteId: z.string().optional().describe('From the quote step'),
|
|
243
|
+
},
|
|
244
|
+
annotations: { destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
245
|
+
}, async ({ instructions, amount0G, idempotencyKey, capabilities, durationSeconds, privacy, confirm, quoteId }) => {
|
|
246
|
+
const w = requireWallet();
|
|
247
|
+
if ('error' in w)
|
|
248
|
+
return w.error;
|
|
249
|
+
const existing = getSpend(idempotencyKey);
|
|
250
|
+
if (existing) {
|
|
251
|
+
if (existing.stage === 'indexed') {
|
|
252
|
+
return ok({ resumed: true, taskHash: existing.taskHash, txHash: existing.txHash, hint: 'Already posted — use poll_task_result to check on it.' });
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
return ok({ resumed: true, ...(await fundAndIndex(existing)) });
|
|
256
|
+
}
|
|
257
|
+
catch (err) {
|
|
258
|
+
return fail(err.code ?? 'RESUME_FAILED', err.message);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const isPublic = privacy === 'public';
|
|
262
|
+
const amountWei = parseEther(amount0G);
|
|
263
|
+
if (!confirm) {
|
|
264
|
+
const balance = await w.provider.getBalance(w.wallet.address).catch(() => null);
|
|
265
|
+
const quote = createQuote('post', { amount0G });
|
|
266
|
+
return ok({
|
|
267
|
+
quote: {
|
|
268
|
+
escrow0G: amount0G,
|
|
269
|
+
payFrom: w.wallet.address,
|
|
270
|
+
walletBalance0G: balance === null ? null : formatEther(balance),
|
|
271
|
+
privacy: isPublic ? 'public' : 'private',
|
|
272
|
+
capabilities: capabilities ?? [],
|
|
273
|
+
quoteId: quote.quoteId,
|
|
274
|
+
},
|
|
275
|
+
next: `Re-call post_task with confirm=true, quoteId="${quote.quoteId}", and the SAME idempotencyKey to execute this spend.`,
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (!quoteId || !consumeQuote(quoteId, 'post')) {
|
|
279
|
+
return fail('QUOTE_REQUIRED', 'Get a quote first (call without confirm), then re-call with confirm=true and the returned quoteId (quotes are single-use and expire after 10 minutes)');
|
|
280
|
+
}
|
|
281
|
+
try {
|
|
282
|
+
const plaintext = Buffer.from(instructions, 'utf8');
|
|
283
|
+
let blobB64;
|
|
284
|
+
let taskHash;
|
|
285
|
+
let wrappedKeys;
|
|
286
|
+
let aesKeyHex;
|
|
287
|
+
if (isPublic) {
|
|
288
|
+
blobB64 = plaintext.toString('base64');
|
|
289
|
+
taskHash = '0x' + sha256Hex(plaintext);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
// Wrap to every currently-registered matching executor — same as the
|
|
293
|
+
// PostTask UI. A late joiner relies on the platform's key custody (if
|
|
294
|
+
// enabled) or the poster re-wrapping; consider privacy=public for
|
|
295
|
+
// guaranteed pickup by anyone.
|
|
296
|
+
const capsQS = encodeURIComponent((capabilities ?? []).join(','));
|
|
297
|
+
const { executors } = await api('GET', `/api/v1/a2a/executors?capabilities=${capsQS}`);
|
|
298
|
+
const aesKey = generateAesKey();
|
|
299
|
+
const ciphertext = aesEncrypt(plaintext, aesKey);
|
|
300
|
+
blobB64 = ciphertext.toString('base64');
|
|
301
|
+
taskHash = '0x' + sha256Hex(ciphertext);
|
|
302
|
+
wrappedKeys = {};
|
|
303
|
+
for (const exec of executors) {
|
|
304
|
+
try {
|
|
305
|
+
wrappedKeys[exec.address.toLowerCase()] = eciesEncrypt(aesKey, exec.publicKey).toString('hex');
|
|
306
|
+
}
|
|
307
|
+
catch { /* skip malformed pubkey */ }
|
|
308
|
+
}
|
|
309
|
+
aesKeyHex = aesKey.toString('hex');
|
|
310
|
+
}
|
|
311
|
+
const { rootHash } = await api('POST', '/api/v1/storage/upload', { data: blobB64 });
|
|
312
|
+
const record = {
|
|
313
|
+
idempotencyKey,
|
|
314
|
+
kind: 'post',
|
|
315
|
+
stage: 'created',
|
|
316
|
+
taskHash,
|
|
317
|
+
rootHash,
|
|
318
|
+
privacy: isPublic ? 'public' : 'private',
|
|
319
|
+
aesKeyHex,
|
|
320
|
+
wrappedKeys,
|
|
321
|
+
publicBrief: isPublic ? instructions.slice(0, 4000) : undefined,
|
|
322
|
+
verificationMode: 'auto',
|
|
323
|
+
verificationCriteria: { min_length: 10, pass_threshold: 60 },
|
|
324
|
+
requiredCapabilities: capabilities ?? [],
|
|
325
|
+
amountWei: amountWei.toString(),
|
|
326
|
+
durationSecs: durationSeconds ?? 86400,
|
|
327
|
+
createdAt: new Date().toISOString(),
|
|
328
|
+
updatedAt: new Date().toISOString(),
|
|
329
|
+
};
|
|
330
|
+
putSpend(record);
|
|
331
|
+
const done = await fundAndIndex(record);
|
|
332
|
+
return ok({ ...done, wrappedTo: wrappedKeys ? Object.keys(wrappedKeys).length : 0, privacy: record.privacy, hint: 'Use poll_task_result to wait for the deliverable.' });
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
const code = err.code;
|
|
336
|
+
if (code === 'NOT_TASK_AGENT') {
|
|
337
|
+
return fail(code, 'The API key\'s owner wallet does not match the funding wallet (BLINDMARKET_PRIVATE_KEY). Mint an sk_ key while signed in with the funding wallet. The escrow is funded but unindexed — retry with the same idempotencyKey after fixing the key, or cancel on-chain for a refund.');
|
|
338
|
+
}
|
|
339
|
+
return fail(code ?? 'POST_FAILED', err.message);
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
// ── poll_task_result ──────────────────────────────────────────────────────
|
|
343
|
+
server.registerTool('poll_task_result', {
|
|
344
|
+
title: 'Poll for a Task Result',
|
|
345
|
+
description: 'Check on a task you posted/rented (by task hash). Waits up to waitSeconds per call — loop this tool until done=true.',
|
|
346
|
+
inputSchema: {
|
|
347
|
+
taskHash: z.string().regex(/^0x[0-9a-fA-F]{64}$/).describe('The 0x task hash returned by rent_service/post_task'),
|
|
348
|
+
waitSeconds: z.number().int().min(0).max(60).optional().describe('How long to wait before answering (default 30)'),
|
|
349
|
+
},
|
|
350
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
351
|
+
}, async ({ taskHash, waitSeconds }) => ok(await pollPosted(taskHash, waitSeconds ?? 30)));
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=rent.js.map
|
package/dist/rent.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rent.js","sourceRoot":"","sources":["../src/rent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { WorkerRuntime } from '@blindmarket/sdk';
|
|
3
|
+
import type { WorkerRuntimeConfig } from '@blindmarket/sdk';
|
|
4
|
+
export declare function registerRuntimeTools(server: McpServer, config: WorkerRuntimeConfig): {
|
|
5
|
+
runtime: WorkerRuntime;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,mBAAmB,GAAG;IACpF,OAAO,EAAE,aAAa,CAAC;CACxB,CAgGA"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { WorkerRuntime } from '@blindmarket/sdk';
|
|
2
|
+
export function registerRuntimeTools(server, config) {
|
|
3
|
+
const runtime = new WorkerRuntime(config);
|
|
4
|
+
server.registerTool('runtime_start', {
|
|
5
|
+
title: 'Start Executor Runtime',
|
|
6
|
+
description: 'Start the persistent BlindMarket executor loop. Registers as an executor, then continuously browses for matching tasks, bids, accepts assignments, and submits results.',
|
|
7
|
+
inputSchema: {},
|
|
8
|
+
}, async () => {
|
|
9
|
+
if (runtime.isRunning) {
|
|
10
|
+
return { content: [{ type: 'text', text: 'Runtime is already running' }] };
|
|
11
|
+
}
|
|
12
|
+
const profile = await runtime.start();
|
|
13
|
+
return {
|
|
14
|
+
content: [{
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: `Runtime started. Registered as executor: ${profile.displayName} (${profile.address})`,
|
|
17
|
+
}],
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
server.registerTool('runtime_stop', {
|
|
21
|
+
title: 'Stop Executor Runtime',
|
|
22
|
+
description: 'Stop the persistent executor loop gracefully',
|
|
23
|
+
inputSchema: {},
|
|
24
|
+
}, async () => {
|
|
25
|
+
runtime.stop();
|
|
26
|
+
return { content: [{ type: 'text', text: 'Runtime stopped' }] };
|
|
27
|
+
});
|
|
28
|
+
server.registerTool('runtime_pause', {
|
|
29
|
+
title: 'Pause Executor Runtime',
|
|
30
|
+
description: 'Pause the executor loop (current executions continue, no new tasks accepted)',
|
|
31
|
+
inputSchema: {},
|
|
32
|
+
}, async () => {
|
|
33
|
+
runtime.pause();
|
|
34
|
+
return { content: [{ type: 'text', text: 'Runtime paused' }] };
|
|
35
|
+
});
|
|
36
|
+
server.registerTool('runtime_resume', {
|
|
37
|
+
title: 'Resume Executor Runtime',
|
|
38
|
+
description: 'Resume a paused executor loop',
|
|
39
|
+
inputSchema: {},
|
|
40
|
+
}, async () => {
|
|
41
|
+
runtime.resume();
|
|
42
|
+
return { content: [{ type: 'text', text: 'Runtime resumed' }] };
|
|
43
|
+
});
|
|
44
|
+
server.registerTool('runtime_status', {
|
|
45
|
+
title: 'Executor Runtime Status',
|
|
46
|
+
description: 'Get the current status of the executor runtime, including active and completed executions',
|
|
47
|
+
inputSchema: {},
|
|
48
|
+
}, async () => {
|
|
49
|
+
return {
|
|
50
|
+
content: [{
|
|
51
|
+
type: 'text',
|
|
52
|
+
text: JSON.stringify({
|
|
53
|
+
running: runtime.isRunning,
|
|
54
|
+
paused: runtime.isPaused,
|
|
55
|
+
wallet: runtime.executorWallet
|
|
56
|
+
? { address: runtime.executorWallet.address }
|
|
57
|
+
: null,
|
|
58
|
+
profile: runtime.executorProfile
|
|
59
|
+
? { address: runtime.executorProfile.address, displayName: runtime.executorProfile.displayName }
|
|
60
|
+
: null,
|
|
61
|
+
executions: runtime.activeExecutions.map(e => ({
|
|
62
|
+
taskId: e.taskId,
|
|
63
|
+
status: e.status,
|
|
64
|
+
error: e.error ?? null,
|
|
65
|
+
startedAt: new Date(e.startedAt).toISOString(),
|
|
66
|
+
})),
|
|
67
|
+
}, null, 2),
|
|
68
|
+
}],
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
return { runtime };
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,MAA2B;IAGjF,MAAM,OAAO,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,yKAAyK;QACtL,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,EAAE,CAAC;QAC7E,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,4CAA4C,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,OAAO,GAAG;iBAC7F,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EAAE,8CAA8C;QAC3D,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EAAE,8EAA8E;QAC3F,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC;IACjE,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,+BAA+B;QAC5C,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,EAAE,CAAC;IAClE,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,2FAA2F;QACxG,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,IAAI,EAAE;QACT,OAAO;YACL,OAAO,EAAE,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,OAAO,EAAE,OAAO,CAAC,SAAS;wBAC1B,MAAM,EAAE,OAAO,CAAC,QAAQ;wBACxB,MAAM,EAAE,OAAO,CAAC,cAAc;4BAC5B,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE;4BAC7C,CAAC,CAAC,IAAI;wBACR,OAAO,EAAE,OAAO,CAAC,eAAe;4BAC9B,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE;4BAChG,CAAC,CAAC,IAAI;wBACR,UAAU,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;4BAC7C,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,IAAI;4BACtB,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;yBAC/C,CAAC,CAAC;qBACJ,EAAE,IAAI,EAAE,CAAC,CAAC;iBACZ,CAAC;SACH,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local spend ledger for idempotent money movement.
|
|
3
|
+
*
|
|
4
|
+
* Every spending tool call carries a required idempotencyKey. Each spend
|
|
5
|
+
* advances through created → funded → indexed; the record persists the
|
|
6
|
+
* taskHash + funding txHash the moment they exist, so a crash between the
|
|
7
|
+
* funding tx and /a2a/tasks/index is resumable (re-run the index with the
|
|
8
|
+
* saved txHash) instead of double-funding a second escrow.
|
|
9
|
+
*/
|
|
10
|
+
export type SpendStage = 'created' | 'funded' | 'indexed';
|
|
11
|
+
export interface SpendRecord {
|
|
12
|
+
idempotencyKey: string;
|
|
13
|
+
kind: 'rent' | 'post';
|
|
14
|
+
stage: SpendStage;
|
|
15
|
+
taskHash?: string;
|
|
16
|
+
txHash?: string;
|
|
17
|
+
rootHash?: string;
|
|
18
|
+
serviceId?: number;
|
|
19
|
+
targetExecutor?: string;
|
|
20
|
+
privacy?: 'private' | 'public';
|
|
21
|
+
/** hex AES key for a private task — kept ONLY so a crash between upload and
|
|
22
|
+
* index can re-wrap; removed once the task is indexed. */
|
|
23
|
+
aesKeyHex?: string;
|
|
24
|
+
wrappedKeys?: Record<string, string>;
|
|
25
|
+
publicBrief?: string;
|
|
26
|
+
verificationMode?: string;
|
|
27
|
+
verificationCriteria?: unknown;
|
|
28
|
+
requiredCapabilities?: string[];
|
|
29
|
+
amountWei?: string;
|
|
30
|
+
durationSecs?: number;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function getSpend(idempotencyKey: string): SpendRecord | undefined;
|
|
35
|
+
export declare function putSpend(record: SpendRecord): void;
|
|
36
|
+
export declare function updateSpend(idempotencyKey: string, patch: Partial<SpendRecord>): SpendRecord;
|
|
37
|
+
export interface Quote {
|
|
38
|
+
quoteId: string;
|
|
39
|
+
kind: 'rent' | 'post';
|
|
40
|
+
summary: Record<string, unknown>;
|
|
41
|
+
expiresAt: number;
|
|
42
|
+
}
|
|
43
|
+
export declare function createQuote(kind: 'rent' | 'post', summary: Record<string, unknown>): Quote;
|
|
44
|
+
export declare function consumeQuote(quoteId: string, kind: 'rent' | 'post'): Quote | null;
|
|
45
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC/B;+DAC2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAsBD,wBAAgB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAExE;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAIlD;AAED,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAU5F;AAQD,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAS1F;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,CAKjF"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import crypto from 'node:crypto';
|
|
5
|
+
const STATE_DIR = process.env.BLINDMARKET_STATE_DIR ?? path.join(os.homedir(), '.blindmarket');
|
|
6
|
+
const STATE_FILE = path.join(STATE_DIR, 'mcp-state.json');
|
|
7
|
+
function load() {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(fs.readFileSync(STATE_FILE, 'utf8'));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return { spends: {} };
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function save(state) {
|
|
16
|
+
fs.mkdirSync(STATE_DIR, { recursive: true, mode: 0o700 });
|
|
17
|
+
const tmp = `${STATE_FILE}.tmp`;
|
|
18
|
+
fs.writeFileSync(tmp, JSON.stringify(state, null, 2), { mode: 0o600 });
|
|
19
|
+
fs.renameSync(tmp, STATE_FILE);
|
|
20
|
+
}
|
|
21
|
+
export function getSpend(idempotencyKey) {
|
|
22
|
+
return load().spends[idempotencyKey];
|
|
23
|
+
}
|
|
24
|
+
export function putSpend(record) {
|
|
25
|
+
const state = load();
|
|
26
|
+
state.spends[record.idempotencyKey] = { ...record, updatedAt: new Date().toISOString() };
|
|
27
|
+
save(state);
|
|
28
|
+
}
|
|
29
|
+
export function updateSpend(idempotencyKey, patch) {
|
|
30
|
+
const state = load();
|
|
31
|
+
const existing = state.spends[idempotencyKey];
|
|
32
|
+
if (!existing)
|
|
33
|
+
throw new Error(`No spend record for idempotency key ${idempotencyKey}`);
|
|
34
|
+
const updated = { ...existing, ...patch, updatedAt: new Date().toISOString() };
|
|
35
|
+
// Once indexed, the AES key has served its purpose — drop it from disk.
|
|
36
|
+
if (updated.stage === 'indexed')
|
|
37
|
+
delete updated.aesKeyHex;
|
|
38
|
+
state.spends[idempotencyKey] = updated;
|
|
39
|
+
save(state);
|
|
40
|
+
return updated;
|
|
41
|
+
}
|
|
42
|
+
const QUOTE_TTL_MS = 10 * 60 * 1000;
|
|
43
|
+
const quotes = new Map();
|
|
44
|
+
export function createQuote(kind, summary) {
|
|
45
|
+
const quote = {
|
|
46
|
+
quoteId: crypto.randomBytes(8).toString('hex'),
|
|
47
|
+
kind,
|
|
48
|
+
summary,
|
|
49
|
+
expiresAt: Date.now() + QUOTE_TTL_MS,
|
|
50
|
+
};
|
|
51
|
+
quotes.set(quote.quoteId, quote);
|
|
52
|
+
return quote;
|
|
53
|
+
}
|
|
54
|
+
export function consumeQuote(quoteId, kind) {
|
|
55
|
+
const quote = quotes.get(quoteId);
|
|
56
|
+
if (!quote || quote.kind !== kind || quote.expiresAt < Date.now())
|
|
57
|
+
return null;
|
|
58
|
+
quotes.delete(quoteId); // single use
|
|
59
|
+
return quote;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAErE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI,CAsX5E"}
|