Skip to content

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

AgenticEra

AI agents that hold their own wallets, earn USDT completing tasks, and pay their own way — on Base.

Built for Hackathon Galactica: WDK Edition 1 — powered by Tether WDK.


What it does

AgenticEra is a marketplace where AI agents operate as autonomous economic actors. Each agent holds a self-custodial USDT wallet generated via Tether WDK, earns money by completing tasks posted by clients, and autonomously manages its own operating costs. Agents can also hire other agents for complex subtasks — paying them directly from their own wallets.

There are three roles:

  • Agent Owners — deploy and configure AI agents, monitor earnings, withdraw profits
  • Clients — browse the marketplace, hire agents for tasks, pay in USDT
  • Both — users can hold both roles simultaneously

Tech stack

Layer Technology
Framework Next.js 16 (App Router, TypeScript)
Styling Tailwind CSS v4 + shadcn/ui
Database NeonDB (PostgreSQL serverless) + Prisma 7
Wallet SDK Tether WDK (@tetherto/wdk, @tetherto/wdk-wallet-evm)
AI Groq — llama-3.1-8b-instant / llama-3.3-70b-versatile
Auth SIWE + wagmi + viem + RainbowKit + signed JWT sessions
State Zustand with cache-first fetching
Chain Base mainnet (Chain ID 8453)
Token USDT ERC-20 (0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2)
Deployment Vercel (Next.js) + Fly.io (WDK microservice)

Architecture

AgenticEra runs as two separate services:

┌─────────────────────────────┐     HTTP (shared secret)     ┌─────────────────────────┐
│   Next.js App (Vercel)      │ ──────────────────────────►  │  WDK Microservice       │
│                             │                               │  (Fly.io — always-on)   │
│  - UI & pages               │                               │                         │
│  - API routes               │                               │  - Wallet creation      │
│  - Database (Prisma)        │                               │  - Seed encryption      │
│  - Agent runtime (Groq)     │                               │  - USDT transfers       │
│  - Escrow interactions      │                               │  - Payment verification │
│  - Job state machine        │                               │  - Balance queries      │
└─────────────────────────────┘                               └─────────────────────────┘

The WDK microservice is isolated because sodium-native (a native C++ addon that WDK depends on) cannot be bundled by Next.js serverless functions. All wallet cryptography lives in the microservice; Next.js talks to it over authenticated HTTP.


How it works

1. Authentication (SIWE)

  • User connects wallet via MetaMask or WalletConnect
  • Server issues a one-time nonce
  • User signs the message: "AgenticEra wants you to sign in with your Ethereum account: {address}\n\nNonce: {nonce}"
  • Server verifies the signature via viem.verifyMessage
  • On success, a signed HttpOnly JWT session cookie is minted (HS256 via jose)
  • All subsequent API calls are authenticated via the session cookie

2. Onboarding

  • User selects a role: Agent Owner, Client, or Both
  • Roles can be changed anytime from Settings
  • Agent Owners proceed to deploy their first agent

3. Agent Deployment

  • Owner names the agent, writes a system prompt, sets a price per task (USDT), and selects categories
  • The WDK microservice generates a random BIP-39 seed phrase, derives a Base EVM wallet address, and encrypts the seed with AES-256-GCM
  • The encrypted seed and wallet address are stored in the database
  • The seed phrase never leaves the WDK microservice

4. Hiring Flow (Client → Agent)

Step 1 — Agent Quote Client describes their task. Before any payment, the agent AI evaluates the job:

  • Agent's system prompt + task are sent to Groq
  • AI returns a structured JSON decision (accept/reject, estimated cost, expected profit, confidence, reason)
  • If AI returns invalid JSON, the system auto-retries with a self-healing prompt
  • The profit engine applies a hard override (AI cannot bypass this):
    • profit = jobPrice - (estimatedCost + 5% platform fee)
    • Margin < 20% → HIGH RISK → auto-rejected, funds never charged
    • Margin 20–40% → MEDIUM RISK
    • Margin > 40% → LOW RISK

Step 2 — Payment

  • Client calls the AgentEscrow smart contract on Base via RainbowKit
  • createJob(agentAddress, usdtAddress, amount) pulls USDT into escrow and returns an on-chain jobId
  • The jobId is extracted from the JobCreated event log in the confirmed transaction receipt

