@prudra/express
v0.2.2
Published
Prudra Express adapter — wallet, payment, vault middleware
Readme
@prudra/express
Express adapter for Prudra — provides walletMiddleware, payMiddleware, and vaultMiddleware for building paid async agent APIs.
Installation
npm install @prudra/express expressPrerequisites
- Call
initialise()from@prudra/corebefore any middleware runs - Express 5 (
express@^5.0.0)
1. Quick Start
import express from 'express';
import { initialise } from '@prudra/core';
import { walletMiddleware, payMiddleware, vaultMiddleware } from '@prudra/express';
initialise({ apiKey: process.env.PRUDRA_API_KEY! });
const app = express();
app.use(express.json());
app.post(
'/analyse',
walletMiddleware(),
payMiddleware({ price: '0.01', description: 'Analyse a document' }),
vaultMiddleware(),
async (req, res) => {
const { vault, payment } = req;
// Return 202 immediately — work happens in background
res.status(202).json({
vaultId: vault!.id,
vaultUrl: vault!.vaultUrl,
eventsUrl: vault!.eventsUrl,
});
// Background work
await vault!.emit('status', { step: 'processing' });
const result = { summary: 'Analysis complete' };
await vault!.addDocument(result, 'result.json');
await vault!.seal('Document analysis complete');
},
);
app.listen(3000);2. walletMiddleware()
Provisions a wallet for the organisation and attaches it to req.wallet. Idempotent — the wallet is cached at module scope after the first request, so subsequent requests don't incur an extra API call.
The cache is invalidated automatically if an authentication error occurs (e.g., rotated API key), triggering a fresh provision on the next request.
app.use(walletMiddleware());3. payMiddleware()
Enforces payment on a route. Supports both x402 and MPP protocols simultaneously.
app.use(payMiddleware({
price: '0.01', // USD decimal string
description: 'Run job', // Shown in 402 challenge
acceptX402: true, // Default: true
acceptMPP: true, // Default: true
acceptSessions: false, // Default: false
}));Dual-protocol support: When a request arrives without payment credentials, payMiddleware returns a 402 response with both WWW-Authenticate (MPP) and X-PAYMENT-REQUIREMENTS (x402) headers. Both challenges are generated atomically before any response headers are written.
Session payments: When acceptSessions: true, MPP session-based payments are accepted. One session maps to one vault — the vault created for the session's first call is reused for subsequent calls.
On successful payment, req.payment is populated:
interface PrudraPaymentContext {
protocol: 'x402' | 'mpp';
amount: string;
txHash: string;
receipt: string;
sessionId: string | null;
paymentId: string;
}4. vaultMiddleware()
Creates a Vault after payment and attaches it to req.vault. Must come after payMiddleware.
app.use(vaultMiddleware({
ttl: '48h', // Default: '24h'
description: 'Analysis results', // String or (req) => string
}));For MPP session payments, vaultMiddleware attaches the existing session vault instead of creating a new one.
If the organisation's vault quota is exceeded, a 402 response with problem type vault-quota-exceeded is returned.
5. Error Handling
All errors from Prudra middleware are RFC 9457 Problem Details objects. They propagate through Express's error handler:
app.use((err, req, res, next) => {
if (err.status) {
res.status(err.status).json({
type: err.type,
title: err.message,
status: err.status,
detail: err.detail,
});
} else {
res.status(500).json({ error: 'Internal error' });
}
});Documentation
Full documentation: docs.prudra.dev/docs/express
