Minimal Express API that accepts [x402](https://portal.thirdweb.com/x402) payments using thirdweb’s `settlePayment` and facilitator. Configured with a custom **Chain 138** definition; by default uses **Arbitrum Sepolia** and USDC so you can test without a Chain 138 token that supports permit.
## Prerequisites
- Node.js 18+
- [thirdweb](https://portal.thirdweb.com) account and **secret key** (Dashboard → Settings → API Keys)
- A server wallet address (EOA) that will receive payments
## Setup
```bash
cd x402-api
cp .env.example .env
# Edit .env: set THIRDWEB_SECRET_KEY and SERVER_WALLET_ADDRESS
npm install
```
## Run
```bash
npm start
# or with auto-reload
npm run dev
```
- **Health (no payment):** `GET http://localhost:4020/health`
- **Paid routes (402 until payment):** `GET http://localhost:4020/api/premium`, `GET http://localhost:4020/api/paid`
Clients must send payment authorization in the `PAYMENT-SIGNATURE` or `X-PAYMENT` header (e.g. using thirdweb’s `useFetchWithPayment` or equivalent).
x402 requires the payment token to support **ERC-2612 permit** or **ERC-3009** when using thirdweb facilitator. For **Alltra (651940)** we use **local verification** (no facilitator): server returns 402 + `PAYMENT-REQUIRED`, client pays USDC on 651940 and retries with `PAYMENT-SIGNATURE` + `txHash`; server verifies settlement on-chain. See [X402_ALLTRA_ENDPOINT_SPEC.md](../docs/04-configuration/X402_ALLTRA_ENDPOINT_SPEC.md).
- **Default:** The API uses **Arbitrum Sepolia** and default USDC so you can test without custom chains.
- **Alltra (651940) + USDC:** Set `X402_USE_ALLTRA=true` and `SERVER_WALLET_ADDRESS` in `.env`. Optional: `CHAIN_651940_RPC_URL`. Local verification is used; `THIRDWEB_SECRET_KEY` is not required for the Alltra path.
- **Chain 138:** Set `X402_USE_CHAIN_138=true` and optionally `RPC_URL_138` once a Chain 138 token has permit/ERC-3009 (see [CHAIN138_X402_TOKEN_SUPPORT.md](../docs/04-configuration/CHAIN138_X402_TOKEN_SUPPORT.md)).