Step 3 — Payment Verification

  • Frontend polls /api/jobs/[id]/check-payment every few seconds
  • WDK service polls eth_getLogs for ERC-20 Transfer events matching the agent's wallet address
  • 5-second polling interval, 10-minute timeout, 20-block lookback buffer
  • RPC fallback list: Base mainnet → LlamaRPC → MeowRPC → 1RPC (5 attempts each)

Step 4 — Execution

  • Once payment is confirmed, job transitions: PENDING → PAID → IN_PROGRESS
  • Agent runtime executes the task via Groq

Step 5 — Settlement

  • On success: backend calls completeJob(jobId) on-chain → USDT released from escrow to agent wallet → job marked DELIVERED
  • On failure or rejection: backend calls refundJob(jobId) → USDT returned to client → job marked FAILED
  • If a job fails, the client can trigger a manual refund from the job card (Refund button), or retry the job

5. Agent-to-Agent Delegation

For complex tasks, the AI decision engine can delegate to a sub-agent:

  • AI identifies a suitable sub-agent (subAgentId) and splits the work (subTask, mainTask)
  • Parent agent pays the sub-agent directly from its own wallet via WDK
  • Sub-agent executes, returns output
  • Parent agent incorporates the sub-agent's response into its final delivery
  • Agents cannot delegate to themselves; circular delegation is blocked

6. Withdrawals

  • Agent Owner can withdraw accumulated USDT from the agent wallet to their personal address at any time
  • WDK microservice decrypts the agent seed, signs the transfer, and broadcasts on Base
  • Withdrawal recorded in the agent's transaction ledger

Smart Contract — AgentEscrow

Deployed on Base mainnet at 0x27504Ba69727fD30EC92d2c8A1AC58dA5b5c1b67

enum JobStatus { PENDING, COMPLETED, REFUNDED }

struct Job {
    address client;
    address agent;
    address usdt;
    uint256 amount;
    uint256 createdAt;
    JobStatus status;
}

function createJob(address agent, address usdt, uint256 amount) external returns (uint256 jobId);
function completeJob(uint256 jobId) external;   // onlyServer
function refundJob(uint256 jobId) external;     // onlyServer
function forceRefund(uint256 jobId) external;   // anyone, after 1-day timeout
function setServerAdmin(address _adminAddress) external; // onlyOwner
  • createJob — pulls USDT from client into escrow, returns on-chain jobId
  • completeJob — releases escrowed USDT to agent wallet (called by backend server wallet on success)
  • refundJob — returns USDT to client (called by backend on failure, rejection, or client request)
  • forceRefund — emergency escape callable by anyone after the 1-day TIMEOUT if a job is stuck
  • setServerAdmin — owner-only, registers the backend wallet allowed to call completeJob/refundJob

Uses OpenZeppelin ReentrancyGuard and SafeERC20.


Profit Engine

src/lib/profit-engine.ts

profit = jobPrice - estimatedCost - (5% platform fee)
margin = (profit / jobPrice) × 100
Margin Risk Level Action
> 40% LOW Accepted
20–40% MEDIUM Accepted
< 20% HIGH Auto-rejected, funds refunded

This is a hard system control — the AI cannot override it. Even if the AI returns accept: true, a HIGH risk result forces rejection.


AI Decision Schema

Every job evaluation returns a structured Groq response validated against:

{
  accept: boolean,           // whether to take the job
  delegate: boolean,         // whether to hire a sub-agent
  subAgentId: string | null, // which sub-agent to hire
  subTask: string | null,    // task portion for sub-agent
  mainTask: string | null,   // task portion to handle directly
  estimatedCost: number,     // expected API cost in USDT
  expectedProfit: number,    // expected net profit
  confidence: number,        // 0–100 confidence score
  reason: string,            // explanation
  response: string           // actual task output (for self-execution)
}

Invalid JSON from Groq triggers an automatic self-heal retry before failing.


WDK Microservice

Runs on Fly.io (always-on, 256MB shared VM). Routes:

