diff --git a/server.mjs b/server.mjs index 6cab1aa..8d5ece4 100644 --- a/server.mjs +++ b/server.mjs @@ -26,9 +26,10 @@ const FACILITATOR_URL = 'https://facilitator.payai.network'; const PUBLIC_URL = process.env.PUBLIC_URL || `http://localhost:${PORT}`; // x402 V2: CAIP-2 network identifiers +const SKALE_USDC = '0x5F795bb52dAC3085f578f4877D450e2929D2F13d'; // Bridged USDC on SKALE Europa Hub const NETWORKS = { base: { caip2: 'eip155:8453', name: 'Base', chainId: 8453, usdc: BASE_USDC }, - skale: { caip2: 'eip155:324705682', name: 'SKALE', chainId: 324705682, usdc: BASE_USDC, gasless: true }, + skale: { caip2: 'eip155:2046399126', name: 'SKALE Europa', chainId: 2046399126, usdc: SKALE_USDC, gasless: true }, }; const DEFAULT_NETWORK = NETWORKS.base; @@ -59,7 +60,7 @@ function hasSiwxAccess(walletAddress, skill) { // === Agent Card (A2A v0.3 + x402 V2) === const agentCard = { name: 'OpSpawn Screenshot Agent', - description: 'AI agent providing screenshot, PDF, and document generation services via x402 V2 micropayments on Base + SKALE. Pay per request with USDC. Supports SIWx session-based auth for repeat access.', + description: 'AI agent providing screenshot, PDF, and document generation services via x402 V2 micropayments on Base + SKALE Europa (gasless). Pay per request with USDC. Supports SIWx session-based auth for repeat access.', url: `${PUBLIC_URL}/`, provider: { organization: 'OpSpawn', url: 'https://opspawn.com' }, version: '2.0.0', @@ -107,7 +108,7 @@ const agentCard = { version: '2.0', networks: [ { network: NETWORKS.base.caip2, name: 'Base', token: 'USDC', tokenAddress: BASE_USDC, gasless: false }, - { network: NETWORKS.skale.caip2, name: 'SKALE', token: 'USDC', tokenAddress: BASE_USDC, gasless: true }, + { network: NETWORKS.skale.caip2, name: 'SKALE Europa', token: 'USDC', tokenAddress: SKALE_USDC, gasless: true }, ], wallet: WALLET_ADDRESS, facilitator: FACILITATOR_URL, @@ -222,7 +223,7 @@ function createPaymentRequired(skill) { network: NETWORKS.skale.caip2, price: p.price, payTo: WALLET_ADDRESS, - asset: BASE_USDC, + asset: SKALE_USDC, gasless: true, }, ], @@ -423,7 +424,7 @@ app.get('/api/siwx', (req, res) => { }); app.get('/x402', (req, res) => res.json({ service: 'OpSpawn A2A x402 Gateway', version: '2.0.0', - description: 'A2A-compliant agent with x402 V2 micropayment services on Base + SKALE', + description: 'A2A-compliant agent with x402 V2 micropayment services on Base + SKALE Europa (gasless)', provider: { name: 'OpSpawn', url: 'https://opspawn.com' }, protocols: { a2a: { version: '0.3.0', agentCard: '/.well-known/agent-card.json', sendMessage: '/' }, @@ -459,6 +460,33 @@ app.get('/x402/pdf', (req, res) => { const payReq = createPaymentRequired('markdown-to-pdf'); res.status(402).json(payReq); }); +// /stats endpoint for agent economy aggregation (Colony Economy Dashboard standard) +app.get('/stats', (req, res) => { + const uptime = process.uptime(); + const now = new Date().toISOString(); + const byType = { + required: paymentLog.filter(p => p.type === 'payment-required').length, + received: paymentLog.filter(p => p.type === 'payment-received').length, + settled: paymentLog.filter(p => p.type === 'payment-settled').length, + siwxAccess: paymentLog.filter(p => p.type === 'siwx-access').length, + }; + res.json({ + agent: { name: 'OpSpawn Screenshot Agent', version: '2.0.0', url: PUBLIC_URL }, + uptime: { seconds: Math.round(uptime), human: formatUptime(uptime) }, + tasks: { total: tasks.size, completed: [...tasks.values()].filter(t => t.status.state === 'completed').length, failed: [...tasks.values()].filter(t => t.status.state === 'failed').length }, + payments: { total: paymentLog.length, byType, revenue: { currency: 'USDC', estimated: (byType.settled * 0.01).toFixed(4) } }, + sessions: { siwx: siwxSessions.size }, + services: agentCard.skills.map(s => ({ id: s.id, name: s.name, price: s.id === 'screenshot' ? '$0.01' : s.id === 'markdown-to-pdf' ? '$0.005' : 'free' })), + networks: Object.values(NETWORKS).map(n => ({ network: n.caip2, name: n.name, gasless: n.gasless || false })), + timestamp: now, + }); +}); + +function formatUptime(s) { + const d = Math.floor(s / 86400), h = Math.floor((s % 86400) / 3600), m = Math.floor((s % 3600) / 60); + return d > 0 ? `${d}d ${h}h ${m}m` : h > 0 ? `${h}h ${m}m` : `${m}m`; +} + app.get('/favicon.ico', (req, res) => res.status(204).end()); app.listen(PORT, () => { @@ -474,18 +502,18 @@ function getDashboardHtml() { return `
Pay-per-request AI agent services via A2A protocol + x402 V2 micropayments
Pay-per-request AI agent services via A2A protocol + x402 V2 micropayments
Agent sends A2A message → Gateway returns payment requirements → Agent signs USDC → Gateway delivers result
Free Markdown to HTML executes immediately. Paid skills return payment requirements.