Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: CI / CD

on:
push:
branches:
- main
- 'copilot/**'
pull_request:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
# ────────────────────────────────────────────────────────────────
lint-and-type-check:
name: Lint & Type-check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4

- name: Set up Node 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint -- --max-warnings 0

# ────────────────────────────────────────────────────────────────
build:
name: Production Build
runs-on: ubuntu-latest
needs: lint-and-type-check
permissions:
contents: read
env:
# Provide stub env vars so Next.js can build without real secrets
NEXT_PUBLIC_SUPABASE_URL: https://placeholder.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY: placeholder_anon_key
NEXT_PUBLIC_STELLAR_NETWORK: testnet
NEXT_PUBLIC_HORIZON_URL: https://horizon-testnet.stellar.org
steps:
- uses: actions/checkout@v4

- name: Set up Node 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Upload build artefact
uses: actions/upload-artifact@v4
with:
name: next-build-${{ github.sha }}
path: .next/
retention-days: 7

# ────────────────────────────────────────────────────────────────
docker-build:
name: Docker Image Build
runs-on: ubuntu-latest
needs: build
permissions:
contents: read
# Only run on pushes to main (not on every PR)
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build Docker image (no push)
uses: docker/build-push-action@v6
with:
context: .
push: false
tags: agentforge:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max

# ────────────────────────────────────────────────────────────────
# Optional: deploy to Vercel via Vercel CLI when pushing to main
# Uncomment and add VERCEL_TOKEN / VERCEL_ORG_ID / VERCEL_PROJECT_ID
# to repository secrets.
#
# deploy-preview:
# name: Deploy to Vercel
# runs-on: ubuntu-latest
# needs: build
# if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-node@v4
# with:
# node-version: '20'
# cache: 'npm'
# - run: npm ci
# - run: npx vercel --prod --token=${{ secrets.VERCEL_TOKEN }}
# env:
# VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
# VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
50 changes: 50 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# ── Stage 1: deps ─────────────────────────────────────────────────────────────
FROM node:20-alpine AS deps
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci --omit=dev

# ── Stage 2: builder ───────────────────────────────────────────────────────────
FROM node:20-alpine AS builder
WORKDIR /app

COPY package.json package-lock.json ./
RUN npm ci

COPY . .

# Build-time env vars (override in docker-compose or CI)
ARG NEXT_PUBLIC_SUPABASE_URL
ARG NEXT_PUBLIC_SUPABASE_ANON_KEY
ARG NEXT_PUBLIC_STELLAR_NETWORK=testnet
ARG NEXT_PUBLIC_HORIZON_URL=https://horizon-testnet.stellar.org

ENV NEXT_PUBLIC_SUPABASE_URL=$NEXT_PUBLIC_SUPABASE_URL
ENV NEXT_PUBLIC_SUPABASE_ANON_KEY=$NEXT_PUBLIC_SUPABASE_ANON_KEY
ENV NEXT_PUBLIC_STELLAR_NETWORK=$NEXT_PUBLIC_STELLAR_NETWORK
ENV NEXT_PUBLIC_HORIZON_URL=$NEXT_PUBLIC_HORIZON_URL
ENV NEXT_TELEMETRY_DISABLED=1

RUN npm run build

# ── Stage 3: runner ────────────────────────────────────────────────────────────
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs \
&& adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]
82 changes: 74 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
# Agent Forge- 0x402/pubsub architect
# AgentForge — 0x402 / Pub/Sub AI Agent Marketplace