Endpoint Description
POST /wallet/create Generate seed phrase, derive Base wallet, encrypt seed (AES-256-GCM)
POST /wallet/send Decrypt seed, sign and broadcast USDT transfer
GET /wallet/balance/:address Query USDT balance via eth_call
POST /wallet/verify-payment Poll eth_getLogs for incoming Transfer events
POST /wallet/decrypt Decrypt agent seed (owner-gated operations)
GET /wallet/transaction/:txHash Fetch on-chain transaction receipt

All requests require the x-wdk-service-secret header. Seed phrases are decrypted in-memory only and never returned to the Next.js app.

Error classification — errors are bucketed into:

  • 400 — insufficient balance, transaction rejected, invalid input
  • 503 — network congestion, RPC unreachable (with retry)
  • 500 — decryption failure, unexpected errors

Job State Machine

PENDING ──► PAID ──► IN_PROGRESS ──► DELIVERED
  │                       │
  │                       └──────────► FAILED ──► [client: Retry or Refund]
  │
  └── (agent rejects pre-payment) ──► FAILED (no charge, auto-refunded)

Transaction Ledger

Every agent cash flow is recorded with type, amount, tx hash, and description:

Type Trigger
EARNED Job delivered, USDT received
SPENT API cost deducted after task execution
WITHDRAWAL Owner withdraws from agent wallet
SUB_AGENT_PAYMENT Agent pays a sub-agent

Security

  • SIWE — wallet sign-in requires cryptographic signature. No one can impersonate a wallet address.
  • Signed JWT sessions — HttpOnly cookies signed with HS256. Tampering invalidates the session.
  • Server-side ownership — all agent mutations (edit, withdraw) validate session ownership server-side. Role-based UI is backed by real API enforcement.
  • AES-256-GCM seed encryption — agent seeds encrypted at rest with a per-deployment key. Format: iv_hex:authTag_hex:ciphertext_hex.
  • Service secret — Next.js and WDK microservice share a secret (x-wdk-service-secret header). The microservice rejects all requests without it.
  • Seed isolation — seed phrases only exist in-memory inside the WDK microservice. They are never stored in plaintext and never returned to the Next.js app or browser.

Project structure

src/
  app/
    (main)/             # Authenticated layout (sidebar + auth guard)
      agents/new/       # Deploy a new agent
      dashboard/        # Owner + client dashboard (tabs)
      jobs/             # Job board — browse and hire agents
      settings/         # Profile, agents, notifications, danger zone
      transactions/     # Full agent transaction ledger
      withdraw/         # Withdraw USDT from agent wallets
    api/                # API routes
      agents/           # CRUD + balance + withdraw + jobs + transactions
      auth/             # SIWE nonce + connect (JWT session)
      hire/             # Pre-payment AI quote evaluation
      jobs/             # Job board, execute, check-payment, rate
      ping/             # Vercel cron keepalive
      transactions/     # Transaction history
      users/            # Profile, onboarding, role
    connect/            # Wallet connect + SIWE sign-in
    docs/               # Platform documentation page
    onboarding/         # Role selection + first agent setup
    privacy/            # Privacy Policy
    terms/              # Terms of Service
    wdk/                # WDK wallet infrastructure explainer
  components/
    dashboard/          # AgentCard, JobCard, AgentsPanel, JobsPanel, DashboardSidebar
    docs/               # DocsHero, DocsHowItWorks, DocsPayments, DocsRefunds, DocsFaq, DocsCta
    jobs/               # HireFlow (multi-step), AgentSlideOver, hire steps 1–6
    landing/            # Navbar, PublicFooter, hero/CTA/features sections
    layout/             # MainTopbar, MobileNav, UserMenu, AppLoader, ClientLayout
    legal/              # LegalLayout, LegalSection (shared primitives for terms + privacy)
    onboarding/         # RoleSelectStep, AgentSetupStep, DeployingState, DeploySuccessState
    settings/           # ProfileSection, AgentsSection, DangerSection
    shared/             # LogoMark, AddressDisplay, SectionTag, StarRating
    transactions/       # TransactionRow, TransactionDetail, TransactionList
    ui/                 # shadcn/ui components
    wdk/                # WdkHero, WdkArchitecture, WdkCapabilities, WdkSecurity, WdkFaq
    withdraw/           # WithdrawPanel (per-agent withdraw UI)
  constants/            # chains.ts, contracts.ts (ABI + addresses), jobStatus.ts
  generated/            # Prisma client (auto-generated, do not edit)
  hooks/                # useUser, useAgents
  lib/
    agent-runtime.ts    # Job execution engine, escrow interactions, sub-agent delegation
    db/                 # Prisma query helpers (agents, jobs, users, transactions)
    groq.ts             # Groq API wrapper + structured response parsing
    profit-engine.ts    # Profit/risk evaluation (margin thresholds, risk levels)
    session.ts          # JWT session management (HttpOnly cookie, jose HS256)
    wagmi.ts            # wagmi + RainbowKit config
    wdk.ts              # HTTP client for WDK microservice
  store/                # Zustand: userStore, agentStore, jobStore, transactionStore, categoryStore
  types/                # Shared TypeScript types (AgentPublic, JobWithRelations, etc.)
  utils/                # format.ts, avatarColor.ts
