diff --git a/apps/web/src/app/api/webhooks/github/route.ts b/apps/web/src/app/api/webhooks/github/route.ts index 612b4c7..594c6be 100644 --- a/apps/web/src/app/api/webhooks/github/route.ts +++ b/apps/web/src/app/api/webhooks/github/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { prisma } from "@/lib/prisma"; -import { capturePayment } from "@/lib/payment"; +import { capturePayment, executePayout } from "@/lib/payment"; import { TaskStatus } from "@agent-bounty/contracts"; export async function POST(request: NextRequest) { @@ -56,6 +56,7 @@ export async function POST(request: NextRequest) { // Process payout await capturePayment(tx, task.id, `${claim.id}-capture-pr`); + await executePayout(tx, task.id, claim.developer_wallet, claim.held_amount, claim.held_currency, `${claim.id}-payout-pr`); } }); diff --git a/scripts/simulate_agent.ts b/scripts/simulate_agent.ts index aa9fa4a..3dc088d 100644 --- a/scripts/simulate_agent.ts +++ b/scripts/simulate_agent.ts @@ -1,10 +1,11 @@ import { v4 as uuidv4 } from "uuid"; -const API_BASE = "http://192.168.0.110:3000/api/mcp"; +const API_BASE = "http://192.168.0.110:3000/api"; +const MCP_API_BASE = "http://192.168.0.110:3000/api/mcp"; const API_KEY = "super-secret-mcp-key"; async function callTool(tool: string, payload: any) { - const res = await fetch(`${API_BASE}/${tool}`, { + const res = await fetch(`${MCP_API_BASE}/${tool}`, { method: "POST", headers: { "Content-Type": "application/json", @@ -24,45 +25,63 @@ async function main() { console.log("šŸ¤– [Simulated Agent] Booting up..."); const agentId = "agent-simulator-" + Math.floor(Math.random() * 1000); - const targetTaskId = "5b7e923e-6a5b-4395-9b24-7df84d1bc81e"; - console.log(`Selecting Task ID: ${targetTaskId}`); + console.log("šŸ” 1. Scanning for OPEN tasks..."); + const openTasksRes = await fetch(`${API_BASE}/open-tasks`); + const openTasks = await openTasksRes.json(); + + if (!openTasks || openTasks.length === 0) { + console.error("āŒ No open tasks found. Run `scripts/seed_tasks.ts` first."); + return; + } + + const targetTask = openTasks[0]; + const targetTaskId = targetTask.id; + console.log(`šŸŽÆ Found Task: "${targetTask.title}" (ID: ${targetTaskId})`); console.log("\nšŸ’° 2. Claiming Task..."); const claimRes = await callTool("claim_task", { task_id: targetTaskId, agent_id: agentId, - developer_wallet: "0x1234567890123456789012345678901234567890" + // Provide a mocked Stripe Connect ID for payout + developer_wallet: "acct_1MockStripeConnectedAccount123" }); - console.log("Claimed successfully. Claim Token:", claimRes.claim_token); + console.log("āœ… Claimed successfully. Claim Token:", claimRes.claim_token); - console.log("\nšŸ¤–šŸ”„šŸ¤– 3. Demonstrating A2A (Agent-to-Agent) Subcontracting..."); - // Now we create a subtask! - const subTaskRes = await callTool("create_sub_task", { - parent_task_id: targetTaskId, - claim_token: claimRes.claim_token, - title: "Write unit tests for the fibonacci function", - description: "Write comprehensive unit tests in Jest for fib(n).", - reward_amount: 1000, // $10 out of the $500 - acceptance_criteria: { - validation_mode: "AST_PARSING", - test_file_content: "import { test } from 'jest'; test('fake', () => { /* min 20 chars */ });" - } - }); - console.log("Sub-task created successfully! Sub Task ID:", subTaskRes.sub_task_id); - - console.log("\nšŸš€ 4. Submitting Solution for Main Task..."); + console.log("\nšŸš€ 3. Submitting Solution for Main Task..."); + const fakePrUrl = `https://github.com/agent-bounty/example/pull/${Math.floor(Math.random() * 1000)}`; const solutionRes = await callTool("submit_solution", { task_id: targetTaskId, claim_token: claimRes.claim_token, deliverables: { - "index.ts": "export function fib(n: number): number {\n if(n<=1) return n;\n let a=0, b=1, c=0;\n for(let i=2; i<=n; i++) { c=a+b; a=b; b=c; }\n return b;\n}" + "index.ts": "export function fix() { return 'fixed'; }" }, - github_pr_url: "https://github.com/example/pr/1" + github_pr_url: fakePrUrl }); - console.log("Solution submitted! Submission ID:", solutionRes.submission_id); + console.log("āœ… Solution submitted! Submission ID:", solutionRes.submission_id); console.log("Status:", solutionRes.status); - console.log("\nāœ… Simulation complete. Now we wait for the E2B Sandbox judge and the FOMO broadcaster to trigger!"); + console.log("\nšŸ”” 4. Simulating GitHub Webhook (PR Merged)..."); + // Simulate the exact webhook payload that GitHub sends when a PR is merged + const webhookRes = await fetch(`${API_BASE}/webhooks/github`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-github-event": "pull_request" + }, + body: JSON.stringify({ + action: "closed", + pull_request: { + merged: true, + html_url: fakePrUrl + } + }) + }); + + if (webhookRes.ok) { + console.log("āœ… GitHub Webhook processed successfully. Agent should receive payout via Stripe!"); + } else { + console.error("āŒ Webhook failed:", await webhookRes.text()); + } } main().catch(console.error);