@clankxyz/agent 0.1.0 → 0.1.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/dist/index.js CHANGED
@@ -1,6 +1,10 @@
1
1
  // src/agent.ts
2
2
  import { ClankClient } from "@clankxyz/sdk";
3
3
  import { STATUS, VERIFICATION } from "@clankxyz/shared";
4
+ import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
5
+ import { SuiClient } from "@mysten/sui/client";
6
+ import { Transaction } from "@mysten/sui/transactions";
7
+ import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";
4
8
 
5
9
  // src/state.ts
6
10
  import { readFile, writeFile } from "fs/promises";
@@ -212,6 +216,9 @@ var ClankAgent = class {
212
216
  skillRegistry;
213
217
  running = false;
214
218
  heartbeatTimer;
219
+ // On-chain transaction capabilities
220
+ keypair;
221
+ suiClient;
215
222
  // Queue for tasks to create in requester mode
216
223
  taskCreationQueue = [];
217
224
  constructor(config) {
@@ -228,6 +235,17 @@ var ClankAgent = class {
228
235
  });
229
236
  this.skillRegistry = new SkillRegistry();
230
237
  this.skillRegistry.register(echoSkillHandler);
238
+ if (config.privateKey) {
239
+ try {
240
+ const { secretKey } = decodeSuiPrivateKey(config.privateKey);
241
+ this.keypair = Ed25519Keypair.fromSecretKey(secretKey);
242
+ const rpcUrl = config.rpcUrl || (config.network === "mainnet" ? "https://fullnode.mainnet.sui.io:443" : "https://fullnode.testnet.sui.io:443");
243
+ this.suiClient = new SuiClient({ url: rpcUrl });
244
+ console.log(` \u{1F511} On-chain signing enabled: ${this.keypair.toSuiAddress().slice(0, 15)}...`);
245
+ } catch (error) {
246
+ console.error(` \u26A0\uFE0F Failed to load private key: ${error}`);
247
+ }
248
+ }
231
249
  }
232
250
  /**
233
251
  * Register a custom skill handler
@@ -332,13 +350,21 @@ var ClankAgent = class {
332
350
  }
333
351
  console.log(` \u{1F4CB} Polling for tasks...`);
334
352
  try {
335
- const result = await this.client.api.listTasks({
336
- status: STATUS.POSTED,
337
- skillId: skillIds[0],
338
- // API only supports one skill filter currently
339
- limit: 10
353
+ let allTasks = [];
354
+ for (const skillId of skillIds) {
355
+ const result = await this.client.api.listTasks({
356
+ status: STATUS.POSTED,
357
+ skillId,
358
+ limit: 10
359
+ });
360
+ allTasks = [...allTasks, ...result.data];
361
+ }
362
+ const seen = /* @__PURE__ */ new Set();
363
+ const tasks = allTasks.filter((t) => {
364
+ if (seen.has(t.id)) return false;
365
+ seen.add(t.id);
366
+ return true;
340
367
  });
341
- const tasks = result.data;
342
368
  console.log(` \u{1F4CB} Found ${tasks.length} available tasks`);
343
369
  for (const task of tasks) {
344
370
  if (!this.running) break;
@@ -459,13 +485,52 @@ var ClankAgent = class {
459
485
  console.log(` Handler executed successfully`);
460
486
  const storedOutput = await this.client.walrus.storeJson(result.output);
461
487
  console.log(` Output stored: ${storedOutput.blobId.slice(0, 20)}...`);
462
- console.log(` \u2705 Task completed: ${task.taskId.slice(0, 16)}`);
488
+ if (this.keypair && this.suiClient && this.config.packageId) {
489
+ try {
490
+ console.log(` Submitting on-chain...`);
491
+ await this.submitTaskOnChain(task.taskId, storedOutput.blobId);
492
+ console.log(` \u2705 Task submitted on-chain: ${task.taskId.slice(0, 16)}`);
493
+ } catch (error) {
494
+ console.error(` \u274C On-chain submission failed: ${error}`);
495
+ }
496
+ } else {
497
+ console.log(` \u2705 Task completed (no on-chain key): ${task.taskId.slice(0, 16)}`);
498
+ }
463
499
  markTaskCompleted(this.state, task.taskId, task.paymentAmountMist);
464
500
  } catch (error) {
465
501
  console.error(` \u274C Execution error: ${error}`);
466
502
  markTaskFailed(this.state, task.taskId);
467
503
  }
468
504
  }
505
+ /**
506
+ * Submit task output on-chain
507
+ */
508
+ async submitTaskOnChain(taskId, outputRef) {
509
+ if (!this.keypair || !this.suiClient || !this.config.packageId) {
510
+ throw new Error("On-chain signing not configured");
511
+ }
512
+ const tx = new Transaction();
513
+ tx.setGasBudget(1e7);
514
+ tx.moveCall({
515
+ target: `${this.config.packageId}::task::submit`,
516
+ arguments: [
517
+ tx.object(taskId),
518
+ tx.object(this.config.agentId),
519
+ tx.pure.string(outputRef),
520
+ tx.object("0x6")
521
+ // Clock
522
+ ]
523
+ });
524
+ const result = await this.suiClient.signAndExecuteTransaction({
525
+ transaction: tx,
526
+ signer: this.keypair,
527
+ options: { showEffects: true }
528
+ });
529
+ if (result.effects?.status?.status !== "success") {
530
+ throw new Error(`Transaction failed: ${result.effects?.status?.error || "unknown"}`);
531
+ }
532
+ console.log(` Tx: ${result.digest.slice(0, 15)}...`);
533
+ }
469
534
  /**
470
535
  * Refresh skills list from API
471
536
  */
