Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.prudra.dev/llms.txt

Use this file to discover all available pages before exploring further.

How MPP works

MPP reverses the settlement order compared to x402. Instead of signing off-chain and having the server settle, the agent sends a real on-chain transaction first, then proves it to the server by passing the transaction hash. The server verifies the transaction exists on-chain and has the correct amount and recipient before proceeding.

The full flow

The HMAC challenge ID

The challenge id field is computed server-side:
input = [realm, method, intent, request, expires].join('|')
id = base64url(HMAC-SHA256(MPP_CHALLENGE_SECRET, input))
This is stateless verification — no database lookup required. When the agent echoes back the challenge id, Prudra recomputes the HMAC from the echoed parameters and compares with crypto.timingSafeEqual(). If they match, the challenge is genuine. The expires field is part of the signed input, so an expired challenge cannot be replayed with a modified expiry — the HMAC would not match.

Challenge expiry

MPP challenges expire at the expires timestamp included in the WWW-Authenticate header. A typical expiry is 5 minutes from challenge generation. After expiry:
  • The agent’s request returns a 402 with a fresh challenge
  • The agent must request a new challenge and pay again
  • Old challenges are not stored — expiry is enforced purely by the HMAC

On-chain verification

Prudra verifies the Tempo transaction with these checks:
CheckWhat Prudra verifies
Receipt existseth_getTransactionReceipt returns a non-null receipt
Transaction confirmedcurrentBlock - txBlock >= 1 (Tempo Simplex Consensus, no re-orgs)
Recipientto address in the transaction matches the server’s registered wallet
AmountToken transfer amount meets or exceeds the required price
TokenUSDC.e contract address matches
ReplaytxHash is unique — UNIQUE constraint in Postgres
The uint64 underflow guard: confirmations = currentBlock > txBlock ? currentBlock - txBlock : 0 — prevents a panic if the block numbers are unexpected.

MPP vs x402 — key differences

x402MPP
Agent actionSign off-chain (no gas)Send on-chain transaction (gas cost)
SettlementServer submits transaction after verificationAgent already settled — server just verifies
LatencyVerification fast; settlement asyncMust wait for 1 Tempo confirmation (~2s)
ChainBase (USDC)Tempo (USDC.e)
Session paymentsNot supportedSupported
Standardx402 FoundationIETF Internet Draft