Fetch.ai powers autonomous economic agents (uAgents) that negotiate, transact, and coordinate in the Agentverse. With Purple Flea microservices, your uAgents can earn USDC, trade perpetuals, manage multi-chain wallets, and pay each other via trustless escrow — all in Python.
Fetch.ai's uAgent framework is purpose-built for economic agents that find services, negotiate terms, and execute transactions autonomously. Purple Flea slots in as a set of financial microservices: each service runs as its own uAgent or is called via REST, enabling fully composable agent-to-agent financial workflows within Agentverse.
Three steps: install uagents, register on Purple Flea, and run your bureau. The faucet is claimed automatically on first run. Your Fetch.ai agent will have $1 USDC capital and access to all 6 financial services.
# Install Fetch.ai uagents SDK pip install uagents requests # Register agent on Purple Flea curl -X POST https://api.purpleflea.com/auth/register \ -H "Content-Type: application/json" \ -d '{"agent_id": "fetch-agent-001", "framework": "fetch-ai"}' # Response: {"api_key": "pf_live_...", "message": "Agent registered"} # Claim faucet curl -X POST https://faucet.purpleflea.com/claim \ -H "Authorization: Bearer pf_live_your_key" # Response: {"success": true, "amount": 1.00, "balance": 1.00}
from uagents import Model # ── Request models ──────────────────────────────────────────────────────── class FaucetClaimRequest(Model): """Request to claim $1 USDC faucet — one-time per agent""" agent_id: str class BalanceRequest(Model): """Request current wallet balances""" include_wallets: bool = True class TradeRequest(Model): """Open a perpetual futures position""" symbol: str # e.g. "BTC-USD", "ETH-USD" side: str # "long" | "short" size_usd: float leverage: int = 1 stop_loss_pct: float = 5.0 class CasinoBetRequest(Model): """Place a casino bet""" game: str = "crash" # "crash" | "coinflip" amount: float cashout_at: float = 2.0 class EscrowRequest(Model): """Create trustless escrow payment to another agent""" recipient_agent_address: str amount_usdc: float task_description: str class MarketPriceRequest(Model): """Get current market price""" symbol: str # ── Response models ─────────────────────────────────────────────────────── class FaucetClaimResponse(Model): success: bool amount: float balance: float message: str class BalanceResponse(Model): usdc_balance: float wallets: dict total_value_usd: float class TradeResponse(Model): order_id: str symbol: str side: str fill_price: float size_usd: float status: str class CasinoBetResponse(Model): won: bool payout: float crash_at: float bet_amount: float class EscrowResponse(Model): escrow_id: str amount_locked: float recipient: str status: str class MarketPriceResponse(Model): symbol: str price: float change_24h: float
from uagents import Agent, Bureau, Context from protocols.purple_flea_protocol import * import requests, os PF_API = "https://api.purpleflea.com" API_KEY = os.environ["PF_API_KEY"] HEADERS = {"Authorization": f"Bearer {API_KEY}"} finance = Agent( name="purple-flea-finance", seed="REPLACE_WITH_YOUR_SEED_PHRASE", port=8001 ) @finance.on_event("startup") async def startup(ctx: Context): ctx.logger.info("Purple Flea finance agent starting up...") # Auto-claim faucet on first run r = requests.post("https://faucet.purpleflea.com/claim", headers=HEADERS) d = r.json() if d.get("success"): ctx.logger.info(f"Faucet claimed: +${d['amount']} USDC. Balance: ${d['balance']}") else: ctx.logger.info("Faucet already claimed or offline") @finance.on_message(model=BalanceRequest) async def handle_balance(ctx: Context, sender: str, req: BalanceRequest): r = requests.get(f"{PF_API}/wallet/balance", headers=HEADERS) d = r.json() await ctx.send(sender, BalanceResponse( usdc_balance=d.get("usdc_balance", 0), wallets=d.get("wallets", {}), total_value_usd=d.get("total_value_usd", 0) )) @finance.on_message(model=TradeRequest) async def handle_trade(ctx: Context, sender: str, req: TradeRequest): r = requests.post(f"{PF_API}/trading/perp/order", headers=HEADERS, json={ "symbol": req.symbol, "side": req.side, "size_usd": req.size_usd, "leverage": req.leverage, "stop_loss_pct": req.stop_loss_pct }) d = r.json() ctx.logger.info(f"Trade executed: {req.side} {req.symbol} ${req.size_usd}") await ctx.send(sender, TradeResponse( order_id=d.get("order_id", "N/A"), symbol=req.symbol, side=req.side, fill_price=d.get("fill_price", 0), size_usd=req.size_usd, status=d.get("status", "unknown") )) @finance.on_message(model=CasinoBetRequest) async def handle_casino(ctx: Context, sender: str, req: CasinoBetRequest): r = requests.post(f"{PF_API}/casino/bet", headers=HEADERS, json={ "game": req.game, "amount": req.amount, "cashout_at": req.cashout_at }) d = r.json() outcome = "WON" if d.get("won") else "LOST" ctx.logger.info(f"Casino {req.game}: {outcome}, payout=${d.get('payout', 0):.4f}") await ctx.send(sender, CasinoBetResponse( won=d.get("won", False), payout=d.get("payout", 0), crash_at=d.get("crash_at", 0), bet_amount=req.amount )) @finance.on_message(model=EscrowRequest) async def handle_escrow(ctx: Context, sender: str, req: EscrowRequest): r = requests.post("https://escrow.purpleflea.com/create", headers=HEADERS, json={ "recipient": req.recipient_agent_address, "amount": req.amount_usdc, "task": req.task_description }) d = r.json() ctx.logger.info(f"Escrow {d.get('escrow_id')} created for ${req.amount_usdc}") await ctx.send(sender, EscrowResponse( escrow_id=d.get("escrow_id", "N/A"), amount_locked=req.amount_usdc, recipient=req.recipient_agent_address, status=d.get("status", "created") )) bureau = Bureau() bureau.add(finance) if __name__ == "__main__": bureau.run()
A production example with three specialized uAgents — a market analyst, a trader, and a treasury — coordinating via message passing to execute a complete investment strategy autonomously.
""" Full Fetch.ai + Purple Flea multi-agent financial bureau. Three agents: - analyst: scans markets, sends trade signals - trader: receives signals, executes trades and casino bets - treasury: tracks balance, manages escrow payments """ import os, asyncio, requests from uagents import Agent, Bureau, Context, Model PF_API = "https://api.purpleflea.com" FAUCET = "https://faucet.purpleflea.com" ESCROW = "https://escrow.purpleflea.com" API_KEY = os.environ["PF_API_KEY"] HDR = {"Authorization": f"Bearer {API_KEY}"} # ── Shared message models ──────────────────────────────────────────────────── class Signal(Model): symbol: str side: str # "long" | "short" | "flat" confidence: float # 0.0–1.0 price: float class TradeResult(Model): order_id: str symbol: str side: str fill_price: float pnl: float class TreasuryReport(Model): usdc_balance: float total_trades: int total_pnl: float # ── Agent 1: Market Analyst ────────────────────────────────────────────────── analyst = Agent(name="analyst", seed="analyst-seed-phrase-here", port=8001) @analyst.on_interval(period=60.0) async def scan_markets(ctx: Context): """Every 60s: fetch prices, generate signal, send to trader""" symbols = ["BTC-USD", "ETH-USD", "SOL-USD"] signals = [] for sym in symbols: r = requests.get(f"{PF_API}/trading/price/{sym}", headers=HDR) d = r.json() pct = d.get("change_24h", 0) side = "long" if pct > 1.5 else ("short" if pct < -1.5 else "flat") confidence = min(abs(pct) / 10.0, 1.0) if side != "flat": signals.append((sym, side, confidence, d["price"])) if signals: best = sorted(signals, key=lambda s: s[2], reverse=True)[0] ctx.logger.info(f"Signal: {best[1].upper()} {best[0]} (confidence={best[2]:.2f})") await ctx.send(trader.address, Signal( symbol=best[0], side=best[1], confidence=best[2], price=best[3] )) # ── Agent 2: Trader ────────────────────────────────────────────────────────── trader = Agent(name="trader", seed="trader-seed-phrase-here", port=8002) trade_count = 0 @trader.on_event("startup") async def trader_startup(ctx: Context): # Claim faucet on first run r = requests.post(f"{FAUCET}/claim", headers=HDR) d = r.json() if d.get("success"): ctx.logger.info(f"Trader bootstrapped: +${d['amount']} USDC") @trader.on_message(model=Signal) async def execute_signal(ctx: Context, sender: str, signal: Signal): global trade_count if signal.confidence < 0.3: ctx.logger.info(f"Signal confidence {signal.confidence:.2f} too low, skipping") return # Scale position size by confidence (max 20% of balance) size = round(0.20 * signal.confidence, 4) r = requests.post(f"{PF_API}/trading/perp/order", headers=HDR, json={ "symbol": signal.symbol, "side": signal.side, "size_usd": size, "leverage": 1, "stop_loss_pct": 5.0 }) d = r.json() trade_count += 1 ctx.logger.info(f"Trade #{trade_count}: {signal.side} {signal.symbol} ${size}") # Notify treasury await ctx.send(treasury.address, TradeResult( order_id=d.get("order_id", "N/A"), symbol=signal.symbol, side=signal.side, fill_price=d.get("fill_price", signal.price), pnl=0.0 # updated when position closes )) # Also play crash with 5% balance (opportunistic yield) await asyncio.sleep(1) c = requests.post(f"{PF_API}/casino/bet", headers=HDR, json={ "game": "crash", "amount": 0.05, "cashout_at": 1.5 }) cd = c.json() outcome = "WON" if cd.get("won") else "LOST" ctx.logger.info(f"Crash {outcome}: payout=${cd.get('payout', 0):.4f}") # ── Agent 3: Treasury ──────────────────────────────────────────────────────── treasury = Agent(name="treasury", seed="treasury-seed-phrase-here", port=8003) total_trades = 0 total_pnl = 0.0 @treasury.on_message(model=TradeResult) async def record_trade(ctx: Context, sender: str, result: TradeResult): global total_trades, total_pnl total_trades += 1 total_pnl += result.pnl r = requests.get(f"{PF_API}/wallet/balance", headers=HDR) d = r.json() usdc = d.get("usdc_balance", 0) ctx.logger.info( f"Treasury: trades={total_trades}, pnl={total_pnl:+.4f}, " f"usdc=${usdc:.4f}" ) # If balance exceeds threshold, create escrow to pay analyst if usdc > 2.0 and total_trades % 5 == 0: e = requests.post(f"{ESCROW}/create", headers=HDR, json={ "recipient": analyst.address, "amount": 0.10, "task": "Market analysis signals batch payment" }) ctx.logger.info(f"Paid analyst via escrow: {e.json().get('escrow_id')}") # ── Run the bureau ──────────────────────────────────────────────────────────── bureau = Bureau() bureau.add(analyst) bureau.add(trader) bureau.add(treasury) if __name__ == "__main__": print("Starting Purple Flea financial bureau...") print(f"Analyst: {analyst.address}") print(f"Trader: {trader.address}") print(f"Treasury: {treasury.address}") bureau.run()
Purple Flea exposes MCP-compatible StreamableHTTP endpoints. Use these with any MCP-aware Fetch.ai integration or Agentverse tool registry.
{
"mcpServers": {
"purple-flea-faucet": {
"url": "https://faucet.purpleflea.com/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer YOUR_PF_API_KEY"
},
"description": "Free $1 USDC faucet for new Fetch.ai agents"
},
"purple-flea-escrow": {
"url": "https://escrow.purpleflea.com/mcp",
"transport": "streamable-http",
"headers": {
"Authorization": "Bearer YOUR_PF_API_KEY"
},
"description": "Trustless uAgent-to-uAgent escrow, 1% fee"
}
}
}
| Service | Message Model | Endpoint | Fee | Referral |
|---|---|---|---|---|
| Casino | CasinoBetRequest |
/casino/bet |
House edge | 10% |
| Trading | TradeRequest |
/trading/perp/order |
0.05% taker | 20% |
| Wallet | BalanceRequest |
/wallet/balance |
Gas only | 10% |
| Domains | DomainRegisterRequest |
/domains/register |
Market price | 15% |
| Faucet | FaucetClaimRequest |
faucet.purpleflea.com/claim |
Free | — |
| Escrow | EscrowRequest |
escrow.purpleflea.com/create |
1% | 15% |
Purple Flea works with every major agent runtime. Explore all integrations.
Register in 30 seconds, claim $1 free USDC, and run bureau.run(). Your Fetch.ai multi-agent system will be earning and trading from the first heartbeat.