Demonstrates the one-time payment flow using a TIP-20 token transfer on the Tempo testnet (Moderato, chainID=42431).
- Client sends
GET /api/report— no credentials. - Server responds
402 Payment Required+WWW-Authenticatechallenge. - Client builds and signs a TIP-20 transfer transaction off-chain.
- Client retries with
Authorization: Payment <credential>. - Server broadcasts the transaction, waits for confirmation, verifies the
Transferevent. - Server responds
200 OK+ report JSON +Payment-Receiptheader.
- Go 1.25+
- A funded Tempo testnet wallet (alphaUSD balance ≥ 0.10)
- The recipient address to receive payments
Create examples/tempo/charge/server/.env:
MPP_SECRET_KEY=your-secret-key-here
RECIPIENT_ADDRESS=0xYourRecipientAddressHere
ADDR=:8087| Variable | Required | Description |
|---|---|---|
RECIPIENT_ADDRESS |
Yes | Address that receives the alphaUSD payment |
MPP_SECRET_KEY |
No | HMAC key for challenge signing (default: insecure demo key) |
ADDR |
No | Listen address (default: :8087) |
Create examples/tempo/charge/client/.env:
CLIENT_PRIVATE_KEY=0xYourPrivateKeyHere
SERVER_URL=http://localhost:8087| Variable | Required | Description |
|---|---|---|
CLIENT_PRIVATE_KEY |
Yes | 0x-prefixed private key of the paying wallet |
SERVER_URL |
No | Charge server URL (default: http://localhost:8087) |
go run ./examples/tempo/charge/serverOr with inline env vars:
RECIPIENT_ADDRESS=0xYourAddress MPP_SECRET_KEY=my-secret go run ./examples/tempo/charge/serverIn a separate terminal:
go run ./examples/tempo/charge/clientOr with inline env vars:
CLIENT_PRIVATE_KEY=0xYourPrivateKey go run ./examples/tempo/charge/clientThe server logs each step of the payment flow — you can see the unauthenticated request, the 402 challenge, the authenticated retry, and the 200 response:
The client logs each step of the charge flow — challenge received, transaction built, submitted, and receipt obtained:
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/api/health |
None | Free health check |
GET |
/api/report |
Payment | One-time charge: 0.10 alphaUSD |
The server charges 100,000 base units = 0.10 alphaUSD (6 decimals).
Change the amount in examples/tempo/charge/server/main.go:
result := srv.Handle(r, chargeMethod, map[string]any{
"currency": tempo.TokenAlphaUSD,
"amount": "100000", // 0.10 alphaUSD (6 decimals)
"description": "Tempo report — 0.10 alphaUSD",
})
