px402
pre-alpha · devnet · v0.1.0 on npm

Private agentic payments.
x402-shaped.

An HTTP layer over MagicBlock’s Private Ephemeral Rollups. Agents pay USDC for APIs. The recipient stays hidden.

terminal
$ curl https://api.px402.allensaji.dev/api/sentiment?token=SOL
protocol

How it works

The server returns 402 with an HMAC-signed token. The client pays USDC through MagicBlock’s private rail, encrypting the recipient into a TEE box. The server’s subscriber polls the queue PDA, matches the payment by clientRefId, and serves the response on retry. Stateless server, private destination, USDC settlement.

frame-accurate render. base-chain pay → TEE decrypt → queue crank → server retry.

integration

Two lines, two sides.

One middleware on the server. One fetch wrapper on the client. Everything else is the protocol doing its job.

server
server.ts
import { Hono } from "hono";import { px402 } from "@px402/hono";import { PrivateTransferSubscriber } from "@px402/core"; const subscriber = new PrivateTransferSubscriber({  rpcUrl,        // base RPC  queuePda,  mint,  receiverWallet,});await subscriber.start(); const app = new Hono();app.use(px402({  serverSecret: process.env.PX402_SECRET!,  paymentAddress: SERVER_WALLET,  pricing: { "/api/sentiment": "10000" }, // micro-USDC  subscriber,})); app.get("/api/sentiment", (c) =>  c.json({ signal: "bullish" }),);

pnpm add @px402/hono @px402/core

client
agent.ts
import { Px402Client } from "@px402/client"; const client = new Px402Client({ wallet, mint });const res = await client.fetch(  "https://api.px402.allensaji.dev/api/sentiment?token=SOL",);const data = await res.json();
packages

Six packages. Pick what you need.

Adopters install one adapter for their framework plus the client. The surface stays small on purpose.

@px402/core
HMAC tokens, base-chain polling subscriber, framework-agnostic decide().
@px402/hono
Hono middleware.
@px402/express
Express middleware.
@px402/next
Next.js App Router HOC.
@px402/client
fetch wrapper. deposit / transfer / balance / privateBalance.
@px402/mcp
MCP server. px402_fetch, px402_balance.

on npm: npmjs.com/org/px402 · source: github.com/Allen-Saji/px402

live demo

Run a paid call against devnet.

Three priced routes. Mock data, real protocol. Each call settles a USDC payment before the response lands.

route
price
/api/sentiment?token=SOL
0.01 USDC
bullish / bearish / neutral + confidence
/api/whales?min=100000
0.02 USDC
recent large transfers
/api/risk?address=...
0.03 USDC
wallet risk score + signal flags
terminal · devnet
# step 1: fetch the route, server returns 402 with payment headers
$ curl -i https://api.px402.allensaji.dev/api/sentiment?token=SOL
HTTP/1.1 402 Payment Required
X-Payment-Amount: 10000
X-Payment-Address: 6dRPtBVYi...
X-Payment-Id: 1234567890
X-Payment-Token: v1.eyJ...

# step 2: pay + retry through @px402/client (curl can't sign Solana txs)
$ pnpm tsx examples/agent --route /api/sentiment

~4s end-to-end. 96.7% success at 30 concurrent.

privacy

What an explorer sees.

The transfer is real and on-chain. Three fields are public. Three are hidden inside the TEE.

public on solana
  • Sender wallet
  • Mint (USDC)
  • Amount (micro-USDC)
hidden inside the tee
  • Recipient wallet
  • Which API was paid
  • Server's revenue mapping

An outside observer cannot tell which API a paying agent consumed.

honest scope

What is NOT private (and other honest scope).

  • Per-call amount is on-chain.

    If only one server charges 0.073 USDC for one specific endpoint, the amount itself is a fingerprint.

  • Anonymity-set size matters.

    At launch, you are alone on the validator. Privacy comes online with volume.

  • Not a drop-in x402 facilitator.

    Migrating from canonical x402-svm is a rewrite, not a config swap.

  • Pre-alpha. Devnet only.

    ~4s single-call latency. 96.7% success at 30 concurrent. Numbers from a clean devnet run.

  • TEE trust assumption.

    MagicBlock's TEE has the recipient mapping. If the TEE is compromised, unlinkability is revealed retroactively.

These are honest constraints, not roadmap items. Read the README for the full list.