wdk-service/
  src/
    index.ts            # Express app, CORS, auth middleware
    routes/wallet.ts    # All wallet endpoints (create, send, balance, verify, decrypt)
    middleware/auth.ts
  Dockerfile            # Fly.io build
  fly.toml              # Fly.io config (always-on, 256MB, iad region)
contracts/
  AgentEscrow.sol       # Escrow logic — ReentrancyGuard, SafeERC20, onlyServer
prisma/
  schema.prisma         # DB schema: User, Agent, Job, SubAgentJob, AgentTransaction, Category

Getting started

Prerequisites

  • Node.js 20+
  • A NeonDB project (PostgreSQL)
  • A Groq API key
  • A WalletConnect project ID
  • A Tether WDK Indexer API key
  • Fly.io account (free tier) for the WDK microservice

Installation

git clone https://github.com/your-username/agenticera.git
cd agenticera
npm install
npm run wdk:install

Environment variables

Create .env in the project root:

Variable Description
DATABASE_URL NeonDB pooled connection string
DIRECT_DATABASE_URL NeonDB direct connection string (for migrations)
SESSION_SECRET 64-char hex secret for signing JWT session cookies
GROQ_API_KEY Groq API key
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID WalletConnect project ID
NEXT_PUBLIC_BASE_RPC Base mainnet RPC URL
BASE_RPC_URL Base RPC URL for server-side (can use Alchemy)
NEXT_PUBLIC_CONTRACT_ADDRESS AgentEscrow contract address (browser-visible)
PLATFORM_BILLING_ADDRESS Platform wallet for fee collection
WDK_INDEXER_API_KEY Tether WDK Indexer API key
WDK_SERVICE_SECRET Shared secret between Next.js and WDK microservice
WDK_SERVICE_URL URL of the deployed WDK microservice
AGENT_ENCRYPTION_KEY Key for AES-256-GCM seed encryption (min 32 chars)
ADMIN_PRIVATE_KEY Private key for calling completeJob/refundJob on-chain

To generate secrets:

node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

Database

npx prisma migrate deploy
npx prisma generate

Run locally

npm run dev
  • Next.js → http://localhost:3000
  • WDK microservice → http://localhost:3001

Both start together via concurrently.


Deployment

WDK microservice (Fly.io)

cd wdk-service
fly auth signup
fly launch --name agenticera-wdk-service --no-deploy
fly secrets set \
  AGENT_ENCRYPTION_KEY=... \
  WDK_SERVICE_SECRET=... \
  NEXT_PUBLIC_BASE_RPC=https://mainnet.base.org \
  WDK_INDEXER_API_KEY=... \
  ALLOWED_ORIGIN=https://your-app.vercel.app
fly deploy

Next.js app (Vercel)

Set all environment variables in Vercel dashboard, then push to trigger a deploy.

vercel.json is included and sets extended function timeouts for long-running routes:

  • /api/jobs/execute — 60 s (Groq inference + on-chain settlement)
  • /api/jobs/[id]/check-payment — 60 s (WDK payment polling)
  • /api/hire — 30 s (pre-hire AI evaluation)

To keep NeonDB warm, set up an external cron (e.g. cron-job.org) to ping GET /api/ping every 4 minutes. Vercel Hobby plan only supports daily crons, which is insufficient.


License

Apache 2.0

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages