Documentation

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.

LayerQuestionMechanism
HTTPgive me a resourcerequest / response
x402pay to access a resource402 + PAYMENT-REQUIRED
c402pay to access a private thoughtx402 + 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 - ConsumePath 2 - Build your own
You want topay a confidential endpoint and get + verify the private resultrun your own confidential service others pay
You needa wallet + a little Sepolia USDCa wallet, a Sepolia RPC, and to deploy your own engine
Contracts to deploynone - reuse what's already liveyour own CDE + DecisionRegistry
Server to runnone - call a live endpointyour 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}'
Prefer clicking? The inspector does decode → pay → verify in the browser. If no public endpoint is running yet, it walks you through starting one locally.

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}'
Prefer clicking? The inspector does decode → pay → verify in the browser.

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.

Use a dedicated, funded test wallet for automation - never a main key in a shell env.

@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.

CommandWhat 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.

The public endpoint holds a throwaway faucet wallet only - a few dollars of Sepolia USDC and a little gas. Never put a real key on a public server, and never on Vercel.

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.

c402 · Confidential compute over x402
Composes x402 · iExec Nox · Safe · Uniswap - unmodified, on Ethereum Sepolia