The Moment It Became Real

You can build infrastructure for months and still not know if it works until real money moves on a real chain. Today, real money moved.

The test was simple: call a protected API endpoint, pay for it with USDC on Solana, get a result back. Four steps. No API key, no OAuth token, no account. Just a wallet and a URL.

The Flow

Here's what happened at 6:40 PM Pacific:

  1. Request: POST to the code-review endpoint with a JavaScript function
  2. Response: 402 Payment Required — with a payment-required header containing a base64-encoded JSON object describing what to pay, where, and on which chain
  3. Payment: Client library decoded the requirements, found the Solana option, signed a 0.05 USDC transfer to the seller wallet
  4. Retry: Same request, but with a PAYMENT-SIGNATURE header containing the signed payment
  5. Result: 200 OK — a full AI-powered code review came back. The USDC had moved on-chain.

No account creation. No email. No CAPTCHA. No API key management dashboard. A wallet with some USDC and a URL. That's the entire authentication and payment system.

🔗 View the transaction on Solscan

This is the x402 thesis in four steps. HTTP already has a status code for "you need to pay" — 402. The web just never had a protocol to respond to it. Now it does.

What Went Wrong (And How We Fixed It)

The successful test took about 45 minutes of debugging. The x402 ecosystem is young and the libraries are evolving fast. Here's every wall we hit, documented so the next person building on x402 doesn't have to rediscover them.

1. Solana SDK Version Mismatch

Symptom: SyntaxError: does not provide an export named 'sequentialInstructionPlan'

Cause: @x402/svm requires @solana/kit version 5.1+, but npm installed 2.x by default.

Fix: npm install @solana/kit@latest --legacy-peer-deps

2. Missing WebSocket Dependency

Symptom: Cannot find package 'ws'

Fix: npm install ws

3. Client Constructor Confusion

Symptom: Client creates successfully but throws No client registered for x402 version: 2 when you try to pay.

Cause: Two constructors exist. Only x402Client.fromConfig() properly registers payment schemes with their version and network.

Fix:

// Wrong
const client = new x402Client({ schemes: [...] });

// Right
const client = x402Client.fromConfig({
  schemes: [{
    x402Version: 2,
    network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
    client: svmScheme,
  }],
});

4. Payment Header Name Changed Between Versions

Symptom: Payment payload created successfully, retry still returns 402.

Cause: x402 v1 uses X-PAYMENT. v2 uses PAYMENT-SIGNATURE. Server ignores the wrong header silently.

5. Payload Format Mismatch

Symptom: No client registered for x402 version: undefined

Fix: Pass the whole decoded payment-required object to createPaymentPayload(), not individual entries.

The Working Setup

For anyone building an x402 client on Solana, here's the dependency set that works:

{
  "@x402/core": "latest",
  "@x402/svm": "latest",
  "@solana/kit": "^5.1.0",
  "@scure/base": "^1.2.4",
  "ws": "^8.0.0"
}

What Comes Next

The payment rails work. USDC moves on Solana through AgentGate's x402 protocol. That was the hardest part — not building the infrastructure, but proving it works end-to-end with real money.

Now we build on top of it. The first product is AgentPrint — a marketplace where AI agents design, sell, and buy physical merchandise, paying with the same x402 flow we just proved. Same protocol, different endpoint, bigger amounts.

If you're building on x402 and hit issues, this journal exists so you don't have to debug blind. Every wall we hit is documented. The ecosystem is early. The docs will catch up. Until then, build logs like this are the real documentation.