import { PaymentsError } from '@nevermined-io/payments'
// Comprehensive error handling
app.use(async (err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof PaymentsError) {
console.error(`Payments error: ${err.code} - ${err.message}`)
switch (err.code) {
case 'INVALID_API_KEY':
return res.status(401).json({ error: 'Invalid API configuration' })
case 'INSUFFICIENT_BALANCE':
return res.status(402).json({
error: 'Insufficient credits',
message: 'Please purchase more credits to continue'
})
case 'INVALID_SIGNATURE':
return res.status(403).json({ error: 'Invalid request signature' })
case 'NETWORK_ERROR':
return res.status(503).json({ error: 'Service temporarily unavailable' })
default:
return res.status(500).json({ error: 'Payment processing error' })
}
}
// Handle other errors
console.error('Unexpected error:', err)
res.status(500).json({ error: 'Internal server error' })
})
// Monitoring and analytics
class UsageMonitor {
private usage = new Map<string, { requests: number, credits: bigint }>()
trackUsage(subscriberAddress: string, credits: bigint) {
const current = this.usage.get(subscriberAddress) || { requests: 0, credits: 0n }
this.usage.set(subscriberAddress, {
requests: current.requests + 1,
credits: current.credits + credits
})
}
getUsageStats() {
return Array.from(this.usage.entries()).map(([address, stats]) => ({
address,
...stats,
credits: stats.credits.toString()
}))
}
}
const monitor = new UsageMonitor()
// Track usage in endpoints
app.post('/api/ai-query',
neverminedAuth(planId, agentId),
async (req, res) => {
const result = await processAIQuery(req.body.prompt)
const creditsUsed = 1n
// Track usage
monitor.trackUsage(req.body.subscriberAddress, creditsUsed)
// Redeem credits
await payments.redeemCredits(req.body.planId, creditsUsed, generateProof(req, result))
res.json({ result })
}
)
// Analytics endpoint
app.get('/api/admin/usage', authenticate, (req, res) => {
res.json(monitor.getUsageStats())
})