# Buy one Energy Hub response in under five minutes

The paid endpoints use x402 v2 with canonical USDC on Base Mainnet. The buyer signs an EIP-3009 `TransferWithAuthorization`; the facilitator submits the on-chain transaction, so the buyer needs USDC but no ETH for gas.

## Node.js

Prerequisite: Node.js 20 or newer and a Base wallet holding at least 0.001 USDC.

```bash
mkdir energy-hub-buyer && cd energy-hub-buyer
npm init -y
npm install viem
curl -fsS https://energy.netzhandwerker.de/examples/eip3009-payment.mjs -o eip3009-payment.mjs
curl -fsS https://energy.netzhandwerker.de/examples/buy-nodejs -o buy-nodejs.mjs
PRIVATE_KEY=0xYOUR_PRIVATE_KEY node buy-nodejs.mjs
```

The runnable source is also available directly at https://energy.netzhandwerker.de/examples/buy-nodejs.

## Python

```bash
python3 -m venv .venv
. .venv/bin/activate
pip install requests web3 eth-account
curl -fsS https://energy.netzhandwerker.de/examples/buy-python -o buy-python.py
PRIVATE_KEY=0xYOUR_PRIVATE_KEY python buy-python.py
```

## curl plus signing helper

`curl` can send the two HTTP requests, but it cannot create an EIP-712 signature by itself. The published viem helper performs only that signing step.

```bash
mkdir energy-hub-curl && cd energy-hub-curl
npm init -y
npm install viem
curl -fsS https://energy.netzhandwerker.de/examples/buy-curl -o buy-curl.sh
chmod +x buy-curl.sh
PRIVATE_KEY=0xYOUR_PRIVATE_KEY ./buy-curl.sh
```

## Exact wire format

The first request returns HTTP 402. `Payment-Required` is base64-encoded JSON. The price is `accepts[0].amount` in token atomic units; for six-decimal USDC, `1000` is 0.001 USDC. The recipient is `accepts[0].payTo` and the EIP-712 domain is `accepts[0].extra.eip712Domain`.

After signing `from`, `to`, `value`, `validAfter`, `validBefore`, and the random 32-byte `nonce`, the buyer derives `v`, `r`, and `s`. The exact request header is:

```text
PAYMENT-SIGNATURE: base64(JSON({
  "x402Version": 2,
  "resource": { ...challenge.resource },
  "accepted": { ...selected accepts[] item },
  "payload": {
    "signature": "0x<65-byte EIP-712 signature containing r,s,v>",
    "authorization": { "from", "to", "value", "validAfter", "validBefore", "nonce" }
  }
}))
```

Retry the identical method, URL, and JSON body with that header. A valid payment returns HTTP 200 and `Payment-Response` contains the settlement result and transaction hash.

## Rejections

- Expired `validBefore`: request a fresh 402 and sign again; the old authorization is rejected.
- Wrong or changed `value`: the facilitator rejects the proof because it does not match the selected `accepts[]` entry.
- Insufficient USDC: the examples stop before sending a payment header after checking `balanceOf`; the facilitator also cannot settle an unfunded authorization.
- Reused `nonce`: every authorization is single-use; request a fresh challenge and generate a new random nonce.
- Safety limit: all examples default to `MAX_AMOUNT_UNITS=1000` and refuse a more expensive challenge unless the buyer raises that limit explicitly.

Never paste a private key into source code, a URL, a prompt, or a log. Supply it only through the local `PRIVATE_KEY` environment variable.