**Xylem** is a Web3-native AI agent marketplace and builder platform on the Stellar blockchain.
[![CI / CD](https://github.com/mesayanroy/0x402-pubsub/actions/workflows/ci.yml/badge.svg)](https://github.com/mesayanroy/0x402-pubsub/actions/workflows/ci.yml)

**AgentForge (Xylem)** is a Web3-native AI agent marketplace and builder platform on the Stellar blockchain.

## Overview

Users connect their Freighter wallet, build custom AI agents, monetize them on-chain, and every agent API request is metered and paid using the 0x402 AI-to-AI payment protocol.
Users connect their Freighter wallet, build custom AI agents, monetize them on-chain, and every agent API request is metered and paid using the 0x402 AI-to-AI payment protocol. A live trading dashboard lets users test their XLM on the Stellar DEX directly from the UI — no CLI required.

## Tech Stack

- **Frontend**: Next.js 14 (App Router), TypeScript, TailwindCSS, Framer Motion
- **Frontend**: Next.js 15 (App Router), TypeScript, TailwindCSS, Framer Motion
- **Wallet**: Stellar Freighter Wallet SDK (`@stellar/freighter-api`)
- **Blockchain**: Stellar network — smart contracts in Soroban (Rust)
- **Database**: Supabase (PostgreSQL)
- **AI Backends**: OpenAI GPT-4o-mini + Anthropic Claude Haiku
- **Payments**: 0x402 protocol for per-request payments in XLM
- **Realtime**: Ably pub/sub (optional) + Upstash QStash consumers
- **Containerisation**: Docker + Docker Compose

## Getting Started

Expand All @@ -31,14 +35,28 @@ Copy `.env.example` to `.env.local` and fill in your values:
cp .env.example .env.local
```

Key variables:

| Variable | Description |
|---|---|
| `NEXT_PUBLIC_SUPABASE_URL` | Supabase project URL |
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase anon key |
| `SUPABASE_SERVICE_ROLE_KEY` | Supabase service role key (server only) |
| `OPENAI_API_KEY` | OpenAI API key |
| `ANTHROPIC_API_KEY` | Anthropic API key |
| `ABLY_API_KEY` | Ably realtime key *(optional — gracefully disabled if absent)* |
| `QSTASH_TOKEN` | Upstash QStash token *(optional)* |
| `NEXT_PUBLIC_STELLAR_NETWORK` | `testnet` (default) or `mainnet` |
| `NEXT_PUBLIC_HORIZON_URL` | Stellar Horizon endpoint |

### 3. Set up Supabase

Run `supabase-schema.sql` in your Supabase SQL editor.

### 4. Run the development server

```bash
pnpm run dev
npm run dev
```

Open [http://localhost:3000](http://localhost:3000).
Expand All @@ -50,9 +68,10 @@ Open [http://localhost:3000](http://localhost:3000).
| `/` | Landing page with hero, stats, features |
| `/agents` | Browse all deployed agents (marketplace grid) |
| `/agents/[id]` | Agent detail with API docs, try it live, fork |
| `/build` | 3-step agent builder wizard |
| `/dashboard` | User dashboard: my agents, earnings in XLM |
| `/marketplace` | Featured + trending agents |
| `/build` | 3-step agent builder wizard (draft auto-saved to localStorage) |
| `/trading` | **Live trading page** — XLM/USDC chart, Breakout Lines, TP/SL, TVL, buy/sell, collateral, leverage, agent SDK templates |
| `/dashboard` | User dashboard: my agents, earnings in XLM, invoice stream |
| `/marketplace` | Featured + trending agents with owner profile links |
| `/docs` | Developer documentation + 0x402 guide |
| `/devs` | Developer hub: SDK snippets, webhooks |
| `/about` | About the project and architecture |
Expand All @@ -79,10 +98,57 @@ chmod +x contracts/deploy.sh
./contracts/deploy.sh
```

> **Contract IDs (Testnet)**
> | Contract | ID |
> |---|---|
> | AgentRegistry | *(set after first deploy — see `contracts/deploy.sh` output)* |

## Demo Agent IDs

| Agent | ID |
|---|---|
| DeFi Analyst | `1` |
| Code Review Bot | `2` |
| Smart Contract Auditor | `3` |
| XLM Trading Bot | `4` |
| Soroban Dev Assistant | `5` |

> These IDs are available in demo mode (no Supabase required). When Supabase is configured, agents receive a UUID.

## API Routes

- `POST /api/agents/create` — Deploy a new agent
- `GET /api/agents/list` — List public agents
- `GET /api/agents/[id]` — Get agent by ID
- `POST /api/agents/[id]/run` — Run agent (0x402)
- `POST /api/payment/verify` — Verify Stellar tx
- `GET /api/ably/token` — Ably auth token (returns 503 gracefully when not configured)

## Docker

Build and run with Docker Compose:

```bash
# Copy and fill in secrets
cp .env.example .env

# Build image and start services
docker compose up --build -d

# View logs
docker compose logs -f web
```

The `web` service listens on port **3000**. An optional `consumers` service runs the QStash background workers.

## CI / CD

The repository ships a GitHub Actions workflow at `.github/workflows/ci.yml`.

| Job | Trigger | What it does |
|---|---|---|
| `lint-and-type-check` | every push / PR | `next lint` + TypeScript checks |
| `build` | after lint passes | `next build`, uploads `.next/` artefact |
| `docker-build` | pushes to `main` | Builds Docker image (cached) |

To enable Vercel auto-deploy, uncomment the `deploy-preview` job and add `VERCEL_TOKEN`, `VERCEL_ORG_ID`, and `VERCEL_PROJECT_ID` to repository secrets.
Loading
Loading