c402 developer docs
Everything to build, call, and verify confidential compute over x402. No accounts, no API keys - bring a wallet.
Introduction
c402 is a confidential compute layer that sits on top of x402 the same way x402 sits on top of HTTP. It lets any server publish a TEE-attested confidential endpoint that any client can pay for and verify - adding exactly two HTTP headers on top of x402.
| Layer | Question | Mechanism |
|---|---|---|
| HTTP | give me a resource | request / response |
| x402 | pay to access a resource | 402 + PAYMENT-REQUIRED |
| c402 | pay to access a private thought | x402 + 2 headers |
The confidential computation runs inside an iExec Nox (Intel TDX) TEE. Inputs, state, and reasoning stay encrypted; the fact that an attested decision happened stays publicly verifiable on-chain.
Two ways to use c402
Before you install anything, figure out which of these you are. They need completely different setup - most people start as a consumer.
| Path 1 - Consume | Path 2 - Build your own | |
|---|---|---|
| You want to | pay a confidential endpoint and get + verify the private result | run your own confidential service others pay |
| You need | a wallet + a little Sepolia USDC | a wallet, a Sepolia RPC, and to deploy your own engine |
| Contracts to deploy | none - reuse what's already live | your own CDE + DecisionRegistry |
| Server to run | none - call a live endpoint | your c402 server (cde-api-style) |
Path 1 - Consume (start here). There are no accounts and no API keys: you authenticate by paying. Bring a wallet with a little Sepolia USDC (free from a faucet), point it at a live c402 endpoint, and you get the attested result back - re-verifiable against the already-deployed registry. Nothing to deploy.
# decode the 402 handshake (no wallet needed)
npx @c402/cli inspect <endpoint-url>
# pay with your wallet, get the attested result + on-chain verification
npx @c402/cli call <endpoint-url> --key $C402_KEY --rpc $SEPOLIA_RPC_URL \
--body '{"exposure":6000,"signal":50}'Path 2 - Build your own. To become a provider you deploy your own CDE + DecisionRegistry (the on-chain decrypt permission is tied to your runtime key, so you can't reuse someone else's), then run your c402 server pointing at those addresses. One command scaffolds the contracts - see Self-host & deploy.
Installation
c402 is a pnpm monorepo that runs TypeScript directly on Node 22+ (no build step). Install the protocol packages you need:
pnpm add @c402/server # build a confidential endpoint pnpm add @c402/client # call one from an agent pnpm add @c402/verify # verify an attestation # the terminal tool - no install needed npx @c402/cli --help
To run the full reference stack (facilitator + treasury/payroll servers + control plane) from a clone, follow docs/setup-deploy-usage.md.
Quickstart
Call a live c402 endpoint from the terminal in one command (needs a wallet key with a little Sepolia USDC):
# 1. decode a c402 endpoint's 402 handshake (no wallet needed)
npx @c402/cli inspect http://localhost:4021/v1/decide
# 2. pay it with your wallet, get the attested result + on-chain verification
npx @c402/cli call http://localhost:4021/v1/decide \
--key $C402_KEY --rpc $SEPOLIA_RPC_URL \
--body '{"exposure":6000,"signal":50}'The two headers
c402 is intentionally minimal. On an unpaid request a c402 server returns HTTP 402 with both:
- PAYMENT-REQUIRED - the standard x402 header (price, token, network).
- Compute-Required - the confidential computation: TEE standard, compute contract, input/output schema.
On a paid request it returns 200 with the x402 PAYMENT-RESPONSE and a c402 X-Attestation. Everything else - what the computation means - is up to the server.
Attestation & verification
The X-Attestation is not a trust-us blob. Every field is a real, independently re-verifiable on-chain artifact: decisionId, commitment, registry, tx, output handles. A verifier re-reads the commitment from chain and confirms it matches - no cooperation from the server.
Verification proves a confidential decision happened and matches its commitment. It never reveals the private result - that stays ACL-encrypted to the authorized runtime.
Confidentiality model
Nox provides confidentiality of values, not anonymity of addresses. Calls and addresses stay public; the values - inputs, encrypted state, and the decision itself - are encrypted. Never claim anonymity.
No accounts, no API keys
c402 inherits x402's model: no signup, no accounts, no API keys. The caller authenticates by paying - signing an EIP-3009 authorization with their wallet. The --key a client uses is a wallet private key, not an issued token. The wallet needs the settlement token (e.g. Sepolia USDC), not gas - the facilitator relays.
@c402/server
Declare a confidential, pay-per-call endpoint in one function. The middleware handles the 402, both headers, payment verification, TEE execution, and the attestation.
import express from "express";
import { c402 } from "@c402/server";
const app = express();
app.use(express.json());
app.post("/decide", c402({
price: "0.01", // human USDC price
token: USDC_SEPOLIA, // EIP-3009 settlement token
network: "eip155:11155111", // CAIP-2
facilitator: FACILITATOR_URL, // x402 facilitator
payTo: PAY_TO,
contract: CDE, // on-chain confidential-compute contract
schema: { input: "euint256", output: "treasury-action" },
compute: async (input, ctx) => {
// runs inside the iExec Nox TEE; return the result + on-chain artifacts
return { result, decisionId, commitment, registry, tx, outputHandles };
},
}));@c402/client
Call a c402 endpoint like a normal fetch. It reads Compute-Required, pays via x402, reads X-Attestation, and re-verifies on-chain - invisibly.
import { privateKeyToAccount } from "viem/accounts";
import { c402Fetch } from "@c402/client";
const call = c402Fetch({
signer: privateKeyToAccount(process.env.C402_KEY),
network: "eip155:11155111",
rpcUrl: process.env.SEPOLIA_RPC_URL,
});
const res = await call("https://server/decide", { body: { exposure: 6000, signal: 50 } });
res.result; // the computation output
res.attestation; // the TEE proof
res.verified.valid; // re-checked on-chain@c402/verify
A standalone verifier anyone can run - re-reads the on-chain commitment and confirms it matches.
import { verifyAttestation } from "@c402/verify";
const result = await verifyAttestation(attestation, { rpcUrl });
result.valid; // true / false
result.checks; // [{ name, ok, detail }] - registry-has-decision, commitment-matches, …@c402/cli
The generic terminal tool. Works against any c402 server.
| Command | What it does |
|---|---|
| c402 inspect <url> | decode the 402 handshake (no wallet) |
| c402 call <url> --body … | pay with your wallet, print the attested result |
| c402 verify --id <n> --registry <addr> | re-verify a decision on-chain, from just its id |
Guide: build a c402 server
A c402 app is a normal Express server with one c402({…}) endpoint. The path is yours to choose (/decide, /score, anything) - clients discover price and schema from the headers, not the URL. See examples/hello-c402 for a full server + client.
Guide: call it from an agent
An agent is a c402 client with a funded wallet. The request body is app-defined - the treasury endpoint wants { exposure, signal }, payroll wants { budget, requested }. Run c402 inspect to see the declared schema, then send the app's documented JSON.
Guide: self-host & deploy
The reference stack: a self-hosted x402 facilitator for eip155:11155111, the c402 servers, and the Next.js control plane. The frontend is read-only (no private key) and deploys to Vercel; the servers sign transactions and need a funded key that must live on the server host - never on Vercel, never committed.
1. Deploy your own confidential engine. One command builds the Nox contracts and deploys your own CDE + DecisionRegistry to Sepolia (needs SEPOLIA_RPC_URL + SEPOLIA_PRIVATE_KEY in .env):
pnpm run deploy:own # prints the deployed addresses (also written to docs/deployments.sepolia.json). # copy them into .env: # CDE_ADDRESS=0x... # DECISION_REGISTRY_ADDRESS=0x...
2. Run your c402 server. Point it at your addresses and start the facilitator + server:
pnpm --filter @c402/facilitator start # relays payment on-chain (port 4022) pnpm --filter @c402/cde-api start # your c402 endpoint (port 4021)
3. Host it publicly (optional). To let anyone test your endpoint, deploy the facilitator + server as one always-on service. The repo ships a render.yaml blueprint and a scripts/start-public-endpoint.ts launcher that runs both in one Render web service, plus public-endpoint guardrails (per-IP rate limit, daily cap, and a low-gas graceful 503) so a throwaway wallet stays funded. A GitHub Actions keep-alive pings /health so the free tier doesn't sleep. Set your public URL as NEXT_PUBLIC_CDE_URL on Vercel and the inspector + CLI will hit it live.
Full walkthroughs: setup-deploy-usage.md and vercel-deploy.md.
Reference: Compute-Required
Base64url JSON on the 402. The client reads this to know what to encrypt and what to expect.
{
"version": "c402/1",
"tee": "iexec-nox/intel-tdx",
"network": "eip155:11155111",
"contract": "0x…CDE",
"input": { "schema": "euint256", "encoding": "plaintext" },
"output": { "schema": "treasury-action" },
"description": "Confidential treasury decision"
}Reference: X-Attestation
Base64url JSON on the paid 200. Every field is a real on-chain artifact.
{
"version": "c402/1",
"standard": "iexec-nox/intel-tdx",
"network": "eip155:11155111",
"contract": "0x…CDE",
"decisionId": "13",
"commitment": "0x…",
"registry": "0x…DecisionRegistry",
"tx": "0x…",
"outputHandles": { "action": "0x…" },
"issuedAt": 1750000000000
}Reference: response envelope
Every c402 response body is the same envelope, whatever the app:
{
"result": { /* the app's output */ },
"attestation": { /* the X-Attestation object */ }
}Full spec: SPEC.md · JSON schema: packages/c402-spec/schema/attestation.schema.json.