@@ -741,17 +806,17 @@ var ClankAgent = class {
741
806
  // src/config.ts
742
807
  import "dotenv/config";
743
808
  function loadConfig() {
744
- const apiUrl = process.env.TASKNET_API_URL;
745
- const apiKey = process.env.TASKNET_API_KEY;
746
- const agentId = process.env.TASKNET_AGENT_ID;
809
+ const apiUrl = process.env.CLANK_API_URL;
810
+ const apiKey = process.env.CLANK_API_KEY;
811
+ const agentId = process.env.CLANK_AGENT_ID;
747
812
  if (!apiUrl) {
748
- throw new Error("TASKNET_API_URL is required");
813
+ throw new Error("CLANK_API_URL is required");
749
814
  }
750
815
  if (!apiKey) {
751
- throw new Error("TASKNET_API_KEY is required");
816
+ throw new Error("CLANK_API_KEY is required");
752
817
  }
753
818
  if (!agentId) {
754
- throw new Error("TASKNET_AGENT_ID is required");
819
+ throw new Error("CLANK_AGENT_ID is required");
755
820
  }
756
821
  return {
757
822
  // API configuration
@@ -761,9 +826,10 @@ function loadConfig() {
761
826
  // Agent mode
762
827
  mode: process.env.AGENT_MODE ?? "worker",
763
828
  // Network configuration
764
- network: process.env.TASKNET_NETWORK ?? "testnet",
829
+ network: process.env.CLANK_NETWORK ?? "testnet",
765
830
  rpcUrl: process.env.SUI_RPC_URL,
766
- packageId: process.env.TASKNET_PACKAGE_ID,
831
+ packageId: process.env.CLANK_PACKAGE_ID,
832
+ privateKey: process.env.CLANK_PRIVATE_KEY,
767
833
  // Walrus configuration
768
834
  walrusAggregator: process.env.WALRUS_AGGREGATOR_URL,
769
835
  walrusPublisher: process.env.WALRUS_PUBLISHER_URL,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/agent.ts","../src/state.ts","../src/skills/types.ts","../src/skills/echo.ts","../src/config.ts"],"sourcesContent":["import { ClankClient } from \"@clankxyz/sdk\";\nimport { STATUS, VERIFICATION } from \"@clankxyz/shared\";\nimport type { AgentConfig } from \"./config.js\";\nimport type { AgentState, ActiveTask, PendingTask } from \"./state.js\";\nimport {\n loadState,\n saveState,\n addActiveTask,\n removeActiveTask,\n markTaskCompleted,\n markTaskFailed,\n addPendingTask,\n updatePendingTask,\n markPendingSettled,\n markPendingExpired,\n} from \"./state.js\";\nimport { SkillRegistry, echoSkillHandler } from \"./skills/index.js\";\n\n/**\n * Task creation request for requester mode\n */\nexport interface CreateTaskRequest {\n skillId: string;\n input: object;\n paymentAmountMist: bigint;\n expiresInMs?: number;\n expectedOutputHash?: string;\n}\n\n/**\n * Clank Reference Agent\n *\n * A reference implementation of an autonomous agent that:\n * - Worker Mode: Polls for tasks, accepts, executes, and submits\n * - Requester Mode: Creates tasks, monitors progress, confirms/rejects\n * - Hybrid Mode: Both worker and requester capabilities\n * - Persists state for crash recovery\n */\nexport class ClankAgent {\n private client: ClankClient;\n private config: AgentConfig;\n private state!: AgentState;\n private skillRegistry: SkillRegistry;\n private running = false;\n private heartbeatTimer?: ReturnType<typeof setInterval>;\n\n // Queue for tasks to create in requester mode\n private taskCreationQueue: CreateTaskRequest[] = [];\n\n constructor(config: AgentConfig) {\n this.config = config;\n\n // Initialize SDK client\n this.client = new ClankClient({\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n network: config.network,\n rpcUrl: config.rpcUrl,\n packageId: config.packageId,\n walrusAggregator: config.walrusAggregator,\n walrusPublisher: config.walrusPublisher,\n agentId: config.agentId,\n });\n\n // Initialize skill registry\n this.skillRegistry = new SkillRegistry();\n\n // Register default handlers\n this.skillRegistry.register(echoSkillHandler);\n }\n\n /**\n * Register a custom skill handler\n */\n registerSkillHandler(handler: typeof echoSkillHandler): void {\n this.skillRegistry.register(handler);\n }\n\n /**\n * Start the agent\n */\n async start(): Promise<void> {\n console.log(`\\n🤖 Clank Agent starting...`);\n console.log(` Agent ID: ${this.config.agentId}`);\n console.log(` Mode: ${this.config.mode.toUpperCase()}`);\n console.log(` API URL: ${this.config.apiUrl}`);\n console.log(` Network: ${this.config.network}`);\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n console.log(` Skills: ${this.config.skillIds.length} configured`);\n console.log(` Max concurrent: ${this.config.maxConcurrentTasks}`);\n }\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n console.log(` Max pending: ${this.config.maxPendingTasks}`);\n console.log(` Auto-confirm deterministic: ${this.config.autoConfirmDeterministic}`);\n }\n console.log(` Heartbeat: ${this.config.heartbeatIntervalMs}ms\\n`);\n\n // Load persisted state\n this.state = await loadState(\n this.config.stateFilePath,\n this.config.agentId\n );\n\n // Refresh skills list from API (for worker/hybrid)\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n await this.refreshSkills();\n await this.recoverActiveTasks();\n }\n\n // Recover pending tasks (for requester/hybrid)\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n await this.recoverPendingTasks();\n }\n\n // Mark as running\n this.running = true;\n\n // Start heartbeat loop\n await this.heartbeat();\n\n this.heartbeatTimer = setInterval(\n () => this.heartbeat().catch(console.error),\n this.config.heartbeatIntervalMs\n );\n\n console.log(`\\n✅ Agent is now running`);\n console.log(` Press Ctrl+C to stop\\n`);\n }\n\n /**\n * Stop the agent gracefully\n */\n async stop(): Promise<void> {\n console.log(`\\n🛑 Stopping agent...`);\n this.running = false;\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n }\n\n // Save final state\n await saveState(this.config.stateFilePath, this.state);\n\n console.log(` State saved`);\n console.log(` Active tasks: ${this.state.activeTasks.length}`);\n console.log(`✅ Agent stopped\\n`);\n }\n\n /**\n * Main heartbeat loop\n */\n private async heartbeat(): Promise<void> {\n const now = Date.now();\n this.state.stats.lastHeartbeat = now;\n\n console.log(`\\n💓 Heartbeat at ${new Date().toISOString()}`);\n\n try {\n // Worker mode: poll and process tasks\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n console.log(` [WORKER] Active tasks: ${this.state.activeTasks.length}/${this.config.maxConcurrentTasks}`);\n await this.pollForTasks();\n await this.processActiveTasks();\n }\n\n // Requester mode: create and monitor tasks\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n console.log(` [REQUESTER] Pending tasks: ${this.state.pendingTasks.length}/${this.config.maxPendingTasks}`);\n await this.processTaskCreationQueue();\n await this.monitorPendingTasks();\n }\n\n // Save state\n await saveState(this.config.stateFilePath, this.state);\n } catch (error) {\n console.error(`❌ Heartbeat error: ${error}`);\n }\n }\n\n /**\n * Poll for available tasks\n */\n private async pollForTasks(): Promise<void> {\n // Check if we can accept more tasks\n if (this.state.activeTasks.length >= this.config.maxConcurrentTasks) {\n console.log(` 📋 At max capacity, skipping poll`);\n return;\n }\n\n // Get skills we can handle\n const skillIds = this.state.skills.map((s) => s.skillId);\n if (skillIds.length === 0) {\n console.log(` 📋 No skills registered, skipping poll`);\n return;\n }\n\n console.log(` 📋 Polling for tasks...`);\n\n try {\n // Poll for POSTED tasks for our skills\n const result = await this.client.api.listTasks({\n status: STATUS.POSTED,\n skillId: skillIds[0], // API only supports one skill filter currently\n limit: 10,\n });\n\n const tasks = result.data;\n console.log(` 📋 Found ${tasks.length} available tasks`);\n\n for (const task of tasks) {\n if (!this.running) break;\n if (this.state.activeTasks.length >= this.config.maxConcurrentTasks) break;\n\n // Check if we can handle this skill\n const skill = this.state.skills.find((s) => s.skillId === task.skill.id);\n if (!skill) continue;\n\n // Check if handler exists\n if (!this.skillRegistry.canHandle(skill.name, skill.version)) {\n console.log(` ⏭ No handler for ${skill.name}@${skill.version}`);\n continue;\n }\n\n // Check minimum payment\n if (BigInt(task.payment_amount_mist) < this.config.minPaymentThreshold) {\n console.log(` ⏭ Payment too low: ${task.payment_amount_mist}`);\n continue;\n }\n\n // Check deadline\n const expiresAt = new Date(task.expires_at).getTime();\n if (expiresAt - Date.now() < this.config.minExecutionTimeMs) {\n console.log(` ⏭ Not enough time: ${task.id}`);\n continue;\n }\n\n // Try to accept this task\n await this.acceptTask(task, skill);\n }\n } catch (error) {\n console.error(` ❌ Poll error: ${error}`);\n }\n }\n\n /**\n * Accept a task\n */\n private async acceptTask(\n task: { id: string; payment_amount_mist: string; worker_bond_amount: string; expires_at: string },\n skill: { skillId: string; name: string }\n ): Promise<void> {\n console.log(`\\n 🎯 Accepting task ${task.id.slice(0, 16)}...`);\n\n try {\n // Get full task details\n const fullTask = await this.client.api.getTask(task.id);\n\n // Add to active tasks (optimistic)\n const activeTask: ActiveTask = {\n taskId: task.id,\n skillId: skill.skillId,\n skillName: skill.name,\n status: STATUS.IN_PROGRESS,\n paymentAmountMist: task.payment_amount_mist,\n workerBondAmount: task.worker_bond_amount,\n inputPayloadRef: fullTask.input_payload_ref,\n expectedOutputHash: fullTask.expected_output_hash,\n acceptedAt: Date.now(),\n expiresAt: new Date(task.expires_at).getTime(),\n };\n\n addActiveTask(this.state, activeTask);\n console.log(` ✅ Task accepted: ${task.id.slice(0, 16)}`);\n\n // Note: In a full implementation, we would:\n // 1. Call reserve() on-chain\n // 2. Call accept() with bond\n // For now, we simulate with API-only flow\n\n } catch (error) {\n console.error(` ❌ Failed to accept task: ${error}`);\n }\n }\n\n /**\n * Process active tasks\n */\n private async processActiveTasks(): Promise<void> {\n const now = Date.now();\n\n for (const task of [...this.state.activeTasks]) {\n if (!this.running) break;\n\n try {\n // Check if expired\n if (task.expiresAt <= now) {\n console.log(` ⏰ Task expired: ${task.taskId.slice(0, 16)}`);\n markTaskFailed(this.state, task.taskId);\n continue;\n }\n\n // Check if still in progress\n if (task.status !== STATUS.IN_PROGRESS) {\n continue;\n }\n\n // Execute the skill\n await this.executeTask(task);\n } catch (error) {\n console.error(` ❌ Task processing error: ${error}`);\n }\n }\n }\n\n /**\n * Execute a task\n */\n private async executeTask(task: ActiveTask): Promise<void> {\n console.log(`\\n ⚙️ Executing task ${task.taskId.slice(0, 16)}...`);\n console.log(` Skill: ${task.skillName}`);\n\n try {\n // Find handler\n const handler = this.skillRegistry.findHandler(task.skillName, \"1.0.0\");\n if (!handler) {\n console.error(` ❌ No handler for ${task.skillName}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n // Fetch input from Walrus\n let input: object;\n try {\n input = await this.client.walrus.getJson(task.inputPayloadRef);\n console.log(` Input fetched from Walrus`);\n } catch (error) {\n console.error(` ❌ Failed to fetch input: ${error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n // Validate input\n if (handler.validateInput) {\n const validation = handler.validateInput(input);\n if (!validation.valid) {\n console.error(` ❌ Input validation failed: ${validation.error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n }\n\n // Execute handler\n const result = await handler.execute(input, {\n taskId: task.taskId,\n skillId: task.skillId,\n skillName: task.skillName,\n skillVersion: \"1.0.0\",\n paymentAmountMist: BigInt(task.paymentAmountMist),\n expiresAt: task.expiresAt,\n });\n\n if (!result.success || !result.output) {\n console.error(` ❌ Handler failed: ${result.error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n console.log(` Handler executed successfully`);\n\n // Store output in Walrus\n const storedOutput = await this.client.walrus.storeJson(result.output);\n console.log(` Output stored: ${storedOutput.blobId.slice(0, 20)}...`);\n\n // Submit output\n // Note: In full implementation, we would call submit() on-chain\n console.log(` ✅ Task completed: ${task.taskId.slice(0, 16)}`);\n\n // Mark as completed\n markTaskCompleted(this.state, task.taskId, task.paymentAmountMist);\n\n } catch (error) {\n console.error(` ❌ Execution error: ${error}`);\n markTaskFailed(this.state, task.taskId);\n }\n }\n\n /**\n * Refresh skills list from API\n */\n private async refreshSkills(): Promise<void> {\n console.log(` 📚 Refreshing skills...`);\n\n try {\n const agent = await this.client.api.getAgent(this.config.agentId);\n\n this.state.skills = agent.skills.map((s) => ({\n skillId: s.id,\n name: s.name,\n version: s.version,\n verificationType: s.verification_type,\n basePriceMist: s.base_price_mist,\n workerBondMist: \"0\", // Not in API response\n }));\n\n console.log(` 📚 Found ${this.state.skills.length} skills`);\n\n // Also use configured skill IDs\n for (const skillId of this.config.skillIds) {\n if (!this.state.skills.find((s) => s.skillId === skillId)) {\n // Try to fetch skill details\n try {\n const skill = await this.client.api.getSkill(skillId);\n this.state.skills.push({\n skillId: skill.id,\n name: skill.name,\n version: skill.version,\n verificationType: skill.verification_type,\n basePriceMist: skill.base_price_mist,\n workerBondMist: skill.worker_bond_mist,\n });\n } catch {\n console.warn(` ⚠ Could not fetch skill ${skillId}`);\n }\n }\n }\n } catch (error) {\n console.error(` ❌ Failed to refresh skills: ${error}`);\n }\n }\n\n /**\n * Recover active tasks after restart\n */\n private async recoverActiveTasks(): Promise<void> {\n if (this.state.activeTasks.length === 0) {\n return;\n }\n\n console.log(` 🔄 Recovering ${this.state.activeTasks.length} active tasks...`);\n\n const now = Date.now();\n const tasksToRemove: string[] = [];\n\n for (const task of this.state.activeTasks) {\n // Remove expired tasks\n if (task.expiresAt <= now) {\n console.log(` ⏰ Removing expired task: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n continue;\n }\n\n // Verify task is still valid\n try {\n const fullTask = await this.client.api.getTask(task.taskId);\n\n // Check if task is still in progress\n if (\n fullTask.status !== STATUS.IN_PROGRESS &&\n fullTask.status !== STATUS.ACCEPTED\n ) {\n console.log(` ❌ Task no longer active: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n }\n } catch {\n // Task may have been settled or cancelled\n console.log(` ❌ Task not found: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n }\n }\n\n // Remove invalid tasks\n for (const taskId of tasksToRemove) {\n removeActiveTask(this.state, taskId);\n }\n\n console.log(` 🔄 Recovery complete: ${this.state.activeTasks.length} active tasks`);\n }\n\n /**\n * Get current stats\n */\n getStats() {\n return {\n worker: {\n ...this.state.stats,\n activeTasks: this.state.activeTasks.length,\n registeredSkills: this.state.skills.length,\n },\n requester: {\n ...this.state.requesterStats,\n pendingTasks: this.state.pendingTasks.length,\n queuedTasks: this.taskCreationQueue.length,\n },\n };\n }\n\n /**\n * Get the SDK client\n */\n getClient(): ClankClient {\n return this.client;\n }\n\n // === Requester Mode Methods ===\n\n /**\n * Queue a task for creation (requester mode)\n */\n queueTask(request: CreateTaskRequest): void {\n if (this.config.mode === \"worker\") {\n throw new Error(\"Cannot create tasks in worker mode\");\n }\n\n if (this.state.pendingTasks.length >= this.config.maxPendingTasks) {\n throw new Error(\"Maximum pending tasks reached\");\n }\n\n this.taskCreationQueue.push(request);\n console.log(` 📤 Task queued for creation (skill: ${request.skillId})`);\n }\n\n /**\n * Process task creation queue\n */\n private async processTaskCreationQueue(): Promise<void> {\n while (this.taskCreationQueue.length > 0 && this.running) {\n if (this.state.pendingTasks.length >= this.config.maxPendingTasks) {\n console.log(` 📤 Max pending tasks reached, pausing creation`);\n break;\n }\n\n const request = this.taskCreationQueue.shift()!;\n await this.createTask(request);\n }\n }\n\n /**\n * Create a task on-chain (requester mode)\n */\n private async createTask(request: CreateTaskRequest): Promise<void> {\n console.log(`\\n 📝 Creating task for skill ${request.skillId.slice(0, 16)}...`);\n\n try {\n // Get skill details\n const skill = await this.client.api.getSkill(request.skillId);\n\n // Store input in Walrus\n const storedInput = await this.client.walrus.storeJson(request.input);\n console.log(` Input stored: ${storedInput.blobId.slice(0, 20)}...`);\n\n // Calculate expiry\n const expiresInMs = request.expiresInMs ?? this.config.taskTimeoutMs;\n const expiresAt = Date.now() + expiresInMs;\n\n // Create task via API\n // Note: In full implementation, this would be an on-chain transaction\n const now = Date.now();\n const taskId = `task_${now}_${Math.random().toString(36).slice(2, 10)}`;\n\n // Add to pending tasks\n const pendingTask: PendingTask = {\n taskId,\n skillId: request.skillId,\n skillName: skill.name,\n status: STATUS.POSTED,\n paymentAmountMist: request.paymentAmountMist.toString(),\n workerBondAmount: skill.worker_bond_mist,\n inputPayloadRef: storedInput.blobId,\n expectedOutputHash: request.expectedOutputHash,\n createdAt: now,\n expiresAt,\n };\n\n addPendingTask(this.state, pendingTask);\n console.log(` ✅ Task created: ${taskId.slice(0, 16)}`);\n\n } catch (error) {\n console.error(` ❌ Failed to create task: ${error}`);\n // Re-queue for retry? For now, just log\n }\n }\n\n /**\n * Monitor pending tasks and process submissions\n */\n private async monitorPendingTasks(): Promise<void> {\n const now = Date.now();\n\n for (const task of [...this.state.pendingTasks]) {\n if (!this.running) break;\n\n try {\n // Check if expired\n if (task.expiresAt <= now) {\n console.log(` ⏰ Task expired: ${task.taskId.slice(0, 16)}`);\n markPendingExpired(this.state, task.taskId);\n continue;\n }\n\n // Fetch current status from API\n // Note: In production, we'd use the on-chain task ID\n // For now, simulate status checks\n\n // Process based on status\n if (task.status === STATUS.SUBMITTED && task.outputPayloadRef) {\n await this.processSubmittedTask(task);\n }\n\n } catch (error) {\n console.error(` ❌ Error monitoring task ${task.taskId.slice(0, 16)}: ${error}`);\n }\n }\n }\n\n /**\n * Process a submitted task (verify output and confirm/reject)\n */\n private async processSubmittedTask(task: PendingTask): Promise<void> {\n console.log(`\\n 🔍 Processing submitted task ${task.taskId.slice(0, 16)}...`);\n\n if (!task.outputPayloadRef) {\n console.log(` ⚠ No output payload reference`);\n return;\n }\n\n try {\n // Fetch output from Walrus\n const output = await this.client.walrus.getJson(task.outputPayloadRef);\n console.log(` Output fetched from Walrus`);\n\n // Get skill to check verification type\n const skill = await this.client.api.getSkill(task.skillId);\n \n // Determine if we should auto-confirm\n let shouldConfirm = false;\n\n if (skill.verification_type === VERIFICATION.DETERMINISTIC) {\n // Deterministic: verify hash matches\n if (this.config.autoConfirmDeterministic) {\n if (task.expectedOutputHash) {\n // In production, compute hash and compare\n // For now, assume it matches\n console.log(` Deterministic verification passed`);\n shouldConfirm = true;\n } else {\n console.log(` No expected hash, auto-confirming deterministic task`);\n shouldConfirm = true;\n }\n }\n } else if (skill.verification_type === VERIFICATION.TIME_BOUND) {\n // Time-bound: auto-settle after deadline\n console.log(` Time-bound task, waiting for deadline`);\n } else {\n // RequesterConfirm: need manual confirmation\n console.log(` Awaiting manual confirmation for task`);\n // In a real agent, this would emit an event or call a callback\n }\n\n if (shouldConfirm) {\n await this.confirmTask(task);\n }\n\n } catch (error) {\n console.error(` ❌ Failed to process submitted task: ${error}`);\n }\n }\n\n /**\n * Confirm a submitted task (release payment to worker)\n */\n async confirmTask(task: PendingTask): Promise<void> {\n console.log(` ✅ Confirming task ${task.taskId.slice(0, 16)}...`);\n\n try {\n // Note: In full implementation, call confirm() on-chain\n // For now, simulate confirmation\n\n markPendingSettled(this.state, task.taskId, task.paymentAmountMist);\n console.log(` ✅ Task confirmed and settled`);\n\n } catch (error) {\n console.error(` ❌ Failed to confirm task: ${error}`);\n }\n }\n\n /**\n * Reject a submitted task (return payment, slash worker bond)\n */\n async rejectTask(task: PendingTask, reason: string): Promise<void> {\n console.log(` ❌ Rejecting task ${task.taskId.slice(0, 16)}...`);\n console.log(` Reason: ${reason}`);\n\n try {\n // Note: In full implementation, call reject() on-chain\n // For now, simulate rejection\n\n markPendingExpired(this.state, task.taskId);\n console.log(` ❌ Task rejected`);\n\n } catch (error) {\n console.error(` ❌ Failed to reject task: ${error}`);\n }\n }\n\n /**\n * Get pending task by ID\n */\n getPendingTask(taskId: string): PendingTask | undefined {\n return this.state.pendingTasks.find((t) => t.taskId === taskId);\n }\n\n /**\n * Get all pending tasks\n */\n getPendingTasks(): PendingTask[] {\n return [...this.state.pendingTasks];\n }\n\n /**\n * Recover pending tasks after restart\n */\n private async recoverPendingTasks(): Promise<void> {\n if (this.state.pendingTasks.length === 0) {\n return;\n }\n\n console.log(` 🔄 Recovering ${this.state.pendingTasks.length} pending tasks...`);\n\n const now = Date.now();\n const tasksToRemove: string[] = [];\n\n for (const task of this.state.pendingTasks) {\n // Remove expired tasks\n if (task.expiresAt <= now) {\n console.log(` ⏰ Removing expired pending task: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n this.state.requesterStats.tasksExpired++;\n continue;\n }\n\n // In production, verify task still exists on-chain\n }\n\n // Remove invalid tasks\n this.state.pendingTasks = this.state.pendingTasks.filter(\n (t) => !tasksToRemove.includes(t.taskId)\n );\n\n console.log(` 🔄 Recovery complete: ${this.state.pendingTasks.length} pending tasks`);\n }\n}\n","import { readFile, writeFile } from \"fs/promises\";\nimport { existsSync } from \"fs\";\n\n/**\n * Active task being processed by the agent\n */\nexport interface ActiveTask {\n taskId: string;\n skillId: string;\n skillName: string;\n status: number;\n paymentAmountMist: string;\n workerBondAmount: string;\n inputPayloadRef: string;\n expectedOutputHash?: string;\n acceptedAt: number;\n expiresAt: number;\n}\n\n/**\n * Registered skill that this agent can handle\n */\nexport interface RegisteredSkill {\n skillId: string;\n name: string;\n version: string;\n verificationType: number;\n basePriceMist: string;\n workerBondMist: string;\n}\n\n/**\n * Pending task created by the agent (requester mode)\n */\nexport interface PendingTask {\n taskId: string;\n skillId: string;\n skillName: string;\n status: number;\n paymentAmountMist: string;\n workerBondAmount: string;\n inputPayloadRef: string;\n expectedOutputHash?: string;\n createdAt: number;\n expiresAt: number;\n workerId?: string;\n outputPayloadRef?: string;\n submittedAt?: number;\n}\n\n/**\n * Agent state that is persisted to disk\n */\nexport interface AgentState {\n // Active tasks being processed (worker mode)\n activeTasks: ActiveTask[];\n\n // Pending tasks awaiting completion (requester mode)\n pendingTasks: PendingTask[];\n\n // Skills this agent is registered to handle\n skills: RegisteredSkill[];\n\n // Statistics (worker)\n stats: {\n tasksAccepted: number;\n tasksCompleted: number;\n tasksFailed: number;\n totalEarnedMist: string;\n lastHeartbeat: number;\n startedAt: number;\n };\n\n // Statistics (requester)\n requesterStats: {\n tasksCreated: number;\n tasksSettled: number;\n tasksExpired: number;\n totalSpentMist: string;\n };\n\n // Agent identity\n agentId: string;\n}\n\n/**\n * Create initial empty state\n */\nexport function createInitialState(agentId: string): AgentState {\n return {\n activeTasks: [],\n pendingTasks: [],\n skills: [],\n stats: {\n tasksAccepted: 0,\n tasksCompleted: 0,\n tasksFailed: 0,\n totalEarnedMist: \"0\",\n lastHeartbeat: 0,\n startedAt: Date.now(),\n },\n requesterStats: {\n tasksCreated: 0,\n tasksSettled: 0,\n tasksExpired: 0,\n totalSpentMist: \"0\",\n },\n agentId,\n };\n}\n\n/**\n * Load state from file\n */\nexport async function loadState(\n filePath: string,\n agentId: string\n): Promise<AgentState> {\n if (!existsSync(filePath)) {\n console.log(`📁 No state file found, creating new state`);\n return createInitialState(agentId);\n }\n\n try {\n const data = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(data) as AgentState;\n\n // Validate agent ID matches\n if (state.agentId !== agentId) {\n console.warn(`⚠ State file agent ID mismatch, creating new state`);\n return createInitialState(agentId);\n }\n\n console.log(`📁 Loaded state: ${state.activeTasks.length} active tasks`);\n return state;\n } catch (error) {\n console.warn(`⚠ Failed to load state file: ${error}`);\n return createInitialState(agentId);\n }\n}\n\n/**\n * Save state to file\n */\nexport async function saveState(\n filePath: string,\n state: AgentState\n): Promise<void> {\n try {\n await writeFile(filePath, JSON.stringify(state, null, 2));\n } catch (error) {\n console.error(`❌ Failed to save state: ${error}`);\n }\n}\n\n/**\n * Add active task to state\n */\nexport function addActiveTask(state: AgentState, task: ActiveTask): void {\n // Check if task already exists\n const existing = state.activeTasks.find((t) => t.taskId === task.taskId);\n if (!existing) {\n state.activeTasks.push(task);\n state.stats.tasksAccepted++;\n }\n}\n\n/**\n * Remove active task from state\n */\nexport function removeActiveTask(state: AgentState, taskId: string): void {\n state.activeTasks = state.activeTasks.filter((t) => t.taskId !== taskId);\n}\n\n/**\n * Update task in state\n */\nexport function updateActiveTask(\n state: AgentState,\n taskId: string,\n updates: Partial<ActiveTask>\n): void {\n const task = state.activeTasks.find((t) => t.taskId === taskId);\n if (task) {\n Object.assign(task, updates);\n }\n}\n\n/**\n * Mark task as completed\n */\nexport function markTaskCompleted(\n state: AgentState,\n taskId: string,\n earnedMist: string\n): void {\n removeActiveTask(state, taskId);\n state.stats.tasksCompleted++;\n state.stats.totalEarnedMist = (\n BigInt(state.stats.totalEarnedMist) + BigInt(earnedMist)\n ).toString();\n}\n\n/**\n * Mark task as failed\n */\nexport function markTaskFailed(state: AgentState, taskId: string): void {\n removeActiveTask(state, taskId);\n state.stats.tasksFailed++;\n}\n\n// === Requester Mode State Functions ===\n\n/**\n * Add pending task to state (requester mode)\n */\nexport function addPendingTask(state: AgentState, task: PendingTask): void {\n const existing = state.pendingTasks.find((t) => t.taskId === task.taskId);\n if (!existing) {\n state.pendingTasks.push(task);\n state.requesterStats.tasksCreated++;\n }\n}\n\n/**\n * Remove pending task from state\n */\nexport function removePendingTask(state: AgentState, taskId: string): void {\n state.pendingTasks = state.pendingTasks.filter((t) => t.taskId !== taskId);\n}\n\n/**\n * Update pending task in state\n */\nexport function updatePendingTask(\n state: AgentState,\n taskId: string,\n updates: Partial<PendingTask>\n): void {\n const task = state.pendingTasks.find((t) => t.taskId === taskId);\n if (task) {\n Object.assign(task, updates);\n }\n}\n\n/**\n * Mark pending task as settled\n */\nexport function markPendingSettled(\n state: AgentState,\n taskId: string,\n spentMist: string\n): void {\n removePendingTask(state, taskId);\n state.requesterStats.tasksSettled++;\n state.requesterStats.totalSpentMist = (\n BigInt(state.requesterStats.totalSpentMist) + BigInt(spentMist)\n ).toString();\n}\n\n/**\n * Mark pending task as expired\n */\nexport function markPendingExpired(state: AgentState, taskId: string): void {\n removePendingTask(state, taskId);\n state.requesterStats.tasksExpired++;\n}\n","/**\n * Result of skill execution\n */\nexport interface SkillResult {\n success: boolean;\n output?: object;\n error?: string;\n}\n\n/**\n * Skill handler interface - implement this for each skill\n */\nexport interface SkillHandler {\n /** Handler name */\n name: string;\n\n /** Handler version */\n version: string;\n\n /**\n * Check if this handler can process the given skill\n */\n canHandle(skillName: string, skillVersion: string): boolean;\n\n /**\n * Execute the skill with the given input\n */\n execute(input: object, context?: SkillContext): Promise<SkillResult>;\n\n /**\n * Validate the input before processing\n */\n validateInput?(input: object): { valid: boolean; error?: string };\n\n /**\n * Estimate execution time in milliseconds\n */\n estimateExecutionTime?(input: object): number;\n}\n\n/**\n * Context provided to skill handlers\n */\nexport interface SkillContext {\n taskId: string;\n skillId: string;\n skillName: string;\n skillVersion: string;\n paymentAmountMist: bigint;\n expiresAt: number;\n}\n\n/**\n * Skill registry for managing available handlers\n */\nexport class SkillRegistry {\n private handlers: SkillHandler[] = [];\n\n /**\n * Register a skill handler\n */\n register(handler: SkillHandler): void {\n // Check for duplicates\n const existing = this.handlers.find(\n (h) => h.name === handler.name && h.version === handler.version\n );\n if (existing) {\n console.warn(`⚠ Handler ${handler.name}@${handler.version} already registered`);\n return;\n }\n\n this.handlers.push(handler);\n console.log(`📦 Registered handler: ${handler.name}@${handler.version}`);\n }\n\n /**\n * Find a handler for the given skill\n */\n findHandler(skillName: string, skillVersion: string): SkillHandler | undefined {\n return this.handlers.find((h) => h.canHandle(skillName, skillVersion));\n }\n\n /**\n * Get all registered handlers\n */\n getHandlers(): SkillHandler[] {\n return [...this.handlers];\n }\n\n /**\n * Check if any handler can process the skill\n */\n canHandle(skillName: string, skillVersion: string): boolean {\n return this.findHandler(skillName, skillVersion) !== undefined;\n }\n}\n","import type { SkillHandler, SkillResult } from \"./types.js\";\n\n/**\n * Echo skill handler - simply echoes back the input with metadata\n *\n * This is a reference implementation for testing the task flow.\n */\nexport const echoSkillHandler: SkillHandler = {\n name: \"echo\",\n version: \"1.0.0\",\n\n /**\n * Check if this handler can process the given skill\n */\n canHandle(skillName: string, skillVersion: string): boolean {\n return (\n skillName.toLowerCase().includes(\"echo\") ||\n skillName.toLowerCase().includes(\"test\")\n );\n },\n\n /**\n * Process the input and return the output\n */\n async execute(input: object): Promise<SkillResult> {\n const now = Date.now();\n\n // Simulate some processing time (100-500ms)\n await new Promise((resolve) =>\n setTimeout(resolve, 100 + Math.random() * 400)\n );\n\n // Return the echoed input with metadata\n const output = {\n echo: input,\n metadata: {\n processedAt: now,\n processingTimeMs: Date.now() - now,\n handler: \"echo-skill-v1\",\n version: \"1.0.0\",\n },\n };\n\n return {\n success: true,\n output,\n };\n },\n\n /**\n * Validate the input before processing\n */\n validateInput(input: object): { valid: boolean; error?: string } {\n // Echo skill accepts any input\n if (input === null || input === undefined) {\n return { valid: false, error: \"Input cannot be null or undefined\" };\n }\n return { valid: true };\n },\n};\n\n/**\n * Echo skill JSON schema\n */\nexport const echoInputSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n description: \"Echo skill input - any JSON object\",\n additionalProperties: true,\n};\n\nexport const echoOutputSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n properties: {\n echo: {\n description: \"The echoed input\",\n },\n metadata: {\n type: \"object\",\n properties: {\n processedAt: { type: \"number\" },\n processingTimeMs: { type: \"number\" },\n handler: { type: \"string\" },\n version: { type: \"string\" },\n },\n required: [\"processedAt\", \"processingTimeMs\", \"handler\", \"version\"],\n },\n },\n required: [\"echo\", \"metadata\"],\n};\n","import \"dotenv/config\";\nimport type { Network } from \"@clankxyz/shared\";\n\n/**\n * Agent mode: worker executes tasks, requester creates and monitors tasks\n */\nexport type AgentMode = \"worker\" | \"requester\" | \"hybrid\";\n\n/**\n * Agent configuration loaded from environment variables\n */\nexport interface AgentConfig {\n // API configuration\n apiUrl: string;\n apiKey: string;\n\n // Agent identity\n agentId: string;\n\n // Agent mode\n mode: AgentMode;\n\n // Network configuration\n network: Network;\n rpcUrl?: string;\n packageId?: string;\n\n // Walrus configuration\n walrusAggregator?: string;\n walrusPublisher?: string;\n\n // Worker behavior\n maxConcurrentTasks: number;\n minPaymentThreshold: bigint;\n minExecutionTimeMs: number;\n heartbeatIntervalMs: number;\n pollIntervalMs: number;\n\n // Requester behavior\n maxPendingTasks: number;\n autoConfirmDeterministic: boolean;\n taskTimeoutMs: number;\n\n // Skills this agent can handle (worker mode)\n skillIds: string[];\n\n // State persistence\n stateFilePath: string;\n\n // Webhook server (optional)\n webhookPort?: number;\n webhookSecret?: string;\n}\n\n/**\n * Load configuration from environment variables\n */\nexport function loadConfig(): AgentConfig {\n const apiUrl = process.env.TASKNET_API_URL;\n const apiKey = process.env.TASKNET_API_KEY;\n const agentId = process.env.TASKNET_AGENT_ID;\n\n if (!apiUrl) {\n throw new Error(\"TASKNET_API_URL is required\");\n }\n if (!apiKey) {\n throw new Error(\"TASKNET_API_KEY is required\");\n }\n if (!agentId) {\n throw new Error(\"TASKNET_AGENT_ID is required\");\n }\n\n return {\n // API configuration\n apiUrl,\n apiKey,\n agentId,\n\n // Agent mode\n mode: (process.env.AGENT_MODE as AgentMode) ?? \"worker\",\n\n // Network configuration\n network: (process.env.TASKNET_NETWORK as Network) ?? \"testnet\",\n rpcUrl: process.env.SUI_RPC_URL,\n packageId: process.env.TASKNET_PACKAGE_ID,\n\n // Walrus configuration\n walrusAggregator: process.env.WALRUS_AGGREGATOR_URL,\n walrusPublisher: process.env.WALRUS_PUBLISHER_URL,\n\n // Worker behavior\n maxConcurrentTasks: parseInt(process.env.MAX_CONCURRENT_TASKS ?? \"5\", 10),\n minPaymentThreshold: BigInt(process.env.MIN_PAYMENT_THRESHOLD ?? \"10000000\"), // $10\n minExecutionTimeMs: parseInt(process.env.MIN_EXECUTION_TIME_MS ?? \"1800000\", 10), // 30 min\n heartbeatIntervalMs: parseInt(process.env.HEARTBEAT_INTERVAL_MS ?? \"60000\", 10), // 1 min\n pollIntervalMs: parseInt(process.env.POLL_INTERVAL_MS ?? \"30000\", 10), // 30 sec\n\n // Requester behavior\n maxPendingTasks: parseInt(process.env.MAX_PENDING_TASKS ?? \"20\", 10),\n autoConfirmDeterministic: process.env.AUTO_CONFIRM_DETERMINISTIC !== \"false\",\n taskTimeoutMs: parseInt(process.env.TASK_TIMEOUT_MS ?? \"3600000\", 10), // 1 hour\n\n // Skills\n skillIds: process.env.SKILL_IDS?.split(\",\").filter(Boolean) ?? [],\n\n // State persistence\n stateFilePath: process.env.STATE_FILE_PATH ?? \"./.agent-state.json\",\n\n // Webhook server\n webhookPort: process.env.WEBHOOK_PORT\n ? parseInt(process.env.WEBHOOK_PORT, 10)\n : undefined,\n webhookSecret: process.env.WEBHOOK_SECRET,\n };\n}\n\n/**\n * Validate configuration\n */\nexport function validateConfig(config: AgentConfig): void {\n if (config.mode === \"worker\" || config.mode === \"hybrid\") {\n if (config.skillIds.length === 0) {\n console.warn(\"⚠ No skill IDs configured. Agent will not accept any tasks.\");\n }\n\n if (config.maxConcurrentTasks < 1) {\n throw new Error(\"maxConcurrentTasks must be at least 1\");\n }\n }\n\n if (config.mode === \"requester\" || config.mode === \"hybrid\") {\n if (config.maxPendingTasks < 1) {\n throw new Error(\"maxPendingTasks must be at least 1\");\n }\n }\n\n if (config.heartbeatIntervalMs < 10000) {\n console.warn(\"⚠ Heartbeat interval < 10s may cause rate limiting\");\n }\n\n if (![\"worker\", \"requester\", \"hybrid\"].includes(config.mode)) {\n throw new Error(`Invalid AGENT_MODE: ${config.mode}. Must be worker, requester, or hybrid`);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/agent.ts","../src/state.ts","../src/skills/types.ts","../src/skills/echo.ts","../src/config.ts"],"sourcesContent":["import { ClankClient } from \"@clankxyz/sdk\";\nimport { STATUS, VERIFICATION } from \"@clankxyz/shared\";\nimport { Ed25519Keypair } from \"@mysten/sui/keypairs/ed25519\";\nimport { SuiClient } from \"@mysten/sui/client\";\nimport { Transaction } from \"@mysten/sui/transactions\";\nimport { decodeSuiPrivateKey } from \"@mysten/sui/cryptography\";\nimport type { AgentConfig } from \"./config.js\";\nimport type { AgentState, ActiveTask, PendingTask } from \"./state.js\";\nimport {\n loadState,\n saveState,\n addActiveTask,\n removeActiveTask,\n markTaskCompleted,\n markTaskFailed,\n addPendingTask,\n updatePendingTask,\n markPendingSettled,\n markPendingExpired,\n} from \"./state.js\";\nimport { SkillRegistry, echoSkillHandler } from \"./skills/index.js\";\n\n/**\n * Task creation request for requester mode\n */\nexport interface CreateTaskRequest {\n skillId: string;\n input: object;\n paymentAmountMist: bigint;\n expiresInMs?: number;\n expectedOutputHash?: string;\n}\n\n/**\n * Clank Reference Agent\n *\n * A reference implementation of an autonomous agent that:\n * - Worker Mode: Polls for tasks, accepts, executes, and submits\n * - Requester Mode: Creates tasks, monitors progress, confirms/rejects\n * - Hybrid Mode: Both worker and requester capabilities\n * - Persists state for crash recovery\n */\nexport class ClankAgent {\n private client: ClankClient;\n private config: AgentConfig;\n private state!: AgentState;\n private skillRegistry: SkillRegistry;\n private running = false;\n private heartbeatTimer?: ReturnType<typeof setInterval>;\n \n // On-chain transaction capabilities\n private keypair?: Ed25519Keypair;\n private suiClient?: SuiClient;\n\n // Queue for tasks to create in requester mode\n private taskCreationQueue: CreateTaskRequest[] = [];\n\n constructor(config: AgentConfig) {\n this.config = config;\n\n // Initialize SDK client\n this.client = new ClankClient({\n apiUrl: config.apiUrl,\n apiKey: config.apiKey,\n network: config.network,\n rpcUrl: config.rpcUrl,\n packageId: config.packageId,\n walrusAggregator: config.walrusAggregator,\n walrusPublisher: config.walrusPublisher,\n agentId: config.agentId,\n });\n\n // Initialize skill registry\n this.skillRegistry = new SkillRegistry();\n\n // Register default handlers\n this.skillRegistry.register(echoSkillHandler);\n \n // Initialize on-chain transaction capabilities if private key provided\n if (config.privateKey) {\n try {\n const { secretKey } = decodeSuiPrivateKey(config.privateKey);\n this.keypair = Ed25519Keypair.fromSecretKey(secretKey);\n \n const rpcUrl = config.rpcUrl || (config.network === \"mainnet\" \n ? \"https://fullnode.mainnet.sui.io:443\"\n : \"https://fullnode.testnet.sui.io:443\");\n this.suiClient = new SuiClient({ url: rpcUrl });\n \n console.log(` 🔑 On-chain signing enabled: ${this.keypair.toSuiAddress().slice(0, 15)}...`);\n } catch (error) {\n console.error(` ⚠️ Failed to load private key: ${error}`);\n }\n }\n }\n\n /**\n * Register a custom skill handler\n */\n registerSkillHandler(handler: typeof echoSkillHandler): void {\n this.skillRegistry.register(handler);\n }\n\n /**\n * Start the agent\n */\n async start(): Promise<void> {\n console.log(`\\n🤖 Clank Agent starting...`);\n console.log(` Agent ID: ${this.config.agentId}`);\n console.log(` Mode: ${this.config.mode.toUpperCase()}`);\n console.log(` API URL: ${this.config.apiUrl}`);\n console.log(` Network: ${this.config.network}`);\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n console.log(` Skills: ${this.config.skillIds.length} configured`);\n console.log(` Max concurrent: ${this.config.maxConcurrentTasks}`);\n }\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n console.log(` Max pending: ${this.config.maxPendingTasks}`);\n console.log(` Auto-confirm deterministic: ${this.config.autoConfirmDeterministic}`);\n }\n console.log(` Heartbeat: ${this.config.heartbeatIntervalMs}ms\\n`);\n\n // Load persisted state\n this.state = await loadState(\n this.config.stateFilePath,\n this.config.agentId\n );\n\n // Refresh skills list from API (for worker/hybrid)\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n await this.refreshSkills();\n await this.recoverActiveTasks();\n }\n\n // Recover pending tasks (for requester/hybrid)\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n await this.recoverPendingTasks();\n }\n\n // Mark as running\n this.running = true;\n\n // Start heartbeat loop\n await this.heartbeat();\n\n this.heartbeatTimer = setInterval(\n () => this.heartbeat().catch(console.error),\n this.config.heartbeatIntervalMs\n );\n\n console.log(`\\n✅ Agent is now running`);\n console.log(` Press Ctrl+C to stop\\n`);\n }\n\n /**\n * Stop the agent gracefully\n */\n async stop(): Promise<void> {\n console.log(`\\n🛑 Stopping agent...`);\n this.running = false;\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n }\n\n // Save final state\n await saveState(this.config.stateFilePath, this.state);\n\n console.log(` State saved`);\n console.log(` Active tasks: ${this.state.activeTasks.length}`);\n console.log(`✅ Agent stopped\\n`);\n }\n\n /**\n * Main heartbeat loop\n */\n private async heartbeat(): Promise<void> {\n const now = Date.now();\n this.state.stats.lastHeartbeat = now;\n\n console.log(`\\n💓 Heartbeat at ${new Date().toISOString()}`);\n\n try {\n // Worker mode: poll and process tasks\n if (this.config.mode === \"worker\" || this.config.mode === \"hybrid\") {\n console.log(` [WORKER] Active tasks: ${this.state.activeTasks.length}/${this.config.maxConcurrentTasks}`);\n await this.pollForTasks();\n await this.processActiveTasks();\n }\n\n // Requester mode: create and monitor tasks\n if (this.config.mode === \"requester\" || this.config.mode === \"hybrid\") {\n console.log(` [REQUESTER] Pending tasks: ${this.state.pendingTasks.length}/${this.config.maxPendingTasks}`);\n await this.processTaskCreationQueue();\n await this.monitorPendingTasks();\n }\n\n // Save state\n await saveState(this.config.stateFilePath, this.state);\n } catch (error) {\n console.error(`❌ Heartbeat error: ${error}`);\n }\n }\n\n /**\n * Poll for available tasks\n */\n private async pollForTasks(): Promise<void> {\n // Check if we can accept more tasks\n if (this.state.activeTasks.length >= this.config.maxConcurrentTasks) {\n console.log(` 📋 At max capacity, skipping poll`);\n return;\n }\n\n // Get skills we can handle\n const skillIds = this.state.skills.map((s) => s.skillId);\n if (skillIds.length === 0) {\n console.log(` 📋 No skills registered, skipping poll`);\n return;\n }\n\n console.log(` 📋 Polling for tasks...`);\n\n try {\n // Poll for POSTED tasks for ALL our skills\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let allTasks: any[] = [];\n \n for (const skillId of skillIds) {\n const result = await this.client.api.listTasks({\n status: STATUS.POSTED,\n skillId: skillId,\n limit: 10,\n });\n allTasks = [...allTasks, ...result.data];\n }\n \n // Deduplicate by task ID\n const seen = new Set<string>();\n const tasks = allTasks.filter((t) => {\n if (seen.has(t.id)) return false;\n seen.add(t.id);\n return true;\n });\n \n console.log(` 📋 Found ${tasks.length} available tasks`);\n\n for (const task of tasks) {\n if (!this.running) break;\n if (this.state.activeTasks.length >= this.config.maxConcurrentTasks) break;\n\n // Check if we can handle this skill\n const skill = this.state.skills.find((s) => s.skillId === task.skill.id);\n if (!skill) continue;\n\n // Check if handler exists\n if (!this.skillRegistry.canHandle(skill.name, skill.version)) {\n console.log(` ⏭ No handler for ${skill.name}@${skill.version}`);\n continue;\n }\n\n // Check minimum payment\n if (BigInt(task.payment_amount_mist) < this.config.minPaymentThreshold) {\n console.log(` ⏭ Payment too low: ${task.payment_amount_mist}`);\n continue;\n }\n\n // Check deadline\n const expiresAt = new Date(task.expires_at).getTime();\n if (expiresAt - Date.now() < this.config.minExecutionTimeMs) {\n console.log(` ⏭ Not enough time: ${task.id}`);\n continue;\n }\n\n // Try to accept this task\n await this.acceptTask(task, skill);\n }\n } catch (error) {\n console.error(` ❌ Poll error: ${error}`);\n }\n }\n\n /**\n * Accept a task\n */\n private async acceptTask(\n task: { id: string; payment_amount_mist: string; worker_bond_amount: string; expires_at: string },\n skill: { skillId: string; name: string }\n ): Promise<void> {\n console.log(`\\n 🎯 Accepting task ${task.id.slice(0, 16)}...`);\n\n try {\n // Get full task details\n const fullTask = await this.client.api.getTask(task.id);\n\n // Add to active tasks (optimistic)\n const activeTask: ActiveTask = {\n taskId: task.id,\n skillId: skill.skillId,\n skillName: skill.name,\n status: STATUS.IN_PROGRESS,\n paymentAmountMist: task.payment_amount_mist,\n workerBondAmount: task.worker_bond_amount,\n inputPayloadRef: fullTask.input_payload_ref,\n expectedOutputHash: fullTask.expected_output_hash,\n acceptedAt: Date.now(),\n expiresAt: new Date(task.expires_at).getTime(),\n };\n\n addActiveTask(this.state, activeTask);\n console.log(` ✅ Task accepted: ${task.id.slice(0, 16)}`);\n\n // Note: In a full implementation, we would:\n // 1. Call reserve() on-chain\n // 2. Call accept() with bond\n // For now, we simulate with API-only flow\n\n } catch (error) {\n console.error(` ❌ Failed to accept task: ${error}`);\n }\n }\n\n /**\n * Process active tasks\n */\n private async processActiveTasks(): Promise<void> {\n const now = Date.now();\n\n for (const task of [...this.state.activeTasks]) {\n if (!this.running) break;\n\n try {\n // Check if expired\n if (task.expiresAt <= now) {\n console.log(` ⏰ Task expired: ${task.taskId.slice(0, 16)}`);\n markTaskFailed(this.state, task.taskId);\n continue;\n }\n\n // Check if still in progress\n if (task.status !== STATUS.IN_PROGRESS) {\n continue;\n }\n\n // Execute the skill\n await this.executeTask(task);\n } catch (error) {\n console.error(` ❌ Task processing error: ${error}`);\n }\n }\n }\n\n /**\n * Execute a task\n */\n private async executeTask(task: ActiveTask): Promise<void> {\n console.log(`\\n ⚙️ Executing task ${task.taskId.slice(0, 16)}...`);\n console.log(` Skill: ${task.skillName}`);\n\n try {\n // Find handler\n const handler = this.skillRegistry.findHandler(task.skillName, \"1.0.0\");\n if (!handler) {\n console.error(` ❌ No handler for ${task.skillName}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n // Fetch input from Walrus\n let input: object;\n try {\n input = await this.client.walrus.getJson(task.inputPayloadRef);\n console.log(` Input fetched from Walrus`);\n } catch (error) {\n console.error(` ❌ Failed to fetch input: ${error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n // Validate input\n if (handler.validateInput) {\n const validation = handler.validateInput(input);\n if (!validation.valid) {\n console.error(` ❌ Input validation failed: ${validation.error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n }\n\n // Execute handler\n const result = await handler.execute(input, {\n taskId: task.taskId,\n skillId: task.skillId,\n skillName: task.skillName,\n skillVersion: \"1.0.0\",\n paymentAmountMist: BigInt(task.paymentAmountMist),\n expiresAt: task.expiresAt,\n });\n\n if (!result.success || !result.output) {\n console.error(` ❌ Handler failed: ${result.error}`);\n markTaskFailed(this.state, task.taskId);\n return;\n }\n\n console.log(` Handler executed successfully`);\n\n // Store output in Walrus\n const storedOutput = await this.client.walrus.storeJson(result.output);\n console.log(` Output stored: ${storedOutput.blobId.slice(0, 20)}...`);\n\n // Submit output on-chain if we have signing capability\n if (this.keypair && this.suiClient && this.config.packageId) {\n try {\n console.log(` Submitting on-chain...`);\n await this.submitTaskOnChain(task.taskId, storedOutput.blobId);\n console.log(` ✅ Task submitted on-chain: ${task.taskId.slice(0, 16)}`);\n } catch (error) {\n console.error(` ❌ On-chain submission failed: ${error}`);\n // Still mark as completed locally for retry later\n }\n } else {\n console.log(` ✅ Task completed (no on-chain key): ${task.taskId.slice(0, 16)}`);\n }\n\n // Mark as completed\n markTaskCompleted(this.state, task.taskId, task.paymentAmountMist);\n\n } catch (error) {\n console.error(` ❌ Execution error: ${error}`);\n markTaskFailed(this.state, task.taskId);\n }\n }\n \n /**\n * Submit task output on-chain\n */\n private async submitTaskOnChain(taskId: string, outputRef: string): Promise<void> {\n if (!this.keypair || !this.suiClient || !this.config.packageId) {\n throw new Error(\"On-chain signing not configured\");\n }\n \n const tx = new Transaction();\n tx.setGasBudget(10_000_000); // 0.01 SUI gas\n \n // Call task::submit(task, worker, output_ref, clock)\n tx.moveCall({\n target: `${this.config.packageId}::task::submit`,\n arguments: [\n tx.object(taskId),\n tx.object(this.config.agentId),\n tx.pure.string(outputRef),\n tx.object(\"0x6\"), // Clock\n ],\n });\n \n const result = await this.suiClient.signAndExecuteTransaction({\n transaction: tx,\n signer: this.keypair,\n options: { showEffects: true },\n });\n \n if (result.effects?.status?.status !== \"success\") {\n throw new Error(`Transaction failed: ${result.effects?.status?.error || \"unknown\"}`);\n }\n \n console.log(` Tx: ${result.digest.slice(0, 15)}...`);\n }\n\n /**\n * Refresh skills list from API\n */\n private async refreshSkills(): Promise<void> {\n console.log(` 📚 Refreshing skills...`);\n\n try {\n const agent = await this.client.api.getAgent(this.config.agentId);\n\n this.state.skills = agent.skills.map((s) => ({\n skillId: s.id,\n name: s.name,\n version: s.version,\n verificationType: s.verification_type,\n basePriceMist: s.base_price_mist,\n workerBondMist: \"0\", // Not in API response\n }));\n\n console.log(` 📚 Found ${this.state.skills.length} skills`);\n\n // Also use configured skill IDs\n for (const skillId of this.config.skillIds) {\n if (!this.state.skills.find((s) => s.skillId === skillId)) {\n // Try to fetch skill details\n try {\n const skill = await this.client.api.getSkill(skillId);\n this.state.skills.push({\n skillId: skill.id,\n name: skill.name,\n version: skill.version,\n verificationType: skill.verification_type,\n basePriceMist: skill.base_price_mist,\n workerBondMist: skill.worker_bond_mist,\n });\n } catch {\n console.warn(` ⚠ Could not fetch skill ${skillId}`);\n }\n }\n }\n } catch (error) {\n console.error(` ❌ Failed to refresh skills: ${error}`);\n }\n }\n\n /**\n * Recover active tasks after restart\n */\n private async recoverActiveTasks(): Promise<void> {\n if (this.state.activeTasks.length === 0) {\n return;\n }\n\n console.log(` 🔄 Recovering ${this.state.activeTasks.length} active tasks...`);\n\n const now = Date.now();\n const tasksToRemove: string[] = [];\n\n for (const task of this.state.activeTasks) {\n // Remove expired tasks\n if (task.expiresAt <= now) {\n console.log(` ⏰ Removing expired task: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n continue;\n }\n\n // Verify task is still valid\n try {\n const fullTask = await this.client.api.getTask(task.taskId);\n\n // Check if task is still in progress\n if (\n fullTask.status !== STATUS.IN_PROGRESS &&\n fullTask.status !== STATUS.ACCEPTED\n ) {\n console.log(` ❌ Task no longer active: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n }\n } catch {\n // Task may have been settled or cancelled\n console.log(` ❌ Task not found: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n }\n }\n\n // Remove invalid tasks\n for (const taskId of tasksToRemove) {\n removeActiveTask(this.state, taskId);\n }\n\n console.log(` 🔄 Recovery complete: ${this.state.activeTasks.length} active tasks`);\n }\n\n /**\n * Get current stats\n */\n getStats() {\n return {\n worker: {\n ...this.state.stats,\n activeTasks: this.state.activeTasks.length,\n registeredSkills: this.state.skills.length,\n },\n requester: {\n ...this.state.requesterStats,\n pendingTasks: this.state.pendingTasks.length,\n queuedTasks: this.taskCreationQueue.length,\n },\n };\n }\n\n /**\n * Get the SDK client\n */\n getClient(): ClankClient {\n return this.client;\n }\n\n // === Requester Mode Methods ===\n\n /**\n * Queue a task for creation (requester mode)\n */\n queueTask(request: CreateTaskRequest): void {\n if (this.config.mode === \"worker\") {\n throw new Error(\"Cannot create tasks in worker mode\");\n }\n\n if (this.state.pendingTasks.length >= this.config.maxPendingTasks) {\n throw new Error(\"Maximum pending tasks reached\");\n }\n\n this.taskCreationQueue.push(request);\n console.log(` 📤 Task queued for creation (skill: ${request.skillId})`);\n }\n\n /**\n * Process task creation queue\n */\n private async processTaskCreationQueue(): Promise<void> {\n while (this.taskCreationQueue.length > 0 && this.running) {\n if (this.state.pendingTasks.length >= this.config.maxPendingTasks) {\n console.log(` 📤 Max pending tasks reached, pausing creation`);\n break;\n }\n\n const request = this.taskCreationQueue.shift()!;\n await this.createTask(request);\n }\n }\n\n /**\n * Create a task on-chain (requester mode)\n */\n private async createTask(request: CreateTaskRequest): Promise<void> {\n console.log(`\\n 📝 Creating task for skill ${request.skillId.slice(0, 16)}...`);\n\n try {\n // Get skill details\n const skill = await this.client.api.getSkill(request.skillId);\n\n // Store input in Walrus\n const storedInput = await this.client.walrus.storeJson(request.input);\n console.log(` Input stored: ${storedInput.blobId.slice(0, 20)}...`);\n\n // Calculate expiry\n const expiresInMs = request.expiresInMs ?? this.config.taskTimeoutMs;\n const expiresAt = Date.now() + expiresInMs;\n\n // Create task via API\n // Note: In full implementation, this would be an on-chain transaction\n const now = Date.now();\n const taskId = `task_${now}_${Math.random().toString(36).slice(2, 10)}`;\n\n // Add to pending tasks\n const pendingTask: PendingTask = {\n taskId,\n skillId: request.skillId,\n skillName: skill.name,\n status: STATUS.POSTED,\n paymentAmountMist: request.paymentAmountMist.toString(),\n workerBondAmount: skill.worker_bond_mist,\n inputPayloadRef: storedInput.blobId,\n expectedOutputHash: request.expectedOutputHash,\n createdAt: now,\n expiresAt,\n };\n\n addPendingTask(this.state, pendingTask);\n console.log(` ✅ Task created: ${taskId.slice(0, 16)}`);\n\n } catch (error) {\n console.error(` ❌ Failed to create task: ${error}`);\n // Re-queue for retry? For now, just log\n }\n }\n\n /**\n * Monitor pending tasks and process submissions\n */\n private async monitorPendingTasks(): Promise<void> {\n const now = Date.now();\n\n for (const task of [...this.state.pendingTasks]) {\n if (!this.running) break;\n\n try {\n // Check if expired\n if (task.expiresAt <= now) {\n console.log(` ⏰ Task expired: ${task.taskId.slice(0, 16)}`);\n markPendingExpired(this.state, task.taskId);\n continue;\n }\n\n // Fetch current status from API\n // Note: In production, we'd use the on-chain task ID\n // For now, simulate status checks\n\n // Process based on status\n if (task.status === STATUS.SUBMITTED && task.outputPayloadRef) {\n await this.processSubmittedTask(task);\n }\n\n } catch (error) {\n console.error(` ❌ Error monitoring task ${task.taskId.slice(0, 16)}: ${error}`);\n }\n }\n }\n\n /**\n * Process a submitted task (verify output and confirm/reject)\n */\n private async processSubmittedTask(task: PendingTask): Promise<void> {\n console.log(`\\n 🔍 Processing submitted task ${task.taskId.slice(0, 16)}...`);\n\n if (!task.outputPayloadRef) {\n console.log(` ⚠ No output payload reference`);\n return;\n }\n\n try {\n // Fetch output from Walrus\n const output = await this.client.walrus.getJson(task.outputPayloadRef);\n console.log(` Output fetched from Walrus`);\n\n // Get skill to check verification type\n const skill = await this.client.api.getSkill(task.skillId);\n \n // Determine if we should auto-confirm\n let shouldConfirm = false;\n\n if (skill.verification_type === VERIFICATION.DETERMINISTIC) {\n // Deterministic: verify hash matches\n if (this.config.autoConfirmDeterministic) {\n if (task.expectedOutputHash) {\n // In production, compute hash and compare\n // For now, assume it matches\n console.log(` Deterministic verification passed`);\n shouldConfirm = true;\n } else {\n console.log(` No expected hash, auto-confirming deterministic task`);\n shouldConfirm = true;\n }\n }\n } else if (skill.verification_type === VERIFICATION.TIME_BOUND) {\n // Time-bound: auto-settle after deadline\n console.log(` Time-bound task, waiting for deadline`);\n } else {\n // RequesterConfirm: need manual confirmation\n console.log(` Awaiting manual confirmation for task`);\n // In a real agent, this would emit an event or call a callback\n }\n\n if (shouldConfirm) {\n await this.confirmTask(task);\n }\n\n } catch (error) {\n console.error(` ❌ Failed to process submitted task: ${error}`);\n }\n }\n\n /**\n * Confirm a submitted task (release payment to worker)\n */\n async confirmTask(task: PendingTask): Promise<void> {\n console.log(` ✅ Confirming task ${task.taskId.slice(0, 16)}...`);\n\n try {\n // Note: In full implementation, call confirm() on-chain\n // For now, simulate confirmation\n\n markPendingSettled(this.state, task.taskId, task.paymentAmountMist);\n console.log(` ✅ Task confirmed and settled`);\n\n } catch (error) {\n console.error(` ❌ Failed to confirm task: ${error}`);\n }\n }\n\n /**\n * Reject a submitted task (return payment, slash worker bond)\n */\n async rejectTask(task: PendingTask, reason: string): Promise<void> {\n console.log(` ❌ Rejecting task ${task.taskId.slice(0, 16)}...`);\n console.log(` Reason: ${reason}`);\n\n try {\n // Note: In full implementation, call reject() on-chain\n // For now, simulate rejection\n\n markPendingExpired(this.state, task.taskId);\n console.log(` ❌ Task rejected`);\n\n } catch (error) {\n console.error(` ❌ Failed to reject task: ${error}`);\n }\n }\n\n /**\n * Get pending task by ID\n */\n getPendingTask(taskId: string): PendingTask | undefined {\n return this.state.pendingTasks.find((t) => t.taskId === taskId);\n }\n\n /**\n * Get all pending tasks\n */\n getPendingTasks(): PendingTask[] {\n return [...this.state.pendingTasks];\n }\n\n /**\n * Recover pending tasks after restart\n */\n private async recoverPendingTasks(): Promise<void> {\n if (this.state.pendingTasks.length === 0) {\n return;\n }\n\n console.log(` 🔄 Recovering ${this.state.pendingTasks.length} pending tasks...`);\n\n const now = Date.now();\n const tasksToRemove: string[] = [];\n\n for (const task of this.state.pendingTasks) {\n // Remove expired tasks\n if (task.expiresAt <= now) {\n console.log(` ⏰ Removing expired pending task: ${task.taskId.slice(0, 16)}`);\n tasksToRemove.push(task.taskId);\n this.state.requesterStats.tasksExpired++;\n continue;\n }\n\n // In production, verify task still exists on-chain\n }\n\n // Remove invalid tasks\n this.state.pendingTasks = this.state.pendingTasks.filter(\n (t) => !tasksToRemove.includes(t.taskId)\n );\n\n console.log(` 🔄 Recovery complete: ${this.state.pendingTasks.length} pending tasks`);\n }\n}\n","import { readFile, writeFile } from \"fs/promises\";\nimport { existsSync } from \"fs\";\n\n/**\n * Active task being processed by the agent\n */\nexport interface ActiveTask {\n taskId: string;\n skillId: string;\n skillName: string;\n status: number;\n paymentAmountMist: string;\n workerBondAmount: string;\n inputPayloadRef: string;\n expectedOutputHash?: string;\n acceptedAt: number;\n expiresAt: number;\n}\n\n/**\n * Registered skill that this agent can handle\n */\nexport interface RegisteredSkill {\n skillId: string;\n name: string;\n version: string;\n verificationType: number;\n basePriceMist: string;\n workerBondMist: string;\n}\n\n/**\n * Pending task created by the agent (requester mode)\n */\nexport interface PendingTask {\n taskId: string;\n skillId: string;\n skillName: string;\n status: number;\n paymentAmountMist: string;\n workerBondAmount: string;\n inputPayloadRef: string;\n expectedOutputHash?: string;\n createdAt: number;\n expiresAt: number;\n workerId?: string;\n outputPayloadRef?: string;\n submittedAt?: number;\n}\n\n/**\n * Agent state that is persisted to disk\n */\nexport interface AgentState {\n // Active tasks being processed (worker mode)\n activeTasks: ActiveTask[];\n\n // Pending tasks awaiting completion (requester mode)\n pendingTasks: PendingTask[];\n\n // Skills this agent is registered to handle\n skills: RegisteredSkill[];\n\n // Statistics (worker)\n stats: {\n tasksAccepted: number;\n tasksCompleted: number;\n tasksFailed: number;\n totalEarnedMist: string;\n lastHeartbeat: number;\n startedAt: number;\n };\n\n // Statistics (requester)\n requesterStats: {\n tasksCreated: number;\n tasksSettled: number;\n tasksExpired: number;\n totalSpentMist: string;\n };\n\n // Agent identity\n agentId: string;\n}\n\n/**\n * Create initial empty state\n */\nexport function createInitialState(agentId: string): AgentState {\n return {\n activeTasks: [],\n pendingTasks: [],\n skills: [],\n stats: {\n tasksAccepted: 0,\n tasksCompleted: 0,\n tasksFailed: 0,\n totalEarnedMist: \"0\",\n lastHeartbeat: 0,\n startedAt: Date.now(),\n },\n requesterStats: {\n tasksCreated: 0,\n tasksSettled: 0,\n tasksExpired: 0,\n totalSpentMist: \"0\",\n },\n agentId,\n };\n}\n\n/**\n * Load state from file\n */\nexport async function loadState(\n filePath: string,\n agentId: string\n): Promise<AgentState> {\n if (!existsSync(filePath)) {\n console.log(`📁 No state file found, creating new state`);\n return createInitialState(agentId);\n }\n\n try {\n const data = await readFile(filePath, \"utf-8\");\n const state = JSON.parse(data) as AgentState;\n\n // Validate agent ID matches\n if (state.agentId !== agentId) {\n console.warn(`⚠ State file agent ID mismatch, creating new state`);\n return createInitialState(agentId);\n }\n\n console.log(`📁 Loaded state: ${state.activeTasks.length} active tasks`);\n return state;\n } catch (error) {\n console.warn(`⚠ Failed to load state file: ${error}`);\n return createInitialState(agentId);\n }\n}\n\n/**\n * Save state to file\n */\nexport async function saveState(\n filePath: string,\n state: AgentState\n): Promise<void> {\n try {\n await writeFile(filePath, JSON.stringify(state, null, 2));\n } catch (error) {\n console.error(`❌ Failed to save state: ${error}`);\n }\n}\n\n/**\n * Add active task to state\n */\nexport function addActiveTask(state: AgentState, task: ActiveTask): void {\n // Check if task already exists\n const existing = state.activeTasks.find((t) => t.taskId === task.taskId);\n if (!existing) {\n state.activeTasks.push(task);\n state.stats.tasksAccepted++;\n }\n}\n\n/**\n * Remove active task from state\n */\nexport function removeActiveTask(state: AgentState, taskId: string): void {\n state.activeTasks = state.activeTasks.filter((t) => t.taskId !== taskId);\n}\n\n/**\n * Update task in state\n */\nexport function updateActiveTask(\n state: AgentState,\n taskId: string,\n updates: Partial<ActiveTask>\n): void {\n const task = state.activeTasks.find((t) => t.taskId === taskId);\n if (task) {\n Object.assign(task, updates);\n }\n}\n\n/**\n * Mark task as completed\n */\nexport function markTaskCompleted(\n state: AgentState,\n taskId: string,\n earnedMist: string\n): void {\n removeActiveTask(state, taskId);\n state.stats.tasksCompleted++;\n state.stats.totalEarnedMist = (\n BigInt(state.stats.totalEarnedMist) + BigInt(earnedMist)\n ).toString();\n}\n\n/**\n * Mark task as failed\n */\nexport function markTaskFailed(state: AgentState, taskId: string): void {\n removeActiveTask(state, taskId);\n state.stats.tasksFailed++;\n}\n\n// === Requester Mode State Functions ===\n\n/**\n * Add pending task to state (requester mode)\n */\nexport function addPendingTask(state: AgentState, task: PendingTask): void {\n const existing = state.pendingTasks.find((t) => t.taskId === task.taskId);\n if (!existing) {\n state.pendingTasks.push(task);\n state.requesterStats.tasksCreated++;\n }\n}\n\n/**\n * Remove pending task from state\n */\nexport function removePendingTask(state: AgentState, taskId: string): void {\n state.pendingTasks = state.pendingTasks.filter((t) => t.taskId !== taskId);\n}\n\n/**\n * Update pending task in state\n */\nexport function updatePendingTask(\n state: AgentState,\n taskId: string,\n updates: Partial<PendingTask>\n): void {\n const task = state.pendingTasks.find((t) => t.taskId === taskId);\n if (task) {\n Object.assign(task, updates);\n }\n}\n\n/**\n * Mark pending task as settled\n */\nexport function markPendingSettled(\n state: AgentState,\n taskId: string,\n spentMist: string\n): void {\n removePendingTask(state, taskId);\n state.requesterStats.tasksSettled++;\n state.requesterStats.totalSpentMist = (\n BigInt(state.requesterStats.totalSpentMist) + BigInt(spentMist)\n ).toString();\n}\n\n/**\n * Mark pending task as expired\n */\nexport function markPendingExpired(state: AgentState, taskId: string): void {\n removePendingTask(state, taskId);\n state.requesterStats.tasksExpired++;\n}\n","/**\n * Result of skill execution\n */\nexport interface SkillResult {\n success: boolean;\n output?: object;\n error?: string;\n}\n\n/**\n * Skill handler interface - implement this for each skill\n */\nexport interface SkillHandler {\n /** Handler name */\n name: string;\n\n /** Handler version */\n version: string;\n\n /**\n * Check if this handler can process the given skill\n */\n canHandle(skillName: string, skillVersion: string): boolean;\n\n /**\n * Execute the skill with the given input\n */\n execute(input: object, context?: SkillContext): Promise<SkillResult>;\n\n /**\n * Validate the input before processing\n */\n validateInput?(input: object): { valid: boolean; error?: string };\n\n /**\n * Estimate execution time in milliseconds\n */\n estimateExecutionTime?(input: object): number;\n}\n\n/**\n * Context provided to skill handlers\n */\nexport interface SkillContext {\n taskId: string;\n skillId: string;\n skillName: string;\n skillVersion: string;\n paymentAmountMist: bigint;\n expiresAt: number;\n}\n\n/**\n * Skill registry for managing available handlers\n */\nexport class SkillRegistry {\n private handlers: SkillHandler[] = [];\n\n /**\n * Register a skill handler\n */\n register(handler: SkillHandler): void {\n // Check for duplicates\n const existing = this.handlers.find(\n (h) => h.name === handler.name && h.version === handler.version\n );\n if (existing) {\n console.warn(`⚠ Handler ${handler.name}@${handler.version} already registered`);\n return;\n }\n\n this.handlers.push(handler);\n console.log(`📦 Registered handler: ${handler.name}@${handler.version}`);\n }\n\n /**\n * Find a handler for the given skill\n */\n findHandler(skillName: string, skillVersion: string): SkillHandler | undefined {\n return this.handlers.find((h) => h.canHandle(skillName, skillVersion));\n }\n\n /**\n * Get all registered handlers\n */\n getHandlers(): SkillHandler[] {\n return [...this.handlers];\n }\n\n /**\n * Check if any handler can process the skill\n */\n canHandle(skillName: string, skillVersion: string): boolean {\n return this.findHandler(skillName, skillVersion) !== undefined;\n }\n}\n","import type { SkillHandler, SkillResult } from \"./types.js\";\n\n/**\n * Echo skill handler - simply echoes back the input with metadata\n *\n * This is a reference implementation for testing the task flow.\n */\nexport const echoSkillHandler: SkillHandler = {\n name: \"echo\",\n version: \"1.0.0\",\n\n /**\n * Check if this handler can process the given skill\n */\n canHandle(skillName: string, skillVersion: string): boolean {\n return (\n skillName.toLowerCase().includes(\"echo\") ||\n skillName.toLowerCase().includes(\"test\")\n );\n },\n\n /**\n * Process the input and return the output\n */\n async execute(input: object): Promise<SkillResult> {\n const now = Date.now();\n\n // Simulate some processing time (100-500ms)\n await new Promise((resolve) =>\n setTimeout(resolve, 100 + Math.random() * 400)\n );\n\n // Return the echoed input with metadata\n const output = {\n echo: input,\n metadata: {\n processedAt: now,\n processingTimeMs: Date.now() - now,\n handler: \"echo-skill-v1\",\n version: \"1.0.0\",\n },\n };\n\n return {\n success: true,\n output,\n };\n },\n\n /**\n * Validate the input before processing\n */\n validateInput(input: object): { valid: boolean; error?: string } {\n // Echo skill accepts any input\n if (input === null || input === undefined) {\n return { valid: false, error: \"Input cannot be null or undefined\" };\n }\n return { valid: true };\n },\n};\n\n/**\n * Echo skill JSON schema\n */\nexport const echoInputSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n description: \"Echo skill input - any JSON object\",\n additionalProperties: true,\n};\n\nexport const echoOutputSchema = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n type: \"object\",\n properties: {\n echo: {\n description: \"The echoed input\",\n },\n metadata: {\n type: \"object\",\n properties: {\n processedAt: { type: \"number\" },\n processingTimeMs: { type: \"number\" },\n handler: { type: \"string\" },\n version: { type: \"string\" },\n },\n required: [\"processedAt\", \"processingTimeMs\", \"handler\", \"version\"],\n },\n },\n required: [\"echo\", \"metadata\"],\n};\n","import \"dotenv/config\";\nimport type { Network } from \"@clankxyz/shared\";\n\n/**\n * Agent mode: worker executes tasks, requester creates and monitors tasks\n */\nexport type AgentMode = \"worker\" | \"requester\" | \"hybrid\";\n\n/**\n * Agent configuration loaded from environment variables\n */\nexport interface AgentConfig {\n // API configuration\n apiUrl: string;\n apiKey: string;\n\n // Agent identity\n agentId: string;\n\n // Agent mode\n mode: AgentMode;\n\n // Network configuration\n network: Network;\n rpcUrl?: string;\n packageId?: string;\n \n // Private key for on-chain transactions (optional)\n privateKey?: string;\n\n // Walrus configuration\n walrusAggregator?: string;\n walrusPublisher?: string;\n\n // Worker behavior\n maxConcurrentTasks: number;\n minPaymentThreshold: bigint;\n minExecutionTimeMs: number;\n heartbeatIntervalMs: number;\n pollIntervalMs: number;\n\n // Requester behavior\n maxPendingTasks: number;\n autoConfirmDeterministic: boolean;\n taskTimeoutMs: number;\n\n // Skills this agent can handle (worker mode)\n skillIds: string[];\n\n // State persistence\n stateFilePath: string;\n\n // Webhook server (optional)\n webhookPort?: number;\n webhookSecret?: string;\n}\n\n/**\n * Load configuration from environment variables\n */\nexport function loadConfig(): AgentConfig {\n const apiUrl = process.env.CLANK_API_URL;\n const apiKey = process.env.CLANK_API_KEY;\n const agentId = process.env.CLANK_AGENT_ID;\n\n if (!apiUrl) {\n throw new Error(\"CLANK_API_URL is required\");\n }\n if (!apiKey) {\n throw new Error(\"CLANK_API_KEY is required\");\n }\n if (!agentId) {\n throw new Error(\"CLANK_AGENT_ID is required\");\n }\n\n return {\n // API configuration\n apiUrl,\n apiKey,\n agentId,\n\n // Agent mode\n mode: (process.env.AGENT_MODE as AgentMode) ?? \"worker\",\n\n // Network configuration\n network: (process.env.CLANK_NETWORK as Network) ?? \"testnet\",\n rpcUrl: process.env.SUI_RPC_URL,\n packageId: process.env.CLANK_PACKAGE_ID,\n privateKey: process.env.CLANK_PRIVATE_KEY,\n\n // Walrus configuration\n walrusAggregator: process.env.WALRUS_AGGREGATOR_URL,\n walrusPublisher: process.env.WALRUS_PUBLISHER_URL,\n\n // Worker behavior\n maxConcurrentTasks: parseInt(process.env.MAX_CONCURRENT_TASKS ?? \"5\", 10),\n minPaymentThreshold: BigInt(process.env.MIN_PAYMENT_THRESHOLD ?? \"10000000\"), // $10\n minExecutionTimeMs: parseInt(process.env.MIN_EXECUTION_TIME_MS ?? \"1800000\", 10), // 30 min\n heartbeatIntervalMs: parseInt(process.env.HEARTBEAT_INTERVAL_MS ?? \"60000\", 10), // 1 min\n pollIntervalMs: parseInt(process.env.POLL_INTERVAL_MS ?? \"30000\", 10), // 30 sec\n\n // Requester behavior\n maxPendingTasks: parseInt(process.env.MAX_PENDING_TASKS ?? \"20\", 10),\n autoConfirmDeterministic: process.env.AUTO_CONFIRM_DETERMINISTIC !== \"false\",\n taskTimeoutMs: parseInt(process.env.TASK_TIMEOUT_MS ?? \"3600000\", 10), // 1 hour\n\n // Skills\n skillIds: process.env.SKILL_IDS?.split(\",\").filter(Boolean) ?? [],\n\n // State persistence\n stateFilePath: process.env.STATE_FILE_PATH ?? \"./.agent-state.json\",\n\n // Webhook server\n webhookPort: process.env.WEBHOOK_PORT\n ? parseInt(process.env.WEBHOOK_PORT, 10)\n : undefined,\n webhookSecret: process.env.WEBHOOK_SECRET,\n };\n}\n\n/**\n * Validate configuration\n */\nexport function validateConfig(config: AgentConfig): void {\n if (config.mode === \"worker\" || config.mode === \"hybrid\") {\n if (config.skillIds.length === 0) {\n console.warn(\"⚠ No skill IDs configured. Agent will not accept any tasks.\");\n }\n\n if (config.maxConcurrentTasks < 1) {\n throw new Error(\"maxConcurrentTasks must be at least 1\");\n }\n }\n\n if (config.mode === \"requester\" || config.mode === \"hybrid\") {\n if (config.maxPendingTasks < 1) {\n throw new Error(\"maxPendingTasks must be at least 1\");\n }\n }\n\n if (config.heartbeatIntervalMs < 10000) {\n console.warn(\"⚠ Heartbeat interval < 10s may cause rate limiting\");\n }\n\n if (![\"worker\", \"requester\", \"hybrid\"].includes(config.mode)) {\n throw new Error(`Invalid AGENT_MODE: ${config.mode}. Must be worker, requester, or hybrid`);\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@clankxyz/agent",
3
- "version": "0.1.0",
4
- "description": "Reference implementation of a TaskNet agent",
3
+ "version": "0.1.2",
4
+ "description": "Reference implementation of a Clank agent",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "bin": {
9
- "tasknet-agent": "./dist/cli.js"
9
+ "clank-agent": "./dist/cli.js"
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
13
  "README.md"
14
14
  ],
15
15
  "keywords": [
16
- "tasknet",
16
+ "clank",
17
17
  "agent",
18
18
  "autonomous",
19
19
  "ai"
@@ -21,11 +21,12 @@
21
21
  "author": "",
22
22
  "license": "MIT",
23
23
  "dependencies": {
24
+ "@mysten/sui": "^1.21.1",
24
25
  "chalk": "^5.3.0",
25
26
  "commander": "^12.1.0",
26
27
  "dotenv": "^16.4.5",
27
- "@clankxyz/sdk": "0.1.0",
28
- "@clankxyz/shared": "0.1.0"
28
+ "@clankxyz/shared": "0.1.0",
29
+ "@clankxyz/sdk": "0.1.0"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/node": "^22.0.0",
@@ -36,7 +37,7 @@
36
37
  },
37
38
  "repository": {
38
39
  "type": "git",
39
- "url": "https://github.com/mission69b/tasknet-protocol"
40
+ "url": "https://github.com/clankxyz/clankxyz"
40
41
  },
41
42
  "scripts": {
42
43
  "build": "tsup",