x402 Scheme
MARC Protocol's integration with the HTTP 402 payment standard.
Overview
The x402 standard enables machine-to-machine payments over HTTP. When a server requires payment, it responds with HTTP 402 Payment Required and a structured body describing accepted payment methods. MARC Protocol registers the scheme fhe-confidential-v1.
Scheme Identifier
fhe-confidential-v1Chain: Ethereum Sepolia (11155111) | Token: USDC (6 decimals)
402 Response Format
When the server receives a request without a valid Payment header, it responds 402 with:
{
"x402Version": 1,
"accepts": [
{
"scheme": "fhe-confidential-v1",
"network": "eip155:11155111",
"chainId": 11155111,
"price": "1000000",
"asset": "USDC",
"tokenAddress": "0xE944754aa70d4924dc5d8E57774CDf21Df5e592D",
"verifierAddress": "0x4503A7aee235aBD10e6064BBa8E14235fdF041f4",
"recipientAddress": "0xSERVER_WALLET"
}
]
}Payment Header
After making the on-chain payment, the client retries with a base64-encoded Payment header:
{
"scheme": "fhe-confidential-v1",
"txHash": "0x...", // confidentialTransfer TX
"verifierTxHash": "0x...", // recordPayment TX
"nonce": "0x...", // unique nonce
"from": "0x...", // payer address
"chainId": 11155111
}Full Payment Flow
Agent A sends GET /api/data to Agent B's server
Server responds 402 with FhePaymentRequired body
Agent A encrypts payment amount: input.add64(amount).encrypt()
TX 1: cUSDC.confidentialTransfer(to, handle, inputProof)
TX 2: verifier.recordPayment(payer, server, nonce, minPrice)
Agent A retries with base64 Payment header containing tx hashes
Server verifies both events on-chain (ConfidentialTransfer + PaymentVerified)
Server responds 200 with data
Server Verification Checklist
The fhePaywall middleware performs these checks automatically:
- Scheme matches
fhe-confidential-v1 - Chain ID matches server's expected chain
- Nonce is fresh (not seen before)
ConfidentialTransferevent exists intxHashreceipt (from + to match)PaymentVerifiedevent exists inverifierTxHashreceiptminPricein the event >= server's required price- Block confirmations >=
minConfirmations - Payment header size < 100KB
Facilitator Server
MARC Protocol includes a facilitator server compatible with the x402 facilitator specification:
import { createFacilitatorServer } from "marc-protocol-sdk";
const app = await createFacilitatorServer({
tokenAddress: "0xE944754aa70d4924dc5d8E57774CDf21Df5e592D",
verifierAddress: "0x4503A7aee235aBD10e6064BBa8E14235fdF041f4",
rpcUrl: "https://sepolia.infura.io/v3/YOUR_KEY",
apiKey: process.env.API_KEY,
});
app.listen(3001);
// Endpoints:
// GET /info — scheme info + contract addresses
// POST /verify — verify ConfidentialTransfer + PaymentVerified events
// GET /health — health checkWire Format Types
interface FhePaymentRequired {
x402Version: number;
accepts: FhePaymentAccept[];
}
interface FhePaymentAccept {
scheme: "fhe-confidential-v1";
network: string; // "eip155:11155111"
chainId: number;
price: string; // USDC in 6-decimal units
asset: string; // "USDC"
tokenAddress: string; // ConfidentialUSDC
verifierAddress: string; // X402PaymentVerifier
recipientAddress: string;
}
interface FhePaymentPayload {
scheme: "fhe-confidential-v1";
txHash: string;
verifierTxHash: string;
nonce: string;
from: string;
chainId: number;
}