Skip to content

feat(client): add spending policy for x402 payments#40

Open
Bortlesboat wants to merge 1 commit intomicrochipgnu:mainfrom
Bortlesboat:feat/client-spending-policy
Open

feat(client): add spending policy for x402 payments#40
Bortlesboat wants to merge 1 commit intomicrochipgnu:mainfrom
Bortlesboat:feat/client-spending-policy

Conversation

@Bortlesboat
Copy link
Copy Markdown

Adds client-side spending controls that sit between x402 402-negotiation and payment signing. Addresses #31.

What it does

SpendingTracker evaluates configurable rules before any payment is signed:

  • Rolling budgetsmaxPerHour / maxPerDay (atomic units, in-memory window)
  • Rate limitingmaxTransactionsPerHour
  • Per-transaction capmaxPerTransaction (works alongside existing maxPaymentValue)
  • Per-tool capstoolLimits map for different spending ceilings per tool name
  • Recipient controlsallowedRecipients / blockedRecipients address lists

The tracker records successful payments and prunes entries older than 24h.

SDK usage

const paymentClient = withX402Client(client, {
  wallet: { evm: signer },
  policy: {
    maxPerHour: BigInt(1_000_000),      // 1 USDC/hour
    maxPerDay: BigInt(10_000_000),       // 10 USDC/day
    maxTransactionsPerHour: 20,
    blockedRecipients: ["0xdead..."],
    toolLimits: {
      "expensive_tool": BigInt(5_000_000),
    },
  },
});

CLI usage

npx mcpay connect \
  --urls https://mcpay.tech/v1/mcp/... \
  --evm 0x... \
  --max-per-hour 1000000 \
  --max-per-day 10000000 \
  --max-tx-per-hour 20

Also reads X402_MAX_PER_HOUR, X402_MAX_PER_DAY, X402_MAX_TX_PER_HOUR env vars.

Design decisions

  • In-memory only — no database or external state. Resets on process restart, which is fine for a client-side guardrail. Persistent tracking belongs in the proxy/server layer.
  • Opt-in — no policy config means zero behavioral change.
  • Evaluate before sign, record after success — failed payments don't count toward budgets.
  • Policy violations return isError: true with a descriptive message, same pattern as the existing maxPaymentValue check.

Type-checks clean against the existing codebase.

Adds a SpendingTracker that evaluates configurable spending rules
before signing any x402 payment. Supports rolling hourly/daily budgets,
per-transaction and per-tool caps, rate limiting, and recipient
allow/block lists. Fully opt-in — no policy configured means existing
behavior is unchanged.

Also exposes --max-per-hour, --max-per-day, --max-tx-per-hour CLI flags
for the connect command.

Closes microchipgnu#31
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 28, 2026

@Bortlesboat is attempting to deploy a commit to the Inventions Hub Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant