moltlaunch 2.0.0 → 2.0.2
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 +2 -2
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
- package/.claude/commands/deploy.md +0 -33
- package/.claude/hooks/regenerate-docs.sh +0 -12
- package/.claude/settings.json +0 -15
- package/.env.example +0 -2
- package/.github/workflows/deploy.yml +0 -37
- package/ROADMAP.md +0 -29
- package/contracts/MandateEscrowV4.sol +0 -281
- package/contracts/mocks/MockFlaunchBuyback.sol +0 -24
- package/hardhat.config.cjs +0 -29
- package/scripts/check-deploy-cost.ts +0 -15
- package/scripts/deploy-escrow-v4.ts +0 -81
- package/scripts/deploy-escrow.cjs +0 -22
- package/scripts/generate-docs.ts +0 -309
- package/shared/manifest.json +0 -87
- package/site/.vscode/extensions.json +0 -4
- package/site/.vscode/launch.json +0 -11
- package/site/README.md +0 -43
- package/site/astro.config.mjs +0 -21
- package/site/functions/agent/[[path]].ts +0 -9
- package/site/functions/task/[[path]].ts +0 -9
- package/site/index.html.bak +0 -1755
- package/site/package-lock.json +0 -6165
- package/site/package.json +0 -17
- package/site/public/_redirects +0 -1
- package/site/public/art/hero.webp +0 -0
- package/site/public/favicon.ico +0 -0
- package/site/public/favicon.svg +0 -4
- package/site/public/logo.png +0 -0
- package/site/public/skill.md +0 -276
- package/site/src/components/AgentGridCard.astro +0 -97
- package/site/src/components/AgentRow.astro +0 -75
- package/site/src/components/Footer.astro +0 -71
- package/site/src/components/GigCard.astro +0 -36
- package/site/src/components/Navbar.astro +0 -93
- package/site/src/components/ReviewCard.astro +0 -29
- package/site/src/components/SkillPill.astro +0 -19
- package/site/src/components/StatusBadge.astro +0 -27
- package/site/src/components/TaskEntry.astro +0 -98
- package/site/src/layouts/Layout.astro +0 -268
- package/site/src/lib/api.ts +0 -342
- package/site/src/pages/404.astro +0 -33
- package/site/src/pages/admin.astro +0 -445
- package/site/src/pages/agent/[...id].astro +0 -678
- package/site/src/pages/agents/index.astro +0 -235
- package/site/src/pages/dashboard.astro +0 -244
- package/site/src/pages/docs.astro +0 -191
- package/site/src/pages/how.astro +0 -156
- package/site/src/pages/index.astro +0 -226
- package/site/src/pages/leaderboard.astro +0 -155
- package/site/src/pages/task/[...id].astro +0 -1467
- package/site/src/styles/global.css +0 -159
- package/site/tailwind.config.mjs +0 -94
- package/site/tsconfig.json +0 -5
- package/site/wrangler.toml +0 -5
- package/src/commands/accept.ts +0 -135
- package/src/commands/agents.ts +0 -190
- package/src/commands/approve.ts +0 -127
- package/src/commands/claim.ts +0 -130
- package/src/commands/decline.ts +0 -55
- package/src/commands/dispute.ts +0 -92
- package/src/commands/earnings.ts +0 -86
- package/src/commands/feedback.ts +0 -147
- package/src/commands/gig.ts +0 -141
- package/src/commands/hire.ts +0 -96
- package/src/commands/inbox.ts +0 -135
- package/src/commands/message.ts +0 -97
- package/src/commands/profile.ts +0 -62
- package/src/commands/quote.ts +0 -80
- package/src/commands/refund.ts +0 -82
- package/src/commands/register.ts +0 -250
- package/src/commands/resolve.ts +0 -104
- package/src/commands/reviews.ts +0 -78
- package/src/commands/revise.ts +0 -65
- package/src/commands/submit.ts +0 -123
- package/src/commands/tasks.ts +0 -224
- package/src/commands/view.ts +0 -122
- package/src/commands/wallet.ts +0 -42
- package/src/index.ts +0 -285
- package/src/lib/agent0.ts +0 -158
- package/src/lib/auth.ts +0 -25
- package/src/lib/constants.ts +0 -55
- package/src/lib/escrow.ts +0 -374
- package/src/lib/files.ts +0 -87
- package/src/lib/flaunch.ts +0 -277
- package/src/lib/mandate.ts +0 -623
- package/src/lib/tasks.ts +0 -466
- package/src/lib/types.ts +0 -112
- package/src/lib/wallet.ts +0 -119
- package/src/lib/x402.ts +0 -86
- package/test/MandateEscrowV4.test.cjs +0 -568
- package/tsconfig.json +0 -19
- package/tsup.config.ts +0 -15
- package/worker/package-lock.json +0 -1812
- package/worker/package.json +0 -18
- package/worker/src/agents.ts +0 -755
- package/worker/src/auth.ts +0 -126
- package/worker/src/files.ts +0 -40
- package/worker/src/index.ts +0 -963
- package/worker/src/profiles.ts +0 -85
- package/worker/src/ratelimit.ts +0 -45
- package/worker/src/tasks.ts +0 -498
- package/worker/src/types.ts +0 -95
- package/worker/tsconfig.json +0 -15
- package/worker/wrangler.toml +0 -19
package/src/lib/tasks.ts
DELETED
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
// MANDATE Task Queue API client
|
|
2
|
-
// Quote-based flow: request → quote → accept → submit → complete
|
|
3
|
-
// All mutating actions require wallet signature for authentication
|
|
4
|
-
|
|
5
|
-
import { APIS } from "./constants.js";
|
|
6
|
-
import { signAction } from "./auth.js";
|
|
7
|
-
import type { Wallet, TaskFile, TaskMessage } from "./types.js";
|
|
8
|
-
|
|
9
|
-
export interface Task {
|
|
10
|
-
id: string;
|
|
11
|
-
agentId: string;
|
|
12
|
-
clientAddress: string;
|
|
13
|
-
task: string;
|
|
14
|
-
status: "requested" | "quoted" | "accepted" | "submitted" | "revision" | "completed" | "declined" | "expired" | "disputed" | "resolved";
|
|
15
|
-
createdAt: number;
|
|
16
|
-
// Quote phase
|
|
17
|
-
quotedPriceWei?: string;
|
|
18
|
-
quotedAt?: number;
|
|
19
|
-
quotedMessage?: string;
|
|
20
|
-
// Work phase
|
|
21
|
-
acceptedAt?: number;
|
|
22
|
-
submittedAt?: number;
|
|
23
|
-
completedAt?: number;
|
|
24
|
-
result?: string;
|
|
25
|
-
files?: TaskFile[];
|
|
26
|
-
txHash?: string;
|
|
27
|
-
// Messages + revisions
|
|
28
|
-
messages?: TaskMessage[];
|
|
29
|
-
revisionCount?: number;
|
|
30
|
-
// Feedback
|
|
31
|
-
ratedAt?: number;
|
|
32
|
-
ratedTxHash?: string;
|
|
33
|
-
ratedScore?: number;
|
|
34
|
-
ratedComment?: string;
|
|
35
|
-
// Dispute phase
|
|
36
|
-
disputedAt?: number;
|
|
37
|
-
resolvedAt?: number;
|
|
38
|
-
disputeTxHash?: string;
|
|
39
|
-
resolveTxHash?: string;
|
|
40
|
-
disputeResolution?: "client" | "agent";
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
interface TaskResponse {
|
|
44
|
-
task: Task;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface TaskListResponse {
|
|
48
|
-
tasks: Task[];
|
|
49
|
-
total: number;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
interface ErrorResponse {
|
|
53
|
-
error: string;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const API_BASE = APIS.MANDATE;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Create a new task request (no price - agent will quote)
|
|
60
|
-
*/
|
|
61
|
-
export async function createTask(
|
|
62
|
-
agentId: string,
|
|
63
|
-
clientAddress: string,
|
|
64
|
-
taskDescription: string,
|
|
65
|
-
): Promise<Task> {
|
|
66
|
-
const response = await fetch(`${API_BASE}/api/tasks`, {
|
|
67
|
-
method: "POST",
|
|
68
|
-
headers: { "Content-Type": "application/json" },
|
|
69
|
-
body: JSON.stringify({
|
|
70
|
-
agentId,
|
|
71
|
-
clientAddress,
|
|
72
|
-
task: taskDescription,
|
|
73
|
-
}),
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
if (!response.ok) {
|
|
77
|
-
const error = (await response.json()) as ErrorResponse;
|
|
78
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const data = (await response.json()) as TaskResponse;
|
|
82
|
-
return data.task;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Get pending tasks for an agent (inbox)
|
|
87
|
-
*/
|
|
88
|
-
export async function getInbox(agentId: string): Promise<Task[]> {
|
|
89
|
-
const response = await fetch(`${API_BASE}/api/tasks/inbox?agent=${encodeURIComponent(agentId)}`);
|
|
90
|
-
|
|
91
|
-
if (!response.ok) {
|
|
92
|
-
const error = (await response.json()) as ErrorResponse;
|
|
93
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const data = (await response.json()) as TaskListResponse;
|
|
97
|
-
return data.tasks;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Get tasks created by a client
|
|
102
|
-
*/
|
|
103
|
-
export async function getClientTasks(clientAddress: string): Promise<Task[]> {
|
|
104
|
-
const response = await fetch(
|
|
105
|
-
`${API_BASE}/api/tasks/client?address=${encodeURIComponent(clientAddress)}`,
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
if (!response.ok) {
|
|
109
|
-
const error = (await response.json()) as ErrorResponse;
|
|
110
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const data = (await response.json()) as TaskListResponse;
|
|
114
|
-
return data.tasks;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get a specific task by ID
|
|
119
|
-
*/
|
|
120
|
-
export async function getTask(taskId: string): Promise<Task> {
|
|
121
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}`);
|
|
122
|
-
|
|
123
|
-
if (!response.ok) {
|
|
124
|
-
const error = (await response.json()) as ErrorResponse;
|
|
125
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const data = (await response.json()) as TaskResponse;
|
|
129
|
-
return data.task;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Agent quotes a price for a task (AUTHENTICATED: agent owner)
|
|
134
|
-
*/
|
|
135
|
-
export async function quoteTask(
|
|
136
|
-
wallet: Wallet,
|
|
137
|
-
taskId: string,
|
|
138
|
-
priceWei: string,
|
|
139
|
-
message?: string,
|
|
140
|
-
): Promise<Task> {
|
|
141
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "quote", taskId);
|
|
142
|
-
|
|
143
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/quote`, {
|
|
144
|
-
method: "POST",
|
|
145
|
-
headers: { "Content-Type": "application/json" },
|
|
146
|
-
body: JSON.stringify({ priceWei, message, signature, timestamp, nonce }),
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
if (!response.ok) {
|
|
150
|
-
const error = (await response.json()) as ErrorResponse;
|
|
151
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const data = (await response.json()) as TaskResponse;
|
|
155
|
-
return data.task;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Agent declines a task (AUTHENTICATED: agent owner)
|
|
160
|
-
*/
|
|
161
|
-
export async function declineTask(wallet: Wallet, taskId: string): Promise<Task> {
|
|
162
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "decline", taskId);
|
|
163
|
-
|
|
164
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/decline`, {
|
|
165
|
-
method: "POST",
|
|
166
|
-
headers: { "Content-Type": "application/json" },
|
|
167
|
-
body: JSON.stringify({ signature, timestamp, nonce }),
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
if (!response.ok) {
|
|
171
|
-
const error = (await response.json()) as ErrorResponse;
|
|
172
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const data = (await response.json()) as TaskResponse;
|
|
176
|
-
return data.task;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Client accepts a quote (AUTHENTICATED: task client)
|
|
181
|
-
*/
|
|
182
|
-
export async function acceptQuote(wallet: Wallet, taskId: string): Promise<Task> {
|
|
183
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "accept", taskId);
|
|
184
|
-
|
|
185
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/accept`, {
|
|
186
|
-
method: "POST",
|
|
187
|
-
headers: { "Content-Type": "application/json" },
|
|
188
|
-
body: JSON.stringify({ clientAddress: wallet.address, signature, timestamp, nonce }),
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
if (!response.ok) {
|
|
192
|
-
const error = (await response.json()) as ErrorResponse;
|
|
193
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const data = (await response.json()) as TaskResponse;
|
|
197
|
-
return data.task;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Agent submits work result (AUTHENTICATED: agent owner)
|
|
202
|
-
*/
|
|
203
|
-
export async function submitTask(
|
|
204
|
-
wallet: Wallet,
|
|
205
|
-
taskId: string,
|
|
206
|
-
result: string,
|
|
207
|
-
files?: TaskFile[],
|
|
208
|
-
): Promise<Task> {
|
|
209
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "submit", taskId);
|
|
210
|
-
|
|
211
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/submit`, {
|
|
212
|
-
method: "POST",
|
|
213
|
-
headers: { "Content-Type": "application/json" },
|
|
214
|
-
body: JSON.stringify({ result, files, signature, timestamp, nonce }),
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
if (!response.ok) {
|
|
218
|
-
const error = (await response.json()) as ErrorResponse;
|
|
219
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const data = (await response.json()) as TaskResponse;
|
|
223
|
-
return data.task;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Mark task as completed after payment (AUTHENTICATED: task client)
|
|
228
|
-
*/
|
|
229
|
-
export async function completeTask(wallet: Wallet, taskId: string, txHash: string): Promise<Task> {
|
|
230
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "complete", taskId);
|
|
231
|
-
|
|
232
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/complete`, {
|
|
233
|
-
method: "POST",
|
|
234
|
-
headers: { "Content-Type": "application/json" },
|
|
235
|
-
body: JSON.stringify({ txHash, signature, timestamp, nonce }),
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
if (!response.ok) {
|
|
239
|
-
const error = (await response.json()) as ErrorResponse;
|
|
240
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const data = (await response.json()) as TaskResponse;
|
|
244
|
-
return data.task;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Client requests revision on submitted work (AUTHENTICATED: task client)
|
|
249
|
-
*/
|
|
250
|
-
export async function requestRevision(wallet: Wallet, taskId: string, reason: string): Promise<Task> {
|
|
251
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "revise", taskId);
|
|
252
|
-
|
|
253
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/revise`, {
|
|
254
|
-
method: "POST",
|
|
255
|
-
headers: { "Content-Type": "application/json" },
|
|
256
|
-
body: JSON.stringify({ reason, signature, timestamp, nonce }),
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
if (!response.ok) {
|
|
260
|
-
const error = (await response.json()) as ErrorResponse;
|
|
261
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const data = (await response.json()) as TaskResponse;
|
|
265
|
-
return data.task;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Send a message on a task (AUTHENTICATED: client or agent owner)
|
|
270
|
-
*/
|
|
271
|
-
export async function sendMessage(wallet: Wallet, taskId: string, content: string): Promise<Task> {
|
|
272
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "message", taskId);
|
|
273
|
-
|
|
274
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/message`, {
|
|
275
|
-
method: "POST",
|
|
276
|
-
headers: { "Content-Type": "application/json" },
|
|
277
|
-
body: JSON.stringify({ content, signature, timestamp, nonce }),
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
if (!response.ok) {
|
|
281
|
-
const error = (await response.json()) as ErrorResponse;
|
|
282
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const data = (await response.json()) as TaskResponse;
|
|
286
|
-
return data.task;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Client refunds a task (AUTHENTICATED: task client)
|
|
291
|
-
*/
|
|
292
|
-
export async function refundTaskRequest(
|
|
293
|
-
wallet: Wallet,
|
|
294
|
-
taskId: string,
|
|
295
|
-
txHash: string,
|
|
296
|
-
): Promise<Task> {
|
|
297
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "refund", taskId);
|
|
298
|
-
|
|
299
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/refund`, {
|
|
300
|
-
method: "POST",
|
|
301
|
-
headers: { "Content-Type": "application/json" },
|
|
302
|
-
body: JSON.stringify({ txHash, signature, timestamp, nonce }),
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
if (!response.ok) {
|
|
306
|
-
const error = (await response.json()) as ErrorResponse;
|
|
307
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const data = (await response.json()) as TaskResponse;
|
|
311
|
-
return data.task;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Client rates an agent after task completion (AUTHENTICATED: task client)
|
|
316
|
-
*/
|
|
317
|
-
export async function rateTask(
|
|
318
|
-
wallet: Wallet,
|
|
319
|
-
taskId: string,
|
|
320
|
-
txHash: string,
|
|
321
|
-
score?: number,
|
|
322
|
-
comment?: string,
|
|
323
|
-
): Promise<Task> {
|
|
324
|
-
const { signature, timestamp, nonce } = await signAction(wallet, "rate", taskId);
|
|
325
|
-
|
|
326
|
-
const response = await fetch(`${API_BASE}/api/tasks/${taskId}/rate`, {
|
|
327
|
-
method: "POST",
|
|
328
|
-
headers: { "Content-Type": "application/json" },
|
|
329
|
-
body: JSON.stringify({ txHash, score, comment, signature, timestamp, nonce }),
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
if (!response.ok) {
|
|
333
|
-
const error = (await response.json()) as ErrorResponse;
|
|
334
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const data = (await response.json()) as TaskResponse;
|
|
338
|
-
return data.task;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// --- Profile API ---
|
|
342
|
-
|
|
343
|
-
export interface AgentProfile {
|
|
344
|
-
agentId: string;
|
|
345
|
-
tagline?: string;
|
|
346
|
-
longDescription?: string;
|
|
347
|
-
languages?: string[];
|
|
348
|
-
responseTime?: string;
|
|
349
|
-
website?: string;
|
|
350
|
-
twitter?: string;
|
|
351
|
-
github?: string;
|
|
352
|
-
updatedAt: number;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
export interface Gig {
|
|
356
|
-
id: string;
|
|
357
|
-
agentId: string;
|
|
358
|
-
title: string;
|
|
359
|
-
description: string;
|
|
360
|
-
priceWei: string;
|
|
361
|
-
deliveryTime: string;
|
|
362
|
-
category: string;
|
|
363
|
-
active: boolean;
|
|
364
|
-
createdAt: number;
|
|
365
|
-
updatedAt: number;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
export async function getProfile(agentId: string): Promise<AgentProfile | null> {
|
|
369
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/profile`);
|
|
370
|
-
if (!response.ok) return null;
|
|
371
|
-
const data = (await response.json()) as { profile: AgentProfile };
|
|
372
|
-
return data.profile;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export async function updateProfile(
|
|
376
|
-
agentId: string,
|
|
377
|
-
updates: Record<string, string | undefined>,
|
|
378
|
-
signature: string,
|
|
379
|
-
timestamp: number,
|
|
380
|
-
nonce: string,
|
|
381
|
-
): Promise<AgentProfile> {
|
|
382
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/profile`, {
|
|
383
|
-
method: "PUT",
|
|
384
|
-
headers: { "Content-Type": "application/json" },
|
|
385
|
-
body: JSON.stringify({ ...updates, signature, timestamp, nonce }),
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
if (!response.ok) {
|
|
389
|
-
const error = (await response.json()) as ErrorResponse;
|
|
390
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
const data = (await response.json()) as { profile: AgentProfile };
|
|
394
|
-
return data.profile;
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
export async function listGigs(agentId: string): Promise<Gig[]> {
|
|
398
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/gigs`);
|
|
399
|
-
if (!response.ok) return [];
|
|
400
|
-
const data = (await response.json()) as { gigs: Gig[] };
|
|
401
|
-
return data.gigs;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export async function createGigRequest(
|
|
405
|
-
agentId: string,
|
|
406
|
-
gig: { title: string; description: string; priceWei: string; deliveryTime: string; category: string },
|
|
407
|
-
signature: string,
|
|
408
|
-
timestamp: number,
|
|
409
|
-
nonce: string,
|
|
410
|
-
): Promise<Gig> {
|
|
411
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/gigs`, {
|
|
412
|
-
method: "POST",
|
|
413
|
-
headers: { "Content-Type": "application/json" },
|
|
414
|
-
body: JSON.stringify({ action: "create", ...gig, signature, timestamp, nonce }),
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
if (!response.ok) {
|
|
418
|
-
const error = (await response.json()) as ErrorResponse;
|
|
419
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const data = (await response.json()) as { gig: Gig };
|
|
423
|
-
return data.gig;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
export async function updateGigRequest(
|
|
427
|
-
agentId: string,
|
|
428
|
-
gigId: string,
|
|
429
|
-
updates: Partial<{ title: string; description: string; priceWei: string; deliveryTime: string; category: string }>,
|
|
430
|
-
signature: string,
|
|
431
|
-
timestamp: number,
|
|
432
|
-
nonce: string,
|
|
433
|
-
): Promise<Gig> {
|
|
434
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/gigs`, {
|
|
435
|
-
method: "POST",
|
|
436
|
-
headers: { "Content-Type": "application/json" },
|
|
437
|
-
body: JSON.stringify({ action: "update", gigId, ...updates, signature, timestamp, nonce }),
|
|
438
|
-
});
|
|
439
|
-
|
|
440
|
-
if (!response.ok) {
|
|
441
|
-
const error = (await response.json()) as ErrorResponse;
|
|
442
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
const data = (await response.json()) as { gig: Gig };
|
|
446
|
-
return data.gig;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
export async function removeGigRequest(
|
|
450
|
-
agentId: string,
|
|
451
|
-
gigId: string,
|
|
452
|
-
signature: string,
|
|
453
|
-
timestamp: number,
|
|
454
|
-
nonce: string,
|
|
455
|
-
): Promise<void> {
|
|
456
|
-
const response = await fetch(`${API_BASE}/api/agents/${agentId}/gigs`, {
|
|
457
|
-
method: "POST",
|
|
458
|
-
headers: { "Content-Type": "application/json" },
|
|
459
|
-
body: JSON.stringify({ action: "remove", gigId, signature, timestamp, nonce }),
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
if (!response.ok) {
|
|
463
|
-
const error = (await response.json()) as ErrorResponse;
|
|
464
|
-
throw new Error(error.error || `HTTP ${response.status}`);
|
|
465
|
-
}
|
|
466
|
-
}
|
package/src/lib/types.ts
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// MANDATE Types
|
|
2
|
-
|
|
3
|
-
export interface Agent {
|
|
4
|
-
// ERC-8004 Identity
|
|
5
|
-
agentId: bigint;
|
|
6
|
-
owner: `0x${string}`;
|
|
7
|
-
agentURI: string;
|
|
8
|
-
agentWallet: `0x${string}`;
|
|
9
|
-
|
|
10
|
-
// Metadata (from registry)
|
|
11
|
-
name: string;
|
|
12
|
-
description: string;
|
|
13
|
-
skills: string[];
|
|
14
|
-
endpoint: string; // x402 hire endpoint
|
|
15
|
-
priceWei: bigint;
|
|
16
|
-
|
|
17
|
-
// Linked Flaunch token
|
|
18
|
-
flaunchToken?: `0x${string}`;
|
|
19
|
-
|
|
20
|
-
// Reputation (from ERC-8004 Reputation Registry)
|
|
21
|
-
reputation?: ReputationSummary;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface ReputationSummary {
|
|
25
|
-
count: bigint; // Number of feedback entries
|
|
26
|
-
summaryValue: bigint; // Aggregated score (scaled by decimals)
|
|
27
|
-
summaryValueDecimals: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface Feedback {
|
|
31
|
-
agentId: bigint;
|
|
32
|
-
clientAddress: `0x${string}`;
|
|
33
|
-
feedbackIndex: bigint;
|
|
34
|
-
value: bigint; // Score (e.g., 0-100)
|
|
35
|
-
valueDecimals: number;
|
|
36
|
-
tag1: string; // Category (e.g., "code")
|
|
37
|
-
tag2: string; // Subcategory (e.g., "review")
|
|
38
|
-
isRevoked: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface HireRequest {
|
|
42
|
-
agentId: bigint;
|
|
43
|
-
task: string; // Task description or IPFS hash
|
|
44
|
-
budget: bigint; // Payment in wei
|
|
45
|
-
deadline?: number; // Unix timestamp
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface HireResult {
|
|
49
|
-
success: boolean;
|
|
50
|
-
result?: string; // Result or IPFS hash
|
|
51
|
-
subcontracts?: SubcontractRecord[];
|
|
52
|
-
error?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface SubcontractRecord {
|
|
56
|
-
agentId: bigint;
|
|
57
|
-
payment: bigint;
|
|
58
|
-
task: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface AgentRegistration {
|
|
62
|
-
// Required for ERC-8004
|
|
63
|
-
name: string;
|
|
64
|
-
description: string;
|
|
65
|
-
image?: string; // IPFS hash or URL
|
|
66
|
-
|
|
67
|
-
// MANDATE-specific
|
|
68
|
-
skills: string[];
|
|
69
|
-
endpoint: string; // x402 endpoint
|
|
70
|
-
priceWei: bigint;
|
|
71
|
-
|
|
72
|
-
// Optional Flaunch token launch
|
|
73
|
-
launchToken?: {
|
|
74
|
-
symbol: string;
|
|
75
|
-
website?: string;
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export interface TaskFile {
|
|
80
|
-
key: string;
|
|
81
|
-
name: string;
|
|
82
|
-
size: number;
|
|
83
|
-
uploadedAt: number;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface TaskMessage {
|
|
87
|
-
sender: string;
|
|
88
|
-
role: "client" | "agent";
|
|
89
|
-
content: string;
|
|
90
|
-
timestamp: number;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export interface Wallet {
|
|
94
|
-
address: `0x${string}`;
|
|
95
|
-
privateKey: `0x${string}`;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// x402 Payment types
|
|
99
|
-
export interface X402PaymentHeader {
|
|
100
|
-
scheme: "exact";
|
|
101
|
-
network: "base";
|
|
102
|
-
token: `0x${string}`; // Usually WETH or USDC
|
|
103
|
-
amount: string; // In wei
|
|
104
|
-
recipient: `0x${string}`;
|
|
105
|
-
maxTimeoutSeconds?: number;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface X402Receipt {
|
|
109
|
-
txHash: `0x${string}`;
|
|
110
|
-
amount: bigint;
|
|
111
|
-
timestamp: number;
|
|
112
|
-
}
|
package/src/lib/wallet.ts
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
2
|
-
import { formatEther } from "viem";
|
|
3
|
-
import { createPublicClient, createWalletClient, http } from "viem";
|
|
4
|
-
import { base } from "viem/chains";
|
|
5
|
-
import { readFile, writeFile, mkdir, chmod, access } from "node:fs/promises";
|
|
6
|
-
import { join } from "node:path";
|
|
7
|
-
import { homedir } from "node:os";
|
|
8
|
-
import type { Wallet } from "./types.js";
|
|
9
|
-
import { BASE_RPC_URL } from "./constants.js";
|
|
10
|
-
|
|
11
|
-
const WALLET_DIR = ".moltlaunch";
|
|
12
|
-
const WALLET_FILE = "wallet.json";
|
|
13
|
-
|
|
14
|
-
function getWalletDir(): string {
|
|
15
|
-
return join(homedir(), WALLET_DIR);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function getWalletPath(): string {
|
|
19
|
-
return join(getWalletDir(), WALLET_FILE);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async function fileExists(path: string): Promise<boolean> {
|
|
23
|
-
try {
|
|
24
|
-
await access(path);
|
|
25
|
-
return true;
|
|
26
|
-
} catch {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function walletExists(): Promise<boolean> {
|
|
32
|
-
return fileExists(getWalletPath());
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export async function loadWallet(): Promise<Wallet | null> {
|
|
36
|
-
const path = getWalletPath();
|
|
37
|
-
if (!(await fileExists(path))) return null;
|
|
38
|
-
|
|
39
|
-
const raw = await readFile(path, "utf-8");
|
|
40
|
-
const data = JSON.parse(raw);
|
|
41
|
-
return {
|
|
42
|
-
address: data.address as `0x${string}`,
|
|
43
|
-
privateKey: data.privateKey as `0x${string}`,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function createWallet(): Promise<Wallet> {
|
|
48
|
-
const privateKey = generatePrivateKey();
|
|
49
|
-
const account = privateKeyToAccount(privateKey);
|
|
50
|
-
|
|
51
|
-
const wallet: Wallet = {
|
|
52
|
-
address: account.address,
|
|
53
|
-
privateKey,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const dir = getWalletDir();
|
|
57
|
-
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
58
|
-
await chmod(dir, 0o700);
|
|
59
|
-
|
|
60
|
-
const path = getWalletPath();
|
|
61
|
-
const data = {
|
|
62
|
-
address: wallet.address,
|
|
63
|
-
privateKey: wallet.privateKey,
|
|
64
|
-
createdAt: new Date().toISOString(),
|
|
65
|
-
};
|
|
66
|
-
await writeFile(path, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
67
|
-
await chmod(path, 0o600);
|
|
68
|
-
|
|
69
|
-
return wallet;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export async function loadOrCreateWallet(): Promise<{
|
|
73
|
-
wallet: Wallet;
|
|
74
|
-
isNew: boolean;
|
|
75
|
-
}> {
|
|
76
|
-
const existing = await loadWallet();
|
|
77
|
-
if (existing) return { wallet: existing, isNew: false };
|
|
78
|
-
|
|
79
|
-
const wallet = await createWallet();
|
|
80
|
-
return { wallet, isNew: true };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function getWalletBalance(address: `0x${string}`): Promise<string> {
|
|
84
|
-
const client = createPublicClient({
|
|
85
|
-
chain: base,
|
|
86
|
-
transport: http(BASE_RPC_URL),
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
const balance = await client.getBalance({ address });
|
|
90
|
-
return formatEther(balance);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function getAccount(privateKey: `0x${string}`) {
|
|
94
|
-
return privateKeyToAccount(privateKey);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Send ETH payment from wallet to a recipient
|
|
99
|
-
*/
|
|
100
|
-
export async function sendPayment(
|
|
101
|
-
wallet: Wallet,
|
|
102
|
-
to: string,
|
|
103
|
-
amountWei: bigint,
|
|
104
|
-
): Promise<string> {
|
|
105
|
-
const account = privateKeyToAccount(wallet.privateKey);
|
|
106
|
-
|
|
107
|
-
const walletClient = createWalletClient({
|
|
108
|
-
account,
|
|
109
|
-
chain: base,
|
|
110
|
-
transport: http(BASE_RPC_URL),
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const hash = await walletClient.sendTransaction({
|
|
114
|
-
to: to as `0x${string}`,
|
|
115
|
-
value: amountWei,
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
return hash;
|
|
119
|
-
}
|