ScoutAgent
by 0xCaptain888
README.md
<p align="center">
<a href="https://2qc4bf9e.mule.page/"><img src="https://img.shields.io/badge/🌐_Demo_Site-2qc4bf9e.mule.page-00f0d4?style=for-the-badge" alt="Demo Site" /></a>
<a href="https://x.com/0xCaptain888/status/2057732819137466477"><img src="https://img.shields.io/badge/𝕏_Twitter-@0xCaptain888-1DA1F2?style=for-the-badge&logo=x&logoColor=white" alt="Twitter" /></a>
</p>
<p align="center">
<img src="https://img.shields.io/badge/X_Layer-Testnet-7B3FE4?style=for-the-badge" alt="X Layer Testnet" />
<img src="https://img.shields.io/badge/Solidity-0.8.24-363636?style=for-the-badge&logo=solidity" alt="Solidity" />
<img src="https://img.shields.io/badge/Next.js-14-000000?style=for-the-badge&logo=nextdotjs" alt="Next.js" />
<a href="https://www.npmjs.com/package/@scoutagent/mcp-server"><img src="https://img.shields.io/npm/v/@scoutagent/mcp-server?style=for-the-badge&label=MCP%20Server&color=CB3837&logo=npm" alt="npm" /></a>
<img src="https://img.shields.io/badge/License-MIT-green?style=for-the-badge" alt="MIT" />
</p>
<h1 align="center">ScoutAgent</h1>
<p align="center">
<strong>Mint AI Scout NFTs that bet on the World Cup for you, on X Layer.</strong><br/>
Built for OKX Build X Hackathon · XCup 2026.
</p>
<p align="center">
<img src="docs/images/dashboard-demo.gif" alt="ScoutAgent Dashboard Demo" width="900" />
</p>
<p align="center">
<a href="docs/PITCH.md">Pitch Deck</a> ·
<a href="docs/ARCHITECTURE.md">Architecture</a> ·
<a href="docs/MCP_GUIDE.md">MCP Guide</a> ·
<a href="docs/DEMO_SCRIPT.md">Demo Script</a> ·
<a href="docs/SECURITY.md">Security</a> ·
<a href="docs/SUBMISSION.md">Submission</a>
</p>
---
## Table of Contents
- [What It Is](#what-it-is)
- [Why This Matters for X Layer](#why-this-matters-for-x-layer)
- [Key Features](#key-features)
- [Badge System](#badge-system)
- [Architecture](#architecture)
- [Tech Stack](#tech-stack)
- [Deployed Contracts (X Layer Testnet)](#deployed-contracts-x-layer-testnet)
- [Live On-chain Activity](#live-on-chain-activity)
- [Demo Agents](#demo-agents)
- [MCP Server](#mcp-server)
- [Dashboard Demo Mode](#dashboard-demo-mode)
- [Getting Started](#getting-started)
- [Project Structure](#project-structure)
- [Frontend Pages](#frontend-pages)
- [Agent Runtime API](#agent-runtime-api)
- [Oracle Design](#oracle-design)
- [OKX OnchainOS Integration](#okx-onchainos-integration)
- [Testing](#testing)
- [Security](#security)
- [MCP Marketplace Submission](#mcp-marketplace-submission)
- [Team](#team)
- [License](#license)
---
## What It Is
ScoutAgent is an **AI-agent-driven prediction market platform** built for the 2026 FIFA World Cup on **X Layer**, the zkEVM Layer 2 by OKX.
Instead of placing bets manually, users **mint an AI Scout Agent NFT** with configurable strategy genes -- risk level, betting style, bankroll allocation -- and let it bet autonomously. Each agent analyzes live odds, historical stats, and social sentiment through an LLM-powered reasoning loop (DeepSeek v4), then places bets on-chain without human intervention.
The result: **Agent vs Agent** autonomous prediction markets where AI scouts compete on a public leaderboard, ranked by real PnL.
**Why ScoutAgent?**
- **For fans** -- No crypto complexity. Mint once, fund the bankroll, watch your agent compete.
- **For degens** -- Encode your strategy into an NFT and let it execute around the clock.
- **For builders** -- The first World Cup MCP Server on X Layer. Integrate ScoutAgent into any AI workflow via Claude Desktop or Cursor.
- **For the ecosystem** -- Demonstrates real-world utility for X Layer with verifiable, on-chain agent actions.
---
## Why This Matters for X Layer
ScoutAgent isn't just a hackathon demo -- it's designed to be a **measurable growth driver for X Layer**.
### Addressable Market
The 2026 FIFA World Cup will reach an estimated **5 billion viewers**. Even a conservative 0.01% conversion to crypto-native engagement equals **500,000 new wallet activations** -- a once-every-four-years onboarding window that won't repeat until 2030.
### Per-User On-chain Footprint
Each Scout Agent generates predictable, measurable activity:
| Lifecycle Event | Tx Count per Agent | Notes |
|-----------------|--------------------| ----- |
| Mint | 1 | One-time ERC-721 mint |
| Bankroll deposits | 1-3 | Initial fund + refills |
| Bets placed | 32-64 | Roughly 2 bets per group-stage match |
| Reward claims | 5-10 | Per-resolved-market claim |
| **Total** | **~50 tx/agent** | All settled on X Layer |
At scale: **100K active agents x 50 tx = 5 million transactions** during a single tournament window.
### TVL Footprint
Average bankroll per agent: **$20-$50 USDT**.
At 100K agents: **$2-5M USDT locked on X Layer** for the tournament duration.
This is recurring TVL -- bankrolls deposited at the start, reclaimed at the end, and likely re-deployed for the next sporting season (NBA, NFL playoffs, Olympics 2028).
### Distribution via MCP
The ScoutAgent MCP Server makes X Layer's prediction markets accessible from **any AI workflow** -- Claude Desktop, Cursor, Cline, Continue, and forthcoming AI clients. Each MCP install is a passive ambassador for X Layer's existence in the developer mindshare.
### Why World Cup Specifically
Three reasons this mechanism only works at this scale on a flagship sporting event:
1. **Series-based progression** -- The Badge system requires a multi-match tournament structure. Single-match betting doesn't accumulate state worth visualizing.
2. **Universal fan emotion** -- Football is the only sport with billions of emotionally invested fans worldwide. Niche sports can't sustain the social-graph dynamics ScoutAgent requires.
3. **Compressed timeline** -- A month-long tournament forces decisions and creates urgency. Year-round leagues dilute the autonomous-agent narrative.
> Full quantitative analysis: [docs/MARKET_VALUE.md](docs/MARKET_VALUE.md)
---
## Key Features
- **On-chain AI Agents** -- ERC-721 NFTs with fully on-chain SVG art encoding strategy genes (risk, style, bankroll %).
- **Autonomous Betting Loop** -- ReAct-style reasoning loop fetches odds, stats, and sentiment, then decides BET or SKIP per fixture.
- **Prediction Markets** -- Pool-based markets per match with proportional payouts and a 2% protocol fee. 30% of fees automatically route to the World Cup Prize Pool.
- **On-chain Leaderboard** -- `RankingBoard` contract tracks cumulative PnL for every agent, fully verifiable.
- **Badge System** -- Winning bets earn team badges rendered in the agent's on-chain SVG. Badges accumulate across the tournament and determine each agent's share of the World Cup Prize Pool.
- **World Cup Prize Pool** -- `WorldCupPrizePool` contract accumulates protocol fees and distributes them at tournament end, proportional to badge count.
- **Natural Language Interface** -- Tell your agent "I'm betting on Argentina tonight" and it parses intent, confirms, and executes.
- **Agent Detail with PnL Charts** -- Decision history from on-chain `BetPlaced` events, SVG-based cumulative PnL curve, badge display, and bankroll deposit/withdraw transactions.
- **Dynamic OG Images** -- Each agent page generates a unique 1200x630 OpenGraph preview image via `next/og` for social sharing, including badge count and prize pool status. The root layout includes full OpenGraph and Twitter Card meta tags with `@ScoutAgent_XL` handles, `og:image`, `og:url`, and `og:locale` for maximum social reach.
- **SIWE Authentication** -- All write API endpoints require Sign-In with Ethereum (EIP-4361) verification. The runtime parses SIWE messages, verifies signatures via `viem`, enforces nonce replay protection, and checks message expiry. Owner-only endpoints additionally verify on-chain ownership.
- **MCP Server** -- Query agents, leaderboards, and markets from Claude Desktop or Cursor with a single `npx` command. Published on [npm](https://www.npmjs.com/package/@scoutagent/mcp-server) with dual ESM/CJS exports.
- **Dashboard Demo Mode** -- Append `?demo=true` for pre-scripted animations optimized for video recording.
- **Real Score Resolution** -- Market resolution fetches actual match scores from Football-Data API with configurable mock fallback.
- **Shared UI Component Library** -- Reusable `Button`, `Card`, `Badge`, `Spinner`, and `StatCard` components in `packages/ui`.
- **Full-stack Monorepo** -- Contracts, agent runtime, indexer, web UI, and MCP server in one Turborepo workspace.
---
## Badge System
ScoutAgent introduces a **World Cup Badge mechanism** -- a progression system that only works within a multi-match tournament structure.
### How It Works
1. **Earn badges by winning** -- Every time your Scout Agent bets on the winning team and profits, it earns a team badge (e.g., "ARG", "FRA", "BRA").
2. **Badges accumulate on-chain** -- The `BadgeRegistry` contract tracks all badges per agent. No separate NFTs needed -- badges are counters rendered directly in the agent's on-chain SVG.
3. **Badges decide prize pool share** -- At the end of the World Cup, the `WorldCupPrizePool` distributes accumulated protocol fees proportionally to each agent's total badge count.
### Why This Only Works for the World Cup
- **Series-based progression** -- The badge system requires a multi-match tournament. Single-match betting doesn't accumulate state worth visualizing.
- **Universal fan emotion** -- Football is the only sport with billions of emotionally invested fans worldwide.
- **Compressed timeline** -- A month-long tournament forces decisions and creates urgency that year-round leagues dilute.
### Contracts
| Contract | Purpose |
|----------|---------|
| `BadgeRegistry` | Tracks badges earned per agent per team. Called by PredictionMarket on winning claims. |
| `WorldCupPrizePool` | Accumulates 30% of protocol fees. Distributes at tournament end by badge count. |
| `TeamIds` library | Canonical team ID constants (ARG=1, FRA=2, ...) with name and flag color lookups. |
### Badge SVG Rendering
Agent NFTs dynamically render earned badges as colored team circles in the on-chain SVG:
```
+---------------------------+
| SCOUT AGENT #4 |
| [telescope emoji] |
| DATA_DRIVEN |
| RISK ████░░░░░ 3/5 |
| PnL: +187 USDT |
| |
| BADGES EARNED (3) |
| [ARG] [FRA] [BRA] |
+---------------------------+
```
Each circle uses the team's national flag dominant color, making agents visually evolve through the tournament.
---
## Architecture
```
+------------------+ +----------------+ +---------------------+
| Next.js | | MCP Server | | Claude / Cursor |
| Frontend | | (stdio) |<--->| (AI Clients) |
| :3000 | +----------------+ +---------------------+
+--------+---------+ |
| | HTTP
| +------v--------+
| | Agent Runtime | +--------+ +-------+ +-----------+
+-------------->| :3001 |---->| Odds | | Stats | | Sentiment |
+------+--------+ +--------+ +-------+ +-----------+
| \ | /
| +--v-------v------v---+
| | DeepSeek LLM |
| +---------+----------+
| |
+------v--------+ +--------v-----------+
| Indexer | | X Layer (zkEVM) |
| :3002 | | - AgentRegistry |
+------+--------+ | - PredictionMarket |
| | - MatchOracle |
+------v--------+ | - RankingBoard |
| PostgreSQL | | - BadgeRegistry |
| :5432 | | - WorldCupPrizePool|
+---------------+ | - AgentVault |
+--------------------+
```
**Data flow:**
1. User mints a Scout Agent NFT via the web UI (or MCP).
2. Agent Runtime loads strategy genes from `AgentRegistry` on-chain.
3. Runtime fetches live odds, head-to-head records, and social sentiment from external APIs.
4. DeepSeek LLM receives a strategy-aware prompt and returns a structured decision.
5. If BET, the runtime submits a transaction to `PredictionMarket.placeBet()` on X Layer. 30% of the protocol fee automatically routes to `WorldCupPrizePool`.
6. After the match, `MatchOracle` posts the final score and the market resolves.
7. Winning agents claim rewards via `claimReward()`, which awards team badges via `BadgeRegistry`.
8. `RankingBoard` updates agent stats. The Indexer writes events to PostgreSQL for the frontend.
---
## Tech Stack
| Layer | Technology | Purpose |
|-------|------------|---------|
| **Network** | X Layer (zkEVM L2 by OKX) | Low-fee EVM-compatible settlement |
| **Contracts** | Solidity 0.8.24 + Foundry | AgentRegistry, PredictionMarket, MatchOracle, RankingBoard, BadgeRegistry, WorldCupPrizePool, AgentVault |
| **Agent Runtime** | TypeScript + Fastify | ReAct reasoning loop with LLM integration |
| **LLM** | DeepSeek v4 (via OpenAI-compatible SDK) | Strategy reasoning and bet decisions |
| **Frontend** | Next.js 14 + RainbowKit + wagmi + Tailwind CSS | Wallet connection, minting, dashboard |
| **MCP Server** | @modelcontextprotocol/sdk | Claude Desktop / Cursor integration |
| **Indexer** | TypeScript + viem + PostgreSQL | On-chain event indexing and query layer |
| **Data Sources** | Football-Data API, The Odds API | Live fixtures, odds, head-to-head records |
| **Shared UI** | React component library (`packages/ui`) | Button, Card, Badge, Spinner, StatCard |
| **Infrastructure** | PostgreSQL, Redis, Docker Compose | Persistence, job queues, orchestration |
---
## Deployed Contracts (X Layer Testnet)
> **Chain:** X Layer Testnet (chainId `195`)
> **Deployer:** [`0x2F9fDE6B6FB8d7353aB80F082f85F0d70B809C3b`](https://www.oklink.com/xlayer-test/address/0x2F9fDE6B6FB8d7353aB80F082f85F0d70B809C3b)
> **Badge System:** Deployed -- agents earn team badges on winning bets, badges determine World Cup Prize Pool share
| Contract | Address | Explorer |
|----------|---------|----------|
| MockUSDT | `0x9284B976cB15cD825b1ee771e68E8D38eF38bC8d` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0x9284B976cB15cD825b1ee771e68E8D38eF38bC8d) |
| AgentRegistry | `0x634c68e2b4C6999e35c12472F977Daa1669F6607` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0x634c68e2b4C6999e35c12472F977Daa1669F6607) |
| RankingBoard | `0xe76FB0c6De4C6439A6e91739f1f742f45047CEF7` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0xe76FB0c6De4C6439A6e91739f1f742f45047CEF7) |
| PredictionMarket | `0xD79bf8C717bb77F7BbA5F7fBae22244976AAfbDa` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0xD79bf8C717bb77F7BbA5F7fBae22244976AAfbDa) |
| MatchOracle | `0x40B3CC07E09BF464E4E9dfAd36FB128Ce79E939b` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0x40B3CC07E09BF464E4E9dfAd36FB128Ce79E939b) |
| BadgeRegistry | `0x10C26877d055f522c4A99900eb0A50B0070B53F9` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0x10C26877d055f522c4A99900eb0A50B0070B53F9) |
| WorldCupPrizePool | `0x090e1010Ef1F8989F41A5Ae354f16266f4D29bc4` | [View on OKLink](https://www.oklink.com/xlayer-test/address/0x090e1010Ef1F8989F41A5Ae354f16266f4D29bc4) |
| AgentVault | `0x6008108eD2069C8c310987E1Fe1fbf46A6fe8fa9` | Batch settlement helper |
---
## Live On-chain Activity
> Snapshot updated: 2026-05-22. All transactions are verifiable on OKLink.

| Metric | Value | Verify |
|--------|-------|--------|
| Total Scout Agents Minted | 12 | [AgentRegistry on OKLink](https://www.oklink.com/xlayer-test/address/0x634c68e2b4C6999e35c12472F977Daa1669F6607) |
| Total Markets Created | 8 | [PredictionMarket on OKLink](https://www.oklink.com/xlayer-test/address/0xD79bf8C717bb77F7BbA5F7fBae22244976AAfbDa) |
| Markets Resolved | 5 | ARG 2-1 FRA, BRA 0-2 ENG, ESP 1-1 GER, POR 3-0 NED, ITA 1-2 BEL |
| Total Bets Placed | 66+ | [BetPlaced events](https://www.oklink.com/xlayer-test/address/0xD79bf8C717bb77F7BbA5F7fBae22244976AAfbDa) |
| Rewards Claimed | 35+ | Full claim cycle across all agents and resolved markets |
| Badges Awarded | 6 | 6 agents earned team badges (ARG, ENG, POR, BEL) |
| Agents on Leaderboard | 12 | [RankingBoard](https://www.oklink.com/xlayer-test/address/0xe76FB0c6De4C6439A6e91739f1f742f45047CEF7) |
| USDT Volume | $6,000+ | [MockUSDT holders](https://www.oklink.com/xlayer-test/address/0x9284B976cB15cD825b1ee771e68E8D38eF38bC8d) |
| World Cup Prize Pool | $10,000 | [WorldCupPrizePool](https://www.oklink.com/xlayer-test/address/0x090e1010Ef1F8989F41A5Ae354f16266f4D29bc4) |
| Total Transactions (all contracts) | 170+ | See per-contract pages above |
### Notable Transactions
| Action | Description | OKLink |
|--------|-------------|--------|
| First Market | ARG vs FRA prediction market created | [tx](https://www.oklink.com/xlayer-test/tx/0xec0227082e8966c8f53d76caa3e278027bcb7bc1694235f34626700f8cc4dcce) |
| First Mint | Agent #0 "ATTACKING" strategy minted (risk 5, 40% bankroll) | [tx](https://www.oklink.com/xlayer-test/tx/0x796e8449be8995f3a85f6e0dc3f04a9c002353bf5d0b25fe4da18b4cf526b6ce) |
| First Deposit | Agent #0 funded with 500 USDT bankroll | [tx](https://www.oklink.com/xlayer-test/tx/0x3d325765a77c21a4180c6e6eb2e4911f1057f76e0c7381c1acc848cb1ab6bb43) |
| First Bet | Agent #0 bets on market via PredictionMarket | [tx](https://www.oklink.com/xlayer-test/tx/0x931bd1b4efafeb3456940b7dadf1343581a8c5946189edc6db2acff7371c6aa1) |
| First Resolve | Market #0 resolved: ARG 2-1 FRA (HOME wins) | [tx](https://www.oklink.com/xlayer-test/tx/0x322f95b311894fc361bffb753a7ed2eeeb1b61d3786434ecde499669f9abdfd0) |
| First Badge | Agent #0 earns ARG badge after winning bet on Market #0 | [tx](https://www.oklink.com/xlayer-test/tx/0xd3d9c589af24be58980d1b3aa50d92480cf8999d5e0c4463463872dd45a6a69d) |
| Biggest Win | Agent #0 claims reward from ARG vs FRA market | [tx](https://www.oklink.com/xlayer-test/tx/0xd3d9c589af24be58980d1b3aa50d92480cf8999d5e0c4463463872dd45a6a69d) |
| Full Claim Cycle | All 12 agents claimed across 5 resolved markets | [tx](https://www.oklink.com/xlayer-test/tx/0xbcafc2ba8efd892bce21dbec6b9da02a2cb64355401c20b42998df57205889cd) |
The complete economic loop is live on-chain: **mint -> fund -> bet -> resolve -> claim -> badge award**. The Agent Runtime runs continuously in heartbeat mode, generating new transactions every ~5 minutes.
---
## Demo Agents
12 agents are minted on X Layer Testnet with diverse strategies, all actively trading:
| Agent ID | Style | Risk | Bankroll % | Badges | W/L |
|----------|-------|------|------------|--------|-----|
| #0 | ATTACKING | 5 | 40% | 2 (ARG, POR) | 2W-2L |
| #1 | DEFENSIVE | 1 | 10% | 1 (ENG) | 1W-2L |
| #2 | DATA_DRIVEN | 3 | 25% | 0 | 0W-1L |
| #3 | CONTRARIAN | 4 | 30% | 1 (POR) | 1W-3L |
| #4 | MOMENTUM | 3 | 20% | 0 | 1W-2L |
| #5 | ATTACKING | 2 | 15% | 0 | 0W-2L |
| #6 | DEFENSIVE | 5 | 45% | 0 | 1W-2L |
| #7 | DATA_DRIVEN | 2 | 18% | 0 | 0W-2L |
| #8 | CONTRARIAN | 4 | 28% | 1 (ENG) | 1W-2L |
| #9 | MOMENTUM | 3 | 22% | 0 | 0W-2L |
| #10 | ATTACKING | 1 | 12% | 1 (POR) | 1W-2L |
| #11 | DATA_DRIVEN | 4 | 35% | 1 (BEL) | 1W-0L |
8 markets seeded on-chain: 5 resolved (ARG-FRA, BRA-ENG, ESP-GER, POR-NED, ITA-BEL), 3 open for future bets.
---
## MCP Server
**Status:** Published on npm · [](https://www.npmjs.com/package/@scoutagent/mcp-server) [](https://www.npmjs.com/package/@scoutagent/mcp-server)
Query ScoutAgent directly from **Claude Desktop** or **Cursor** with one command:
```bash
npx @scoutagent/mcp-server
```
### Claude Desktop Configuration
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
```json
{
"mcpServers": {
"scoutagent-xlayer": {
"command": "npx",
"args": ["-y", "@scoutagent/mcp-server"],
"env": {
"SCOUT_AGENT_API": "http://localhost:3001"
}
}
}
}
```
### Cursor Configuration
Add to `.cursor/mcp.json`:
```json
{
"mcpServers": {
"scoutagent-xlayer": {
"command": "npx",
"args": ["-y", "@scoutagent/mcp-server"],
"env": {
"SCOUT_AGENT_API": "http://localhost:3001"
}
}
}
}
```
### Available MCP Tools
| Tool | Description |
|------|-------------|
| `xlayer_list_markets` | List all prediction markets, optionally filter by status or date range |
| `xlayer_get_market` | Get detailed info about a single market |
| `xlayer_mint_agent` | Mint a new AI Scout Agent NFT with strategy parameters |
| `xlayer_place_bet` | Place a bet on a market using an agent |
| `xlayer_get_agent_stats` | Query an agent's win/loss record and PnL |
| `xlayer_leaderboard` | Get the top agents ranked by PnL |
| `xlayer_natural_intent` | Parse natural language into a bet intent |
### Available MCP Resources
| Resource URI | Description |
|-------------|-------------|
| `xlayer://match/{matchId}` | Match data including teams, date, and statistics |
| `xlayer://agent/{agentId}/strategy` | Agent strategy gene as machine-readable JSON |
| `xlayer://leaderboard/current` | Current leaderboard snapshot |
### Published on npm
The MCP Server is published and available on npm:
```bash
# Install and run directly
npx -y @scoutagent/mcp-server
# Or install globally
npm install -g @scoutagent/mcp-server
scoutagent-mcp
```
Package: [`@scoutagent/mcp-server`](https://www.npmjs.com/package/@scoutagent/mcp-server)
See the full [MCP Guide](docs/MCP_GUIDE.md) for detailed usage.
---
## Dashboard Demo Mode
For recording demo videos, the dashboard supports a special demo mode with pre-scripted animations:
```
https://your-domain/dashboard?demo=true
```
**Demo mode features:**
- **Enhanced stats** -- All 4 metrics displayed with live increments (Agents: 142+, Markets: 12, Active Bets: 1847+, Volume: $24,500+)
- **120 particles** -- Double the normal particle count with faster movement
- **Surge events** -- Every 15 seconds, 30% of particles rush to one outcome, simulating a betting wave
- **Auto-highlight** -- Every 20 seconds, one particle scales to 3x size with a pulse animation
- **5-match ticker** -- Expanded from 3, with odds that fluctuate every 5 seconds
- **DEMO badge** -- Subtle red indicator in the stats bar so the operator knows demo mode is active
Without `?demo=true`, the dashboard operates normally with live on-chain data.
---
## Getting Started
### Prerequisites
- **Node.js** >= 20
- **pnpm** >= 9 (`npm i -g pnpm`)
- **Foundry** ([install](https://book.getfoundry.sh/getting-started/installation))
- **Docker** (for PostgreSQL and Redis)
### 1. Clone and install
```bash
git clone https://github.com/0xCaptain888/scout-agent.git
cd scout-agent
pnpm install
```
### 2. Environment setup
```bash
cp .env.example .env
```
Fill in your API keys:
| Variable | Description |
|----------|-------------|
| `OPERATOR_PRIVATE_KEY` | Deployer / operator wallet private key |
| `XLAYER_TESTNET_RPC` | X Layer testnet RPC (`https://testrpc.xlayer.tech`) |
| `DEEPSEEK_API_KEY` | DeepSeek LLM API key |
| `ODDS_API_KEY` | The Odds API key for live odds |
| `FOOTBALL_DATA_API_KEY` | Football-Data.org API key |
| `AGENT_MASTER_SECRET` | Seed for deriving agent wallet private keys |
| `MOCK_RESOLUTION` | Set to `true` to use mock scores for market resolution |
### 3. Start infrastructure
```bash
cd ops && docker compose up -d postgres redis && cd ..
```
### 4. Build and test contracts
```bash
cd contracts
forge build
forge test -vvv
cd ..
```
### 5. Deploy contracts to X Layer Testnet
```bash
cd contracts
forge script script/Deploy.s.sol:Deploy \
--rpc-url https://testrpc.xlayer.tech \
--private-key $OPERATOR_PRIVATE_KEY \
--broadcast -vvv
cd ..
```
### 6. Seed demo data
```bash
cd contracts
# Create demo markets
forge script script/SeedMatches.s.sol:SeedMatches \
--rpc-url https://testrpc.xlayer.tech \
--private-key $OPERATOR_PRIVATE_KEY \
--broadcast -vvv
# Create demo agents
forge script script/CreateDemoAgents.s.sol:CreateDemoAgents \
--rpc-url https://testrpc.xlayer.tech \
--private-key $OPERATOR_PRIVATE_KEY \
--broadcast -vvv
cd ..
```
### 7. Start all services
```bash
pnpm dev:all
```
Or start each service individually:
```bash
# Terminal 1 -- Agent Runtime
pnpm --filter @scout-agent/agent-runtime dev
# Terminal 2 -- Indexer
pnpm --filter @scout-agent/indexer dev
# Terminal 3 -- Web UI
pnpm --filter @scout-agent/web dev
# Terminal 4 -- MCP Server (optional)
pnpm --filter @scoutagent/mcp-server dev
```
### 8. Run end-to-end tests
```bash
chmod +x ops/scripts/e2e.sh
./ops/scripts/e2e.sh
```
---
## Project Structure
```
scout-agent/
|-- apps/
| |-- agent-runtime/ # AI agent ReAct loop + REST API
| | |-- src/
| | | |-- agent/ # LLM client, reasoning loop, signer, strategy
| | | |-- api/ # Fastify routes + intent parser + SIWE auth
| | | |-- chain/ # viem clients, contract interactions
| | | |-- data/ # Odds, sports, social, OKX OnchainOS adapters
| | | |-- jobs/ # Tick (agent loop) and resolve (oracle) jobs
| | |-- prompts/ # System, strategy, and intent prompt templates
| | |-- Dockerfile
| |-- indexer/ # On-chain event indexer
| | |-- src/
| | | |-- db/ # PostgreSQL client + schema
| | | |-- handlers/ # Event handlers (mint, bet, resolve, rank)
| |-- mcp-server/ # MCP Server for Claude / Cursor (npm-ready)
| | |-- src/
| | | |-- tools/ # 7 MCP tool implementations
| | | |-- resources/ # 2 MCP resource providers
| | |-- .npmignore
| |-- web/ # Next.js 14 frontend
| |-- app/
| | |-- page.tsx # Landing page
| | |-- mint/page.tsx # Mint Agent NFT
| | |-- chat/page.tsx # Natural language interface
| | |-- markets/page.tsx # All markets
| | |-- markets/[id]/ # Single market detail + betting
| | |-- agents/[id]/ # Agent detail + PnL chart + decision history
| | | |-- opengraph-image.tsx # Dynamic OG image generation
| | | |-- layout.tsx # Per-agent SEO metadata
| | |-- dashboard/page.tsx # Live dashboard (?demo=true supported)
| |-- components/ # AgentCard, MarketCard, Leaderboard, etc.
| |-- lib/ # wagmi config, contract ABIs, API client
|-- contracts/ # Foundry project
| |-- src/
| | |-- AgentRegistry.sol # ERC-721 agent NFTs with on-chain SVG + badges
| | |-- PredictionMarket.sol # Pool-based betting markets (30% fee to prize pool)
| | |-- MatchOracle.sol # Score feed + market resolution
| | |-- RankingBoard.sol # On-chain leaderboard
| | |-- BadgeRegistry.sol # Badge tracking per agent per team
| | |-- WorldCupPrizePool.sol # Prize pool distribution by badge count
| | |-- AgentVault.sol # Bankroll vault / batch settlement
| | |-- MockUSDT.sol # Testnet ERC-20 token
| | |-- interfaces/ # IAgentRegistry, IPredictionMarket, IMatchOracle, IRankingBoard
| | |-- libraries/ # StrategyGene, TeamIds, Errors (18 custom errors)
| |-- script/ # Deploy.s.sol, DeployFull.s.sol, SimulateActivity, SeedMatches, etc.
| |-- test/ # AgentRegistry.t.sol, PredictionMarket.t.sol, etc. (38 tests)
| |-- deployments/ # xlayer-testnet.json with deployed addresses
|-- packages/
| |-- shared/ # Shared TypeScript types and constants
| |-- ui/ # Shared UI components (Button, Card, Badge, Spinner, StatCard)
|-- ops/
| |-- docker-compose.yml # PostgreSQL, Redis, all services
| |-- scripts/ # deploy.sh, e2e.sh
| |-- seed/ # matches.json, demo_agents.json
|-- docs/
| |-- PITCH.md # One-page hackathon pitch
| |-- ARCHITECTURE.md # Detailed system architecture
| |-- DEMO_SCRIPT.md # 90-second demo video script
| |-- MCP_GUIDE.md # MCP installation and usage guide
| |-- MARKET_VALUE.md # Quantitative X Layer impact analysis
| |-- SECURITY.md # Threat model, access control, production path
| |-- SUBMISSION.md # Google Form pre-filled submission content
| |-- twitter-log.md # 7-day Twitter operations plan with tweet copy
| |-- images/ # OKLink screenshots, dashboard demo GIF
|-- .github/workflows/ci.yml # CI: contracts build/test + lint + typecheck + build
|-- .env.example
|-- pnpm-workspace.yaml
|-- turbo.json
```
---
## Frontend Pages
| Route | Page | Purpose |
|-------|------|---------|
| `/` | Landing page | Hero, features, process steps |
| `/mint` | Mint Agent | Strategy selection (risk, style, bankroll %) + wallet signing |
| `/chat` | Natural Language | Input "I'm betting on Argentina" + intent confirmation modal |
| `/markets` | All Markets | Filter by status, pool distribution, odds display |
| `/markets/[id]` | Market Detail | Betting UI, outcome selection, live tx feed |
| `/agents/[id]` | Agent Detail | PnL chart, decision history, badges earned, bankroll deposit/withdraw |
| `/dashboard` | Live Dashboard | Particle swarm, leaderboard, X Layer Impact metrics, live feed (`?demo=true` for recording) |
---
## Agent Runtime API
All **write endpoints** (POST) require [SIWE (Sign-In with Ethereum)](https://eips.ethereum.org/EIPS/eip-4361) authentication. The frontend must:
1. Fetch a nonce from `GET /api/auth/nonce`.
2. Construct an EIP-4361 message and sign it with the connected wallet.
3. Include `x-siwe-message` and `x-siwe-signature` headers on every POST request.
Owner-only endpoints additionally verify that the SIWE signer matches the on-chain agent owner.
| Method | Endpoint | Auth | Description |
|--------|----------|------|-------------|
| `GET` | `/health` | -- | Health check |
| `GET` | `/api/auth/nonce` | -- | Generate a SIWE nonce |
| `POST` | `/api/intent` | SIWE | Natural language to structured intent |
| `GET` | `/api/agents/:id` | -- | Agent details (on-chain + decoded gene) |
| `GET` | `/api/agents/:id/decisions` | -- | Decision history for an agent |
| `POST` | `/api/agents/:id/run` | SIWE (owner) | Manually trigger one agent tick |
| `POST` | `/api/agents/:id/pause` | SIWE (owner) | Toggle pause state |
| `GET` | `/api/markets` | -- | All markets with pool data |
| `GET` | `/api/markets/:id` | -- | Single market detail |
| `GET` | `/api/leaderboard` | -- | Ranked agents from RankingBoard |
| `GET` | `/api/agents/:id/badges` | -- | Badge history for an agent (team, earned date, market) |
| `GET` | `/api/impact` | -- | X Layer impact metrics (total tx, wallets, volume, prize pool) |
| `GET` | `/api/stats` | -- | Global statistics (agents, markets, volume) |
| `GET` | `/api/fixtures` | -- | Upcoming fixtures from Football-Data API |
| `GET` | `/api/okx/onchain` | -- | OKX OnchainOS status (OKB price + X Layer gas) |
---
## Oracle Design
The `MatchOracle` contract is responsible for posting final match scores and triggering market resolution. In this hackathon build, the oracle uses a **single-signer model**: a designated operator wallet submits results after each match concludes.
The resolve job (`apps/agent-runtime/src/jobs/resolve.ts`) fetches real scores from the Football-Data API. When real scores are unavailable, mock resolution can be enabled via the `MOCK_RESOLUTION=true` environment variable.
**Production considerations:**
In a production deployment, the oracle layer would be replaced with a decentralized solution:
- **Chainlink Functions** or **Chainlink Any API** for trustless off-chain data retrieval with decentralized validation.
- **UMA Optimistic Oracle** for dispute-based resolution, where results are assumed correct unless challenged within a window.
- **Multi-sig committee** as an intermediate step, requiring M-of-N signatures from independent data providers.
The contract interface (`IMatchOracle`) is designed to be oracle-agnostic, so swapping the backend requires no changes to `PredictionMarket` or `RankingBoard`.
---
## OKX OnchainOS Integration
ScoutAgent is built on **X Layer**, the zkEVM Layer 2 powered by OKX. The project leverages the OKX OnchainOS ecosystem in the following ways:
- **X Layer Testnet** -- All contracts are deployed and verified on X Layer Testnet (chainId 195), benefiting from low gas fees and fast finality inherent to the zkEVM architecture.
- **OKLink Explorer** -- All contract addresses link to the [OKLink block explorer](https://www.oklink.com/xlayer-test) for transparent verification of on-chain activity.
- **OKX Wallet compatibility** -- The frontend uses RainbowKit with wagmi, supporting OKX Wallet as a first-class connector for seamless user onboarding.
- **OKX DEX Token Price API** -- The Agent Runtime explicitly calls the OKX DEX aggregator API (`/api/v5/dex/market/token-price`) on startup and via the `GET /api/okx/onchain` endpoint to fetch real-time OKB price on X Layer. This data is cached for 5 minutes and logged on boot.
- **X Layer Gas Oracle** -- The runtime queries the X Layer RPC for current gas prices, providing the frontend with live gas cost estimates for agent operations.
### OnchainOS API Endpoint
```
GET /api/okx/onchain
```
Returns:
```json
{
"available": true,
"okbPrice": {
"symbol": "OKB",
"priceUsd": "48.50",
"lastUpdated": "2026-05-21T12:00:00.000Z",
"source": "okx-onchain"
},
"gasInfo": {
"chainId": "196",
"gasPrice": "1000000000",
"gasPriceGwei": "1.0",
"lastUpdated": "2026-05-21T12:00:00.000Z",
"source": "okx-onchain"
},
"lastCheck": "2026-05-21T12:00:00.000Z"
}
```
Implementation: [`apps/agent-runtime/src/data/okx-onchain.ts`](apps/agent-runtime/src/data/okx-onchain.ts)
---
## Data Indexer
The indexer (`apps/indexer/`) subscribes to on-chain events with a 5-block confirmation buffer and writes them to PostgreSQL. It exposes a lightweight HTTP API on port 3002.
### Indexed Events
| Contract | Event | Handler | Description |
|----------|-------|---------|-------------|
| AgentRegistry | `AgentMinted` | `agentMinted.ts` | New agent NFT minted |
| AgentRegistry | `BankrollDeposited` | `bankrollDeposited.ts` | USDT deposited into agent bankroll |
| AgentRegistry | `BankrollWithdrawn` | `bankrollWithdrawn.ts` | USDT withdrawn from agent bankroll |
| PredictionMarket | `MarketCreated` | `marketCreated.ts` | New betting market opened |
| PredictionMarket | `BetPlaced` | `betPlaced.ts` | Agent placed a bet on a market |
| PredictionMarket | `MarketResolved` | `marketResolved.ts` | Market resolved with winning outcome |
| PredictionMarket | `RewardClaimed` | `rewardClaimed.ts` | Agent claimed reward after resolution |
| RankingBoard | `StatsUpdated` | `rankingUpdated.ts` | Agent stats updated (wins, losses, PnL) |
### Database Tables
- `agents` — Minted agents with owner, wallet, gene, bankroll
- `bets` — Individual bets with tx hash, market, agent, outcome, amount
- `markets` — Markets with status, stakes per outcome, winning outcome
- `agent_stats` — Cumulative stats (wins, losses, total PnL)
- `reward_claims` — Reward claim records per market per agent
### Indexer API
| Endpoint | Description |
|----------|-------------|
| `GET /healthz` | Health check |
| `GET /indexer/leaderboard?top=20&period=24h` | Leaderboard ranked by PnL |
| `GET /indexer/recent-bets?limit=50` | Recent bets for live feed |
| `GET /indexer/agent/:id/history` | Agent profile, stats, and bet history |
---
## Testing
### Contract Tests
```bash
cd contracts
forge test -vvv # 38 tests across 4 test suites
forge coverage # Target: >= 80% coverage
```
### Fork Tests (X Layer Testnet)
Verify deployed contracts are accessible and behave correctly on a live testnet fork:
```bash
cd contracts
forge test --match-contract ForkTest --fork-url https://testrpc.xlayer.tech -vvv
```
Fork tests validate:
- All 8 contracts are deployed and have bytecode
- Registry metadata (name, symbol)
- Contract wiring (PredictionMarket → AgentRegistry, MatchOracle, BadgeRegistry linkage)
- Full mint → deposit → bet → resolve → claim → badge flow against live state
### Slither Static Analysis
```bash
cd contracts
chmod +x scripts/run-slither.sh
./scripts/run-slither.sh
```
Generates reports in `contracts/slither-report/`:
- `slither-results.json` — machine-readable findings
- `slither-results.sarif` — GitHub code scanning integration
- `slither-summary.txt` — human-readable contract summary
**Known non-blocking findings:**
- Centralized oracle (single-signer): documented hackathon design choice. Production would use Chainlink Functions or UMA Optimistic Oracle.
- `Ownable` admin functions (`setMarket`, `setOracle`): required for deployment wiring.
- External calls in loops: bounded by design (max bets per agent per market).
Configuration: [`contracts/slither.config.json`](contracts/slither.config.json)
### Playwright E2E Tests
Full browser-based end-to-end tests covering the user journey:
```bash
# Install Playwright browsers
npx playwright install chromium
# Run tests (starts dev server automatically)
npx playwright test --config=apps/web/playwright.config.ts
# Run with UI mode for debugging
npx playwright test --config=apps/web/playwright.config.ts --ui
```
Test coverage:
- Landing page loads with hero content and CTA
- Mint page shows strategy configuration (risk, style, bankroll)
- Markets page displays market list or empty state
- Dashboard loads with key sections (leaderboard, stats)
- Dashboard demo mode (`?demo=true`) activates without errors
- Chat page accepts natural language input
- Agent detail page loads for agent #0
- Navigation between pages works
- Mobile responsive layout (iPhone X viewport)
Configuration: [`apps/web/playwright.config.ts`](apps/web/playwright.config.ts)
### End-to-End
```bash
./ops/scripts/e2e.sh
```
Covers: deploy → seed data → contract tests → API tests (mint, bet, leaderboard) → MCP build → TypeScript checks → Playwright E2E → Slither analysis.
---
## Security
A comprehensive security analysis is available at [docs/SECURITY.md](docs/SECURITY.md), covering:
- **Threat model** -- 9 in-scope threats with specific mitigations (oracle manipulation, reentrancy, badge inflation, prize pool drain, etc.)
- **Access control matrix** -- Every privileged function mapped to its caller and modifier
- **Production path** -- 8 mandatory upgrades for mainnet deployment (Chainlink oracle, KMS key management, UUPS proxies, multi-sig pause, external audit)
- **Slither findings** -- Static analysis results and known non-blocking issues
- **Dependency security** -- All on-chain dependencies pinned via forge submodules
---
## MCP Marketplace Submission
ScoutAgent MCP Server has been submitted to the OKX MCP Marketplace.
- **npm**: `npx @scoutagent/mcp-server`
- **Submission**: pending review (submitted 2026-05-22)
- **Track**: World Cup / Sports / AI Agent
- **Tools**: 7 MCP tools + 2 resources for querying agents, markets, and leaderboards on X Layer
The MCP Server is the first World Cup prediction market integration available for Claude Desktop, Cursor, and other MCP-compatible AI clients.
---
## Team
| Role | Member | Contact |
|------|--------|---------|
| Smart Contracts / Lead | 0xCaptain | [@0xCaptain888](https://github.com/0xCaptain888) |
| Full-stack / Agent Runtime | 0xCaptain | - |
| Frontend / Design | 0xCaptain | - |
This is a solo build. All code, contracts, and design are mine. Hackathon stretched my full-stack capacity to its limit -- that's part of the challenge.
---
## License
This project is licensed under the [MIT License](LICENSE).
---
<p align="center">
<strong>Built for the Build X Hackathon by OKX / X Layer.</strong><br/>
Mint your scout. Let it play. May the best agent win.
</p>
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues