# x402 v2 Buyer Quickstart

Use this guide to pay for one `verify_company` call with a buyer-controlled wallet. The service
never asks for an API key or custody of the buyer's private key.

## Production payment contract

- MCP endpoint: `https://israel-counterparty-intelligence.vercel.app/mcp`
- REST endpoint: `https://israel-counterparty-intelligence.vercel.app/v1/verify/mainnet`
- Network: Base Mainnet (`eip155:8453`)
- Asset: native Base USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`)
- Price: `0.05 USDC` per successful `verify_company` call
- Protocol: x402 v2, exact EVM payment
- Authentication: none

The buyer needs its own Base Mainnet wallet, enough native USDC for the call, and enough ETH for
any wallet-side transaction costs. Do not paste a private key into a website or send it to this
service.

## MCP: automatic payment and retry

Install the official MCP/x402 client packages in the buyer application:

```bash
npm install @modelcontextprotocol/sdk @x402/core @x402/evm @x402/mcp viem
```

Create a wallet account in the buyer's own secret-management environment, then wrap a standard MCP
client with the x402 v2 payment client:

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { x402Client } from "@x402/core/client";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { wrapMCPClientWithPayment } from "@x402/mcp";
import { privateKeyToAccount } from "viem/accounts";

const privateKey = process.env.BUYER_PRIVATE_KEY;
if (!privateKey?.startsWith("0x")) throw new Error("BUYER_PRIVATE_KEY is required");

const account = privateKeyToAccount(privateKey as `0x${string}`);
const baseMcpClient = new Client({ name: "buyer-agent", version: "1.0.0" });
const paymentClient = new x402Client()
  .registerPolicy((_version, requirements) =>
    requirements.filter(
      (requirement) =>
        "amount" in requirement &&
        requirement.network === "eip155:8453" &&
        requirement.asset.toLowerCase() === "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913" &&
        BigInt(requirement.amount) <= 50_000n,
    ),
  )
  .register("eip155:8453", new ExactEvmScheme(account));

const client = wrapMCPClientWithPayment(baseMcpClient, paymentClient, {
  autoPayment: true,
  onPaymentRequested: async ({ paymentRequired }) =>
    paymentRequired.accepts.some(
      (requirement) =>
        "amount" in requirement &&
        requirement.network === "eip155:8453" &&
        BigInt(requirement.amount) <= 50_000n,
    ),
});

await client.connect(
  new StreamableHTTPClientTransport(
    new URL("https://israel-counterparty-intelligence.vercel.app/mcp"),
  ),
);

const result = await client.callTool("verify_company", {
  company_number: "514744887",
  language: "en",
});

console.log(result.content);
console.log(result.paymentResponse?.transaction);
```

The first tool call receives a structured x402 v2 `PaymentRequired`. The wrapper signs the selected
requirement, retries the same call with `_meta["x402/payment"]`, and exposes the settlement receipt
from `_meta["x402/payment-response"]`.

## REST: protocol sequence

Send the request once without a payment header to receive HTTP `402` and the base64-encoded
`PAYMENT-REQUIRED` header. An x402 v2 HTTP client must select an acceptable requirement, sign it,
and retry the identical request with `PAYMENT-SIGNATURE`. A successful paid response is HTTP `200`
and includes `PAYMENT-RESPONSE` with the settlement receipt.

```bash
curl -i https://israel-counterparty-intelligence.vercel.app/v1/verify/mainnet \
  -H 'content-type: application/json' \
  --data '{"company_number":"514744887","language":"en"}'
```

Expected unpaid result: HTTP `402`, x402 version `2`, Base Mainnet, native USDC, amount `50000`
(USDC has six decimals), and the server-owned receiving address. Reject the payment if any of those
values differ.

## Successful-call checklist

A completed call has all of the following:

1. The buyer signed the x402 v2 requirement with its own external wallet.
2. The facilitator verified the signature.
3. The service returned a successful MCP tool result or REST HTTP `200`.
4. `x402/payment-response` or `PAYMENT-RESPONSE` reports a successful settlement and transaction.
5. The Base Mainnet transaction transferred real USDC to the advertised receiving address.

If the client can list MCP tools but stops at `PaymentRequired`, it is not yet using an x402-aware
MCP payment wrapper or its payment policy rejected the network, asset, or 0.05 USDC amount.
