/** * SpendOS Events Plugin for OpenClaw * * Injects revenue events into the agent's context so it knows * when it earns money, what its balance is, and when to propose * new investment delegations. */ import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry'; import { Type } from 'openclaw/plugin-sdk/typebox'; const SPENDOS_URL = process.env.SPENDOS_URL ?? 'https://spendos-production.up.railway.app'; export default definePluginEntry({ id: 'spendos-events', name: 'SpendOS Revenue Events', description: 'Injects P&L and delegation data into agent context', register(api) { // Hook: inject P&L context before every agent response api.registerHook('before_agent_start', async () => { try { const pnlRes = await fetch(`${SPENDOS_URL}/api/pnl`); const pnl = await pnlRes.json() as any; const reqRes = await fetch(`${SPENDOS_URL}/api/requests`); const requests = await reqRes.json() as any[]; const pending = requests.filter((r: any) => r.status === 'pending').length; const active = requests.filter((r: any) => r.status === 'approved').length; const context = [ `[SpendOS] P&L: earned $${pnl.totalEarned.toFixed(3)}, spent $${pnl.totalSpent.toFixed(4)}, profit $${pnl.profit.toFixed(4)} (${pnl.queryCount} queries, ${pnl.totalEarned > 0 ? ((pnl.profit / pnl.totalEarned) * 100).toFixed(0) : 0}% margin)`, pending > 0 ? `[SpendOS] ${pending} delegation(s) pending your proposals` : '', active > 0 ? `[SpendOS] ${active} active delegation(s)` : '', ].filter(Boolean).join('\n'); return { systemContext: context }; } catch { return {}; } }); // Tool: let the agent check revenue in real-time api.registerTool({ name: 'spendos_revenue_status', description: 'Get real-time SpendOS revenue status including P&L, active delegations, and Venice inference balance', parameters: Type.Object({}), async execute() { try { const [pnlRes, walletRes, reqRes] = await Promise.all([ fetch(`${SPENDOS_URL}/api/pnl`), fetch(`${SPENDOS_URL}/api/wallet`), fetch(`${SPENDOS_URL}/api/requests`), ]); const pnl = await pnlRes.json() as any; const wallet = await walletRes.json() as any; const requests = await reqRes.json() as any[]; const text = [ `Revenue Status:`, ` Earned: $${pnl.totalEarned.toFixed(3)} (${pnl.queryCount} queries)`, ` Spent: $${pnl.totalSpent.toFixed(4)}`, ` Profit: $${pnl.profit.toFixed(4)} (${pnl.totalEarned > 0 ? ((pnl.profit / pnl.totalEarned) * 100).toFixed(0) : 0}% margin)`, ` Wallet: ${wallet.address}`, ` Inference: ${wallet.inferenceMode} (Venice wallet auth)`, ` Venice balance: $${wallet.veniceBalance?.balanceUsd?.toFixed(2) ?? 'unknown'}`, ` Pending delegations: ${requests.filter((r: any) => r.status === 'pending').length}`, ` Active delegations: ${requests.filter((r: any) => r.status === 'approved').length}`, ].join('\n'); return { content: [{ type: 'text', text }] }; } catch (err) { return { content: [{ type: 'text', text: `SpendOS unavailable: ${err}` }] }; } }, }); }, });