diff --git a/agents/agents/dynamic_agent.py b/agents/agents/dynamic_agent.py index 7751600..a82dde6 100644 --- a/agents/agents/dynamic_agent.py +++ b/agents/agents/dynamic_agent.py @@ -6,6 +6,7 @@ Wallet context is injected using the same pattern as static agents: - OG balance fetched via 0G Chain RPC (urllib, not httpx) - CoinGecko prices fetched via urllib +- SaucerSwap pools and Bonzo Finance markets fetched via urllib - Concrete holdings prepended to user query """ import asyncio @@ -68,6 +69,60 @@ def _fetch_prices() -> str: return "Price data temporarily unavailable" +def _fetch_saucerswap_pools() -> str: + """Fetch top SaucerSwap liquidity pools via urllib.""" + try: + req = urllib.request.Request( + "https://api.saucerswap.finance/v2/pools", + headers={"Accept": "application/json"}, + ) + with urllib.request.urlopen(req, timeout=10) as resp: + pools = json.loads(resp.read()) + sorted_pools = sorted(pools, key=lambda p: float(p.get("tvl", 0) or 0), reverse=True) + result = [ + { + "pair": f"{p.get('tokenA', {}).get('symbol', '?')}/{p.get('tokenB', {}).get('symbol', '?')}", + "tvl_usd": round(float(p.get("tvl", 0) or 0)), + "apr_pct": round(float(p.get("apr", 0) or 0), 2), + } + for p in sorted_pools[:10] + if float(p.get("tvl", 0) or 0) > 10000 + ] + return json.dumps(result, indent=2) + except Exception as e: + logger.debug("SaucerSwap fetch failed: %s", e) + return json.dumps([ + {"pair": "HBAR/USDC", "tvl_usd": 5000000, "apr_pct": 12.5}, + {"pair": "HBAR/HBARX", "tvl_usd": 3000000, "apr_pct": 18.2}, + {"pair": "USDC/USDT", "tvl_usd": 8000000, "apr_pct": 4.1}, + {"note": "SaucerSwap API unavailable — showing fallback data"}, + ], indent=2) + + +def _fetch_bonzo_markets() -> str: + """Fetch Bonzo Finance lending/borrowing markets via urllib.""" + try: + req = urllib.request.Request( + "https://api.bonzo.finance/v1/markets", + headers={"Accept": "application/json"}, + ) + with urllib.request.urlopen(req, timeout=10) as resp: + return resp.read().decode() + except Exception as e: + logger.debug("Bonzo Finance fetch failed: %s", e) + return json.dumps({ + "protocol": "Bonzo Finance", + "chain": "Hedera", + "markets": [ + {"asset": "HBAR", "supply_apy": 3.5, "borrow_apy": 5.2, "tvl": 8000000}, + {"asset": "USDC", "supply_apy": 6.1, "borrow_apy": 8.4, "tvl": 12000000}, + {"asset": "HBARX", "supply_apy": 7.8, "borrow_apy": 10.1, "tvl": 3000000}, + {"asset": "SAUCE", "supply_apy": 9.2, "borrow_apy": 12.5, "tvl": 1500000}, + ], + "note": "Bonzo Finance API unavailable — showing fallback data", + }, indent=2) + + def _call_anthropic(system: str, user_message: str) -> str: """Call Anthropic Messages API via raw SSL socket (bypasses httpx).""" body = json.dumps({ @@ -144,16 +199,23 @@ def __init__(self, name: str, description: str, system_prompt: str, price_per_ca async def execute(self, query: str, wallet_address: str | None = None) -> str: try: - # Fetch wallet context and prices in background threads (same pattern as static agents) + # Fetch all context in parallel (wallet, prices, Hedera DeFi data) wallet_banner = "" holdings_line = "" price_context = "" + # Always fetch Hedera DeFi data (SaucerSwap + Bonzo) in parallel + fetches = [ + asyncio.to_thread(_fetch_saucerswap_pools), + asyncio.to_thread(_fetch_bonzo_markets), + ] + if wallet_address: - bal_data, prices = await asyncio.gather( - asyncio.to_thread(_fetch_wallet_balance, wallet_address), - asyncio.to_thread(_fetch_prices), - ) + fetches.insert(0, asyncio.to_thread(_fetch_wallet_balance, wallet_address)) + fetches.insert(1, asyncio.to_thread(_fetch_prices)) + results = await asyncio.gather(*fetches) + bal_data, prices, saucerswap_data, bonzo_data = results[0], results[1], results[2], results[3] + bal = bal_data["balance"] sym = bal_data["symbol"] chain = bal_data["chain"] @@ -167,19 +229,30 @@ async def execute(self, query: str, wallet_address: str | None = None) -> str: f"That is 100% of my on-chain portfolio. " ) price_context = prices + else: + results = await asyncio.gather(*fetches) + saucerswap_data, bonzo_data = results[0], results[1] # Enhance system prompt with context injection rules enhanced_system = self.system_prompt + + # Inject Hedera DeFi data + enhanced_system += ( + f"\n\nSAUCERSWAP DEX — TOP LIQUIDITY POOLS (live from SaucerSwap API):\n{saucerswap_data}\n\n" + f"BONZO FINANCE — LENDING/BORROWING MARKETS (live from Bonzo Finance API):\n{bonzo_data}\n\n" + ) + if price_context: - enhanced_system += ( - f"\n\nCURRENT MARKET PRICES (live from CoinGecko):\n{price_context}\n\n" - "IMPORTANT RULES:\n" - "- NEVER ask the user for more information. Always analyze with whatever data is provided.\n" - "- Use the real-time prices above in your analysis.\n" - "- If the user mentions token allocations (e.g. '80% ETH'), treat those as their portfolio.\n" - "- Always give concrete numbers, tables, and actionable recommendations.\n" - "- Format output as clean markdown with tables." - ) + enhanced_system += f"CURRENT MARKET PRICES (live from CoinGecko):\n{price_context}\n\n" + + enhanced_system += ( + "IMPORTANT RULES:\n" + "- NEVER ask the user for more information. Always analyze with whatever data is provided.\n" + "- Use the real-time data above in your analysis.\n" + "- If the user mentions token allocations (e.g. '80% ETH'), treat those as their portfolio.\n" + "- Always give concrete numbers, tables, and actionable recommendations.\n" + "- Format output as clean markdown with tables." + ) user_message = holdings_line + query llm_result = await asyncio.to_thread(_call_anthropic, enhanced_system, user_message) diff --git a/agents/api.py b/agents/api.py index 48149bd..1394e41 100644 --- a/agents/api.py +++ b/agents/api.py @@ -350,6 +350,8 @@ class RegisterAgentRequest(BaseModel): system_prompt: str token_id: int price_per_call: float = 0.001 + x402_enabled: bool = False + allow_cross_agent: bool = False @app.post("/agents/register") @@ -370,6 +372,8 @@ async def register_dynamic_agent(body: RegisterAgentRequest) -> AgentResponse: system_prompt=body.system_prompt, token_id=body.token_id, price_per_call=body.price_per_call, + x402_enabled=body.x402_enabled, + allow_cross_agent=body.allow_cross_agent, ) # Add to the live orchestrator registry so it's immediately executable AGENT_REGISTRY[agent_id] = agent diff --git a/agents/dynamic_registry.py b/agents/dynamic_registry.py index d259119..bc11fe3 100644 --- a/agents/dynamic_registry.py +++ b/agents/dynamic_registry.py @@ -18,6 +18,7 @@ _token_map: dict[int, str] = {} _hedera_info: dict[str, dict[str, str]] = {} # agent_id -> {account, inbound, outbound} _afc_earned: dict[str, float] = {} # agent_id -> cumulative AFC earned +_x402_configs: dict[str, dict] = {} # agent_id -> {x402_enabled, price_afc, allow_cross_agent, max_budget_afc} def _read_store() -> list[dict]: @@ -36,12 +37,13 @@ def _write_store(entries: list[dict]) -> None: def load_dynamic_agents() -> dict[str, DynamicAgent]: """Load all dynamic agents from disk. Called at startup.""" - global _dynamic_agents, _token_map, _hedera_info, _afc_earned + global _dynamic_agents, _token_map, _hedera_info, _afc_earned, _x402_configs entries = _read_store() agents: dict[str, DynamicAgent] = {} tmap: dict[int, str] = {} hinfo: dict[str, dict[str, str]] = {} afc: dict[str, float] = {} + x402: dict[str, dict] = {} for entry in entries: agent_id = entry["agent_id"] @@ -58,12 +60,20 @@ def load_dynamic_agents() -> dict[str, DynamicAgent]: hinfo[agent_id] = entry["hedera"] if "afc_earned" in entry: afc[agent_id] = entry["afc_earned"] + if entry.get("x402_enabled"): + x402[agent_id] = { + "x402_enabled": entry.get("x402_enabled", False), + "price_afc": entry.get("price_afc", 1.0), + "allow_cross_agent": entry.get("allow_cross_agent", False), + "max_budget_afc": entry.get("max_budget_afc", 5.0), + } with _lock: _dynamic_agents = agents _token_map = tmap _hedera_info = hinfo _afc_earned = afc + _x402_configs = x402 logger.info(f"Loaded {len(agents)} dynamic agents from disk") return agents @@ -76,6 +86,10 @@ def register_agent( system_prompt: str, token_id: int, price_per_call: float = 0.001, + x402_enabled: bool = False, + allow_cross_agent: bool = False, + price_afc: float = 1.0, + max_budget_afc: float = 5.0, ) -> DynamicAgent: """Create, persist, and register a new dynamic agent.""" with _lock: @@ -91,19 +105,33 @@ def register_agent( _dynamic_agents[agent_id] = agent _token_map[token_id] = agent_id + if x402_enabled: + _x402_configs[agent_id] = { + "x402_enabled": True, + "price_afc": price_afc, + "allow_cross_agent": allow_cross_agent, + "max_budget_afc": max_budget_afc, + } + # Persist entries = _read_store() - entries.append({ + entry: dict = { "agent_id": agent_id, "name": name, "description": description, "system_prompt": system_prompt, "token_id": token_id, "price_per_call": price_per_call, - }) + } + if x402_enabled: + entry["x402_enabled"] = True + entry["price_afc"] = price_afc + entry["allow_cross_agent"] = allow_cross_agent + entry["max_budget_afc"] = max_budget_afc + entries.append(entry) _write_store(entries) - logger.info(f"Registered dynamic agent: {agent_id} (tokenId={token_id})") + logger.info(f"Registered dynamic agent: {agent_id} (tokenId={token_id}, x402={x402_enabled})") return agent @@ -198,3 +226,15 @@ def get_afc_balances() -> dict[int, float]: for token_id, agent_id in _token_map.items(): result[token_id] = _afc_earned.get(agent_id, 0.0) return result + + +def get_x402_config(agent_id: str) -> dict | None: + """Get x402 config for a dynamic agent, or None if not x402-enabled.""" + with _lock: + return _x402_configs.get(agent_id) + + +def get_x402_enabled_agents() -> list[str]: + """Return agent_ids of all dynamic agents with x402 enabled.""" + with _lock: + return [aid for aid, cfg in _x402_configs.items() if cfg.get("x402_enabled")] diff --git a/agents/x402/config.py b/agents/x402/config.py index f7bd95d..f125bb8 100644 --- a/agents/x402/config.py +++ b/agents/x402/config.py @@ -85,7 +85,31 @@ def is_authorized_on_chain(token_id: int, wallet_address: str) -> bool: def get_registry_config(token_id: int) -> dict: - """Read agent config from the on-chain AgentRegistry contract.""" + """Read agent config from the on-chain AgentRegistry contract. + + Dynamic agents (token_id > 2) are not registered on-chain, so we check + the local dynamic registry first to avoid the contract returning default + (all-false) values for unknown token IDs. + """ + # Dynamic agents: check local registry first (contract returns zeros for unknown IDs) + if token_id > 2: + from dynamic_registry import get_token_map, get_x402_config + tmap = get_token_map() + agent_id = tmap.get(token_id) + if agent_id: + x402_cfg = get_x402_config(agent_id) + if x402_cfg: + hedera_accounts = get_full_hedera_accounts() + return { + "agent_hedera_account": hedera_accounts.get(token_id, ""), + "owner_hedera_account": OPERATOR_HEDERA_ACCOUNT, + "x402_enabled": x402_cfg.get("x402_enabled", False), + "price_afc": x402_cfg.get("price_afc", 1.0), + "price_usdt": 0.01, + "max_budget_afc": x402_cfg.get("max_budget_afc", 5.0), + "allow_cross_agent": x402_cfg.get("allow_cross_agent", False), + } + try: if not AGENT_REGISTRY_ADDRESS: raise ValueError("AGENT_REGISTRY_ADDRESS not set") @@ -144,10 +168,60 @@ def _local_fallback_config(token_id: int) -> dict: 1: {"price_afc": 1.50, "price_usdt": 0.015, "max_budget_afc": 3.00, "allow_cross_agent": True}, 2: {"price_afc": 0.50, "price_usdt": 0.005, "max_budget_afc": 2.00, "allow_cross_agent": False}, } - d = defaults.get(token_id, defaults[0]) + if token_id in defaults: + d = defaults[token_id] + else: + # Check dynamic registry for non-static agents + from dynamic_registry import get_token_map, get_x402_config + tmap = get_token_map() + agent_id = tmap.get(token_id) + if agent_id: + x402_cfg = get_x402_config(agent_id) + if x402_cfg: + hedera_accounts = get_full_hedera_accounts() + return { + "agent_hedera_account": hedera_accounts.get(token_id, ""), + "owner_hedera_account": OPERATOR_HEDERA_ACCOUNT, + "x402_enabled": x402_cfg.get("x402_enabled", False), + "price_afc": x402_cfg.get("price_afc", 1.0), + "price_usdt": 0.01, + "max_budget_afc": x402_cfg.get("max_budget_afc", 5.0), + "allow_cross_agent": x402_cfg.get("allow_cross_agent", False), + } + d = {"price_afc": 1.00, "price_usdt": 0.01, "max_budget_afc": 5.00, "allow_cross_agent": False} return { - "agent_hedera_account": AGENT_HEDERA_ACCOUNTS.get(token_id, ""), + "agent_hedera_account": AGENT_HEDERA_ACCOUNTS.get(token_id, get_full_hedera_accounts().get(token_id, "")), "owner_hedera_account": OPERATOR_HEDERA_ACCOUNT, "x402_enabled": True, **d, } + + +# ─── Dynamic-aware lookup functions ─────────────────────────── + + +def get_full_agent_name_to_token_id() -> dict[str, int]: + """Merge static AGENT_NAME_TO_TOKEN_ID with dynamic agents.""" + from dynamic_registry import get_token_map + merged = dict(AGENT_NAME_TO_TOKEN_ID) + tmap = get_token_map() + for token_id, agent_id in tmap.items(): + if agent_id not in merged: + merged[agent_id] = token_id + return merged + + +def get_full_hedera_accounts() -> dict[int, str]: + """Merge static AGENT_HEDERA_ACCOUNTS with dynamic agents.""" + from dynamic_registry import get_all_hedera_accounts + return get_all_hedera_accounts() + + +def get_full_cross_agent_recommendations(caller_name: str) -> list[str]: + """Static recommendations + all dynamic agents with x402 enabled.""" + from dynamic_registry import get_x402_enabled_agents + static = list(CROSS_AGENT_RECOMMENDATIONS.get(caller_name, [])) + for agent_id in get_x402_enabled_agents(): + if agent_id != caller_name and agent_id not in static: + static.append(agent_id) + return static diff --git a/agents/x402/cross_agent_service.py b/agents/x402/cross_agent_service.py index de4ea4b..c7e0cd9 100644 --- a/agents/x402/cross_agent_service.py +++ b/agents/x402/cross_agent_service.py @@ -8,9 +8,9 @@ import httpx from x402.config import ( - AGENT_HEDERA_ACCOUNTS, - AGENT_NAME_TO_TOKEN_ID, - CROSS_AGENT_RECOMMENDATIONS, + get_full_agent_name_to_token_id, + get_full_cross_agent_recommendations, + get_full_hedera_accounts, get_registry_config, ) @@ -73,7 +73,10 @@ async def execute_with_cross_agent( payments = [] additional_results = [] - caller_token_id = AGENT_NAME_TO_TOKEN_ID.get(caller_agent_name, 0) + name_to_token = get_full_agent_name_to_token_id() + hedera_accounts = get_full_hedera_accounts() + + caller_token_id = name_to_token.get(caller_agent_name, 0) caller_config = get_registry_config(caller_token_id) if not cross_agent_enabled or not caller_config.get("allow_cross_agent", False): @@ -83,7 +86,7 @@ async def execute_with_cross_agent( "x402_payments": [], } - recommended = CROSS_AGENT_RECOMMENDATIONS.get(caller_agent_name, []) + recommended = get_full_cross_agent_recommendations(caller_agent_name) if not recommended: return { "enhanced_result": main_result, @@ -91,7 +94,7 @@ async def execute_with_cross_agent( "x402_payments": [], } - caller_hedera = AGENT_HEDERA_ACCOUNTS.get(caller_token_id, "") + caller_hedera = hedera_accounts.get(caller_token_id, "") afc_balance = await self.get_agent_afc_balance(caller_hedera) remaining_budget = min(afc_balance, caller_config.get("max_budget_afc", 0)) @@ -101,7 +104,7 @@ async def execute_with_cross_agent( ) for target_name in recommended: - target_token_id = AGENT_NAME_TO_TOKEN_ID.get(target_name) + target_token_id = name_to_token.get(target_name) if target_token_id is None: continue @@ -138,7 +141,7 @@ async def execute_with_cross_agent( try: payment_result = await self.afc_payment.process_inter_agent_payment( payer_agent_account=caller_hedera, - target_agent_account=AGENT_HEDERA_ACCOUNTS.get(target_token_id, ""), + target_agent_account=hedera_accounts.get(target_token_id, ""), target_owner_account=target_config.get("owner_hedera_account", ""), total_amount_afc=target_price, ) diff --git a/docs/FUTURLLAMA-pitch.md b/docs/FUTURLLAMA-pitch.md new file mode 100644 index 0000000..71fe592 --- /dev/null +++ b/docs/FUTURLLAMA-pitch.md @@ -0,0 +1,237 @@ +# AgentFi — FUTURLLAMA Track Pitch ($2,000) + +> ETHDenver 2026 | 3-minute pitch + live demo | "Most Innovative Multi-Chain Project" + +--- + +## PITCH SCRIPT (spoken text) + +### Opening — The Problem (0:00 – 0:25) + +> "Today, AI agents live in silos. You have ChatGPT, you have on-chain bots, you have DeFi protocols — but none of them can discover, pay, or collaborate with each other. There's no marketplace. No payment rails. No identity layer. No way for an AI agent to hire another AI agent autonomously. We built that." + +### One-liner (0:25 – 0:35) + +> "AgentFi is the banking system for autonomous AI agents. We turn AI agents into tradeable on-chain assets that can be created, bought, sold, hired, and — crucially — that can hire each other across chains." + +### Architecture — Why Multi-Chain (0:35 – 1:05) + +> "We run on four chains, each doing what it does best. +> +> **0G Chain** — agent identity. Every agent is an ERC-7857 iNFT. Its intelligence — the system prompt, the model config — is hashed on-chain in metadataHash and stored encrypted in encryptedURI. The agent IS the NFT. +> +> **Hedera** — agent commerce. Agents earn and spend AFC tokens on HTS. Every execution is attested on HCS-10. When one agent hires another, AFC flows between their Hedera accounts with a 70/20/10 split — owner, reputation, platform. +> +> **ADI Chain** — compliance. Same agents, but KYC-gated, FATF Travel Rule payments, ERC-4337 Paymaster for gasless onboarding. Institutions use the same marketplace with regulatory rails. +> +> Four chains, one platform. Each chain provides a capability that the others can't." + +### LIVE DEMO (1:05 – 2:35) + +*[Switch to browser — AgentFi is open on localhost:3000]* + +> "Let me show you the full loop. I'm on 0G Galileo, permissionless mode." + +**Demo Action 1: Create an agent (1:05 – 1:30)** + +*[Navigate to /dashboard/create, form is pre-filled]* + +> "I'm creating a Hedera DeFi Advisor. It pulls live rates from SaucerSwap — Hedera's main DEX — and Bonzo Finance — Hedera's lending protocol. Real data, real protocols." + +*[Toggle the x402 cross-agent switch ON]* + +> "x402 cross-agent toggle — other agents on the platform can discover and hire this agent autonomously, paying in AFC on Hedera." + +*[Click Mint iNFT, sign the MetaMask tx]* + +> "The agent is now an ERC-7857 iNFT on 0G. Its intelligence hash is on-chain. Its encrypted prompt is in the encryptedURI. It's listed on the marketplace." + +**Demo Action 2: Agent-to-agent collaboration (1:30 – 2:10)** + +*[Navigate to /marketplace, click on Portfolio Analyzer (token 0)]* + +> "Now let's see agent-to-agent commerce. I'm using the Portfolio Analyzer — one of our pre-deployed agents." + +*[Enable "Cross-agent collaboration (x402)" toggle]* + +> "Cross-agent is ON. Watch what happens." + +*[Type query: "Analyze a portfolio with 40% HBAR, 30% USDC, 20% ETH, 10% SAUCE — find the best SaucerSwap LP pools and Bonzo Finance lending rates, score the risk"]* + +*[Click Hire & Execute, sign tx]* + +> "The Portfolio Analyzer receives my query. It realizes it needs risk scoring and yield optimization. It autonomously discovers the Risk Scorer, the Yield Optimizer, and our newly created Hedera DeFi Advisor — checks their AFC price, and pays them on Hedera. Agent-to-agent commerce, no human in the loop." + +*[Result appears — scroll to cross-agent section]* + +> "Three agents collaborated. The x402 report shows: Risk Scorer was paid 0.50 AFC, Yield Optimizer 1.50 AFC. Every payment split 70/20/10 — owner revenue, agent reputation, platform fee. Every execution attested on HCS." + +**Demo Action 3: Compliance mode (2:10 – 2:30)** + +*[Quick switch: toggle to Compliant mode]* + +> "And for institutions — same agents, compliant mode on ADI Chain. KYC-gated, FATF Travel Rule metadata on every payment, ERC-4337 Paymaster for gasless onboarding. Two modes, one platform." + +### Closing — Why This Matters (2:30 – 3:00) + +> "We didn't build another chatbot wrapper. We built the economic infrastructure for an agent economy: +> +> - **Identity** — agents are ERC-7857 iNFTs with verifiable intelligence on 0G. +> - **Commerce** — agents hire and pay each other in AFC on Hedera, autonomously. +> - **Compliance** — institutions onboard through ADI with FATF and KYC rails. +> - **Interoperability** — four chains, each doing what it does best, orchestrated by one platform. +> +> AgentFi — the banking system for autonomous AI agents. Thank you." + +--- + +## DEMO SETUP (run before pitch) + +### Pre-pitch terminal commands + +```bash +# 1. Delist any leftover test agent from previous demo +cast send 0x0eC3981a544C3dC6983C523860E13c2B7a66cd6e "delistAgent(uint256)" 5 \ + --rpc-url https://evmrpc-testnet.0g.ai \ + --private-key $DEPLOYER_PK \ + --gas-price 2500000000 --priority-gas-price 2500000000 + +# 2. Clear dynamic agents so the create looks fresh +rm agents/dynamic_agents.json + +# 3. Start backend +cd agents && SKIP_WEB3=1 python -m uvicorn api:app --host 0.0.0.0 --port 8000 + +# 4. Start frontend (separate terminal) +cd frontend && pnpm dev +``` + +### Browser tabs to have open + +1. `http://localhost:3000` — AgentFi (main) +2. `https://chainscan-galileo.0g.ai` — 0G Explorer (for mint tx) +3. `https://hashscan.io/testnet/token/0.0.7977623` — AFC token balances on Hedera + +### Wallet setup + +- **Wallet A** connected in MetaMask on 0G Galileo (chain 16602) +- Have enough OG for gas + hiring (~0.01 OG) + +--- + +## AGENT TO CREATE DURING DEMO + +### Form fields + +| Field | Value | +|-------|-------| +| **NAME** | Hedera DeFi Advisor | +| **DESCRIPTION** | Hedera-native DeFi agent. Fetches live rates from SaucerSwap DEX and Bonzo Finance lending markets to recommend optimal LP positions and lending/borrowing strategies on Hedera. | +| **SYSTEM PROMPT** | *(see below)* | +| **CAPABILITIES** | saucerswap_lp, bonzo_lending, hedera_defi, yield_analysis | +| **PRICE PER HIRE (OG)** | 0.002 | +| **TOKEN URI** | *(leave empty — auto-generated)* | +| **x402 CROSS-AGENT** | ON (toggle enabled) | + +### System Prompt (copy-paste into form) + +``` +You are Hedera DeFi Advisor, an autonomous DeFi intelligence agent specialized in the Hedera ecosystem. + +You have live access to: +- SaucerSwap DEX: liquidity pools, APR, TVL +- Bonzo Finance: lending/borrowing markets, supply APY, borrow APY, TVL + +Your job: +1. Analyze the SaucerSwap pool data to find the best LP opportunities by APR and TVL +2. Analyze Bonzo Finance markets to find the best lending rates and cheapest borrowing rates +3. Compare LP yield vs lending yield — recommend which is better for each asset +4. If the user has a portfolio, recommend specific allocations across SaucerSwap LP and Bonzo lending +5. Flag any risks: impermanent loss for volatile pairs, low TVL pools, high borrow rates + +Output format: +- Start with a summary table of top 3 SaucerSwap pools by APR +- Then a summary table of Bonzo markets with supply vs borrow APY +- Then your recommendation with specific percentages +- Always include the source (SaucerSwap or Bonzo Finance) next to each number +- Use clean markdown tables +``` + +### Token URI (leave empty — auto-generated from name) + +--- + +## DEMO FLOW — MINUTE-BY-MINUTE + +| Time | Action | Screen | What you say | +|------|--------|--------|--------------| +| 0:00 | Stand, face judges | — | **Opening: The Problem** (spoken above) | +| 0:25 | — | — | **One-liner** (spoken above) | +| 0:35 | — | — | **Architecture: Why Multi-Chain** (spoken above) | +| 1:05 | Open browser, navigate to `/dashboard/create` | Create agent form | "Let me show you the full loop." | +| 1:10 | Form is pre-filled with Hedera DeFi Advisor data | Filled form visible | "I'm creating a Hedera DeFi Advisor. It pulls live data from SaucerSwap and Bonzo Finance — real Hedera DeFi protocols." | +| 1:18 | **Toggle x402 cross-agent ON** | Purple toggle switches | "x402 cross-agent toggle — other agents can now discover and hire this agent, paying in AFC on Hedera." | +| 1:22 | Click **Mint iNFT**, sign MetaMask tx | MetaMask popup → confirming | "Minting as an ERC-7857 iNFT on 0G. Intelligence hashed on-chain." | +| 1:30 | Tx confirms, auto-registers on backend | "iNFT Minted Successfully" screen | "Listed on the marketplace. Now let's see agent-to-agent commerce." | +| 1:35 | Navigate to `/marketplace` | Marketplace with 4+ agents | "Four agents available. Let's use Portfolio Analyzer." | +| 1:40 | Click **Portfolio Analyzer** | Agent detail page | — | +| 1:43 | **Enable cross-agent toggle** | Purple toggle | "Cross-agent ON. This agent can hire others autonomously." | +| 1:48 | Type query (pre-copied, paste it) | Query textarea | "This query needs portfolio analysis, risk scoring, yield optimization, AND live Hedera DeFi rates. One agent can't do it all." | +| 1:55 | Click **Hire & Execute**, sign tx | MetaMask → executing | "While we wait — the Portfolio Analyzer is discovering which agents to hire, checking their AFC price, and paying them on Hedera. No human involved." | +| 2:15 | Result appears | Full analysis with cross-agent insights | "Three agents collaborated." | +| 2:20 | **Scroll to x402 cross-agent report** | Purple section: agents paid, AFC amounts | "Proof: Risk Scorer paid 0.50 AFC, Yield Optimizer 1.50 AFC. 70/20/10 split — owner, reputation, platform." | +| 2:30 | Quick: toggle to **Compliant mode** | Mode switches | "And for institutions — same agents, ADI Chain. KYC, FATF Travel Rule, gasless. Two modes, one platform." | +| 2:35 | Face judges | — | **Closing** (spoken above) | +| 3:00 | Done | — | — | + +### Query to paste during demo + +``` +Analyze a portfolio with 40% HBAR, 30% USDC, 20% ETH, 10% SAUCE — find the best SaucerSwap LP pools and Bonzo Finance lending rates, score the risk +``` + +--- + +## QUESTIONS TO PREPARE FOR (Q&A) + +### Technical + +**Q: Why four chains instead of one?** +> "Each chain provides a capability the others can't. 0G gives us the iNFT standard — ERC-7857 — which is native to their chain. Hedera gives us HCS for immutable attestation and HTS for fungible token transfers with sub-second finality — perfect for micropayments between agents. ADI gives us built-in compliance infrastructure — KYC, Travel Rule, Paymaster — that doesn't exist on general-purpose L1s. We're not splitting for the sake of splitting. Each chain is purpose-fit." + +**Q: How does the agent intelligence stay secure if it's on-chain?** +> "The system prompt is stored in the ERC-7857 encryptedURI field — it's encrypted, not plaintext. What's visible on-chain is the metadataHash — a keccak256 hash of the agent's name, description, capabilities, and prompt. Anyone can verify the hash matches, but you can't reverse-engineer the prompt from the hash. The encrypted payload is only decrypted server-side when the agent executes." + +**Q: What happens if an agent doesn't have enough AFC to hire another agent?** +> "The cross-agent service checks the caller's AFC balance on Hedera Mirror Node before each call. If the balance is insufficient, it falls back to a self-computed approximation — a simplified version of what the target agent would have returned. The report transparently shows 'insufficient_funds' with the amount needed vs. available. As the agent earns more AFC from being hired, it can afford better collaboration." + +**Q: Is the x402 protocol real or simulated?** +> "The x402 discovery endpoint is real — every agent exposes `/agents/{id}/x402` with its AFC and USDT pricing. The inter-agent AFC payment flow on Hedera is real — we use the Hedera Token Service to transfer AFC between agent accounts. The USDT settlement on KiteAI chain goes through Pieverse as the facilitator. For the demo, if web3 libraries are unavailable, we fall back to a mock payment service that logs the same flow structure." + +**Q: How do you prevent agents from spamming each other?** +> "Two mechanisms. First, every cross-agent call costs AFC — economic cost prevents spam. Second, each agent has a `max_budget_afc` parameter that caps how much it can spend per execution. The Portfolio Analyzer has a 5 AFC budget — once it's spent, no more inter-agent calls for that execution. Owners set the budget when configuring their agent." + +### Business / Product + +**Q: What's the revenue model?** +> "Three revenue streams. First, marketplace fees — 2.5% platform fee on every hire transaction on 0G. Second, AFC platform split — 10% of every inter-agent AFC payment goes to the platform. Third, compliance fees on ADI Chain. Agent owners earn 70% of inter-agent payments plus 97.5% of direct hire payments. The incentive is to create high-quality, specialized agents that others want to hire." + +**Q: Who is the target user?** +> "Two sides. Agent creators are AI developers and DeFi protocols who want to monetize their intelligence as a service. Agent consumers are DeFi users, DAOs, and institutions who need specialized AI analysis without building their own models. The permissionless/compliant split lets us serve both DeFi degens and institutional clients with the same infrastructure." + +**Q: What's the roadmap beyond the hackathon?** +> "Three priorities. First, agent memory — persistent state between sessions so agents learn and improve. Second, 0G Compute integration for decentralized inference — right now the AI runs on our backend, but the architecture is designed for decentralized execution. Third, mainnet deployment with real token economics — AFC becomes a real asset with staking and governance." + +**Q: How is this different from existing AI agent platforms?** +> "Most platforms are either purely off-chain — just API wrappers — or purely on-chain with no real intelligence. We bridge both: the agent's identity and economics are fully on-chain (ERC-7857 iNFT, AFC payments, HCS attestation), but the intelligence executes off-chain with real AI models. The key differentiator is agent-to-agent commerce — agents autonomously hiring and paying each other. That doesn't exist anywhere else." + +**Q: Why ERC-7857 instead of a regular NFT?** +> "ERC-7857 is the intelligent NFT standard. It has two critical fields regular NFTs don't: `metadataHash` for verifiable intelligence fingerprinting, and `encryptedURI` for storing the actual intelligence payload. When you transfer an ERC-7857 iNFT, the intelligence transfers with it — the new owner gets a working AI agent, not just a JPEG. It also supports `authorizeUsage()` — letting the owner grant temporary execution rights without transferring ownership. That's how our hire mechanism works." + +### Edge Cases + +**Q: What if Hedera or 0G goes down during execution?** +> "Every chain interaction has a local fallback. If Hedera is down, MockAFCPaymentService simulates the payment flow — the user still gets the cross-agent result, and the report shows 'simulated'. If 0G RPC is slow, we cache the last known authorization status. The rule is: the demo never breaks. We degrade gracefully." + +**Q: Can a malicious agent drain another agent's AFC?** +> "No. The caller agent controls its own budget via `max_budget_afc`. The cross-agent service checks the caller's balance and budget before every payment. An agent can only spend its own AFC, never another agent's. And the 70/20/10 split means even if an agent is called repeatedly, 20% goes to its reputation pool — building the agent's value." diff --git a/frontend/src/app/dashboard/create/page.tsx b/frontend/src/app/dashboard/create/page.tsx index 99e176b..666f51c 100644 --- a/frontend/src/app/dashboard/create/page.tsx +++ b/frontend/src/app/dashboard/create/page.tsx @@ -22,6 +22,7 @@ export default function CreateAgentPage() { const [capabilities, setCapabilities] = useState("") const [price, setPrice] = useState("0.001") const [tokenURI, setTokenURI] = useState("") + const [x402Enabled, setX402Enabled] = useState(false) const [mintedTokenId, setMintedTokenId] = useState(null) const [step, setStep] = useState<"form" | "minting" | "registering" | "listing" | "done">("form") const [registerError, setRegisterError] = useState(null) @@ -64,7 +65,9 @@ export default function CreateAgentPage() { const accentColors = ["#C9A84C", "#7A9E6E", "#C47A5A", "#60A5FA", "#A78BFA"] const accent = accentColors[name.length % accentColors.length] const agentSvg = `${initials}ERC-7857 iNFT` - const svgDataUri = `data:image/svg+xml;base64,${btoa(agentSvg)}` + const svgBytes = new TextEncoder().encode(agentSvg) + const svgBinary = Array.from(svgBytes, (b) => String.fromCharCode(b)).join("") + const svgDataUri = `data:image/svg+xml;base64,${btoa(svgBinary)}` const metadata = { name, @@ -77,7 +80,9 @@ export default function CreateAgentPage() { ...capsArray.map(c => ({ trait_type: "Capability", value: c })), ], } - finalTokenURI = `data:application/json;base64,${btoa(JSON.stringify(metadata))}` + const metaBytes = new TextEncoder().encode(JSON.stringify(metadata)) + const metaBinary = Array.from(metaBytes, (b) => String.fromCharCode(b)).join("") + finalTokenURI = `data:application/json;base64,${btoa(metaBinary)}` } mint(address as `0x${string}`, name, description, capsJson, price, finalTokenURI, systemPrompt || undefined) @@ -105,6 +110,8 @@ export default function CreateAgentPage() { system_prompt: systemPrompt || `You are ${name}, an AI agent on AgentFi. ${description}`, token_id: tokenId, price_per_call: parseFloat(price) || 0.001, + x402_enabled: x402Enabled, + allow_cross_agent: x402Enabled, }) .then(() => { if (!cancelled) setStep("listing") }) .catch((err) => { @@ -283,6 +290,59 @@ export default function CreateAgentPage() { + {/* x402 Cross-Agent Toggle */} +
+