Minimal Express TypeScript server with x402 402 paywall.
- Requires USDC payment to access
GET /weather?city=.... - Price:
$0.001onbase-sepolia. - Weather data from Open-Meteo (no API key required).
cd weather
# create .env with your receiver address
cat > .env <<'EOF'
PAY_TO=0x0000000000000000000000000000000000000000
PORT=3100
TARGET_URL=http://localhost:3100/weather?city=San%20Francisco
# PRIVATE_KEY: used by header generator script
PRIVATE_KEY=
EOF
npm i
npm run devOpen http://localhost:3100/weather?city=San%20Francisco.
Without payment, you should get HTTP 402 with payment requirements or a paywall page.
After paying with an x402 client, the response will be weather JSON for the requested city.
- Request without payment (JSON):
curl -i -H "Accept: application/json" "http://localhost:3100/weather?city=Paris"- Request with paywall HTML (browser-like Accept):
curl -i "http://localhost:3100/weather?city=Paris"- After generating an x402 payment header, include it to get weather:
# Replace <BASE64_XPAYMENT> with the value produced by the payment header script
curl -i -H 'X-PAYMENT: <BASE64_XPAYMENT>' "http://localhost:3100/weather?city=Paris"- Pretty-print the 402 JSON response:
curl -s -H "Accept: application/json" "http://localhost:3100/weather?city=Paris" | jq .- Configure payer credentials (testnet):
# set PRIVATE_KEY to the payer EVM private key (Base Sepolia recommended)
# set TARGET_URL if different- Generate header:
npm run payment:header
# outputs a long Base64 string- Use the header with curl:
HEADER=$(npm run -s payment:header)
curl -i -H "X-PAYMENT: $HEADER" "$TARGET_URL"Notes:
- The script first fetches
/weatherto readacceptsfrom the 402 JSON, then signs anexactEVM payment usingPRIVATE_KEYand prints the header. - Works by default for
base-sepolia.