Two spend-safety fixes from the gap audit (#4814):
- Client.Do refused a 402 only on the budget check, but parsed
maxAmountRequired with a swallowed error, so a non-decimal, overflowing
or negative amount became 0 and passed the cap trivially while Payer.Pay
still signed against the string. Now reject any amount that is not a
positive integer before signing.
- Require settled only when the facilitator implemented Settler; a
verify-only facilitator served the resource while no funds moved. Add
Config.RequireSettlement to fail closed in that case.
Tests cover invalid/negative/overflow amounts and the verify-only
fail-closed path.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
The x402 wrapper could advertise a 402 and verify a payment, but never
settled it (the "exact" scheme needs verify + settle to actually move
funds), and its HTTPFacilitator sent no auth, so it could not use the
Coinbase CDP facilitator — the only one that settles Base mainnet. It
also passed the raw base64 X-PAYMENT string where facilitators expect the
decoded payload object.
- Add an optional Settler interface; HTTPFacilitator now implements
Verify and Settle (POST /verify then /settle), and Require settles a
verified payment and emits the settlement reference.
- HTTPFacilitator.Authorize hook + x402.CDP(keyID, secret) constructor:
mint a short-lived Ed25519 Bearer JWT (stdlib crypto only, no chain
code, no new dependency) so verify/settle authenticate to CDP.
- Decode the X-PAYMENT payload to the object facilitators expect, with
passthrough for non-JSON payloads.
- Requirements gains extra (EIP-712 domain) and mimeType; the asset and
its {name,version} are auto-filled for known networks so clients can
sign. NormalizeNetwork maps base/base-sepolia to CAIP-2 ids.
- Accept the v2 PAYMENT-SIGNATURE request header and emit both
X-PAYMENT-RESPONSE and PAYMENT-RESPONSE.
Backward compatible: the default network stays "base", the Facilitator
interface is unchanged (Settler is additive), and gateway/mcp builds and
tests unchanged. Adds tests for settle, CDP JWT, header aliases, extra,
and payload decoding.
Fixes#2988. Brings 'golangci-lint run ./...' to zero issues (was ~373):
- errcheck: explicitly ignore fire-and-forget calls with '_ =' (and a small
errcheck.exclude-functions list for response writes — json Encoder.Encode,
http ResponseWriter.Write, fmt.Fprint*); genuine cases handled.
- unused: remove dead code (unexported decls and dead test helpers) and the
imports they orphaned.
- staticcheck: ST1005 error strings, ST1016 receiver names, S1000/S1017/S1019/
S1023 simplifications, SA4004/SA4006/SA4010 dead code, SA1021 net.IP.Equal,
SA6002 (store *[]byte in sync.Pool).
- govet: fix a context leak (lostcancel) in internal/util/mdns and move
t.Fatal/Fatalf out of goroutines (testinggoroutine) in tests.
- ineffassign, unconvert: mechanical fixes.
CI: the Lint workflow now runs a blocking full-tree 'golangci-lint run' on
pushes and PRs (dropped only-new-issues now that the tree is clean).
Verified: go build, go vet, test compilation, and unit tests for the
behaviourally-touched packages all pass.
Claude-Session: https://claude.ai/code/session_01CmdEY7pYmV5zzwCjNJ4ykL
Co-authored-by: Claude <noreply@anthropic.com>
* feat(mcp): advertise x402 payment requirements in the tool catalog
/mcp/tools now includes each priced tool's payment requirements (amount,
network, asset, payTo) when payments are enabled, so an agent can see the
cost before calling and choose by price — a shoppable catalog, the
foundation for a tool marketplace. Free tools carry no payment block; the
shared Tool struct is copied when pricing so it isn't mutated. Tests cover
priced/free tools and payments-disabled. Documented in the payments guide.
* feat(x402): consumer client with a spend budget (pay-and-retry)
Add x402.Client, the consumer counterpart to Middleware: it settles 402
challenges automatically via a pluggable Payer, up to a spend Budget. A
call that would exceed the budget is refused before any payment is made,
and spend accumulates across calls — the spend cap that keeps an
autonomous, paying caller in bounds. Tests cover pay-within-budget,
refuse-over-budget, budget accumulation, and free endpoints, end to end
against the server Middleware with a mock facilitator and payer. Guide
documents the consumer side; agent-level AgentMaxSpend is the next step.
* chore: gofmt gateway/mcp/benchmark_test.go (trailing newline)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Follow-up to the merged x402 integration (#2964). Drop the commerce-y
'price' vocabulary for the protocol's own 'amount', and add per-tool
pricing as an operator concern (the way scopes/rate-limits are set at the
gateway).
- x402.Config: Price -> Amount (default), plus Amounts map for per-tool
overrides; AmountFor(tool) resolves per-tool -> default. Add a Require
primitive (per-request enforcement) and LoadConfig for an operator
config file.
- MCP gateway: enforce payment per-tool inside /mcp/call (where scopes
are enforced) using AmountFor, instead of a flat path-based middleware.
- CLI: --x402-price -> --x402-amount; add --x402-config (per-tool file)
to micro mcp serve and micro-mcp-gateway.
- docs: new Payments (x402) guide + nav + README section; blog/22
updated to Amount/Amounts and the config-file model.
Co-authored-by: Claude <noreply@anthropic.com>
Integrate the x402 payment protocol (HTTP 402) so a tool can require a
stablecoin payment and an agent can settle it — the next step after
autonomous agents (blog 21): agents that act, and pay.
- wrapper/x402: HTTP middleware enforcing the 402 challenge/verify flow,
with a pluggable Facilitator interface. Go Micro carries no chain or
crypto code — verification/settlement is delegated to a facilitator
(Coinbase CDP, Alchemy, self-hosted), so Base and Solana are just
different facilitators behind one interface. HTTPFacilitator default;
tests cover challenge / accept / reject via a mock facilitator.
- MCP gateway: optional Options.Payment gates /mcp/call (listing tools
and health stay free); off unless configured.
- micro mcp serve and micro-mcp-gateway: opt-in --x402-pay-to/-price/
-network/-facilitator flags (env vars on the standalone binary).
- blog/22 'Integrating x402: Payments for Agents'; README feature row.
Pricing is flat per call for now; richer models and an agent-side spend
cap (next to MaxSteps/ApproveTool) are follow-ups.
Co-authored-by: Claude <noreply@anthropic.com>