402Guard is a TypeScript SDK that wraps x402 clients with a policy engine and a simple subscription layer on Avalanche.
You add one import, and your x402 calls gain spend limits, rate limits, usage quotas, subscription checks and invoices.
Built for the Avalanche x402 Hack2Build – Payments (Tooling & Infrastructure) track.
Demo : https://youtu.be/NHgjAU1azqM?si=ImlwDN02HNeC5K5b
x402 solves how to pay for APIs over HTTP with on-chain settlement.
What it does not solve is who is allowed to spend how much and under what rules.
If an AI agent or backend loop goes wrong, it can drain a wallet through valid x402 payments.
Teams also still need classic SaaS primitives like monthly plans, per-seat limits and usage-based tiers.
402Guard focuses on that missing safety and finance ops layer.
- Keep using your existing x402 helpers.
- Wrap them with 402Guard.
- Get budgets, quotas, subscriptions and invoices without re-implementing payments or smart contracts.
- Drop-in wrappers for
axiosandfetchthat understand x402. - Intercept
402 Payment Requiredresponses and handle payment, retry and logging. - Enforce local spend and rate limits before signing any payment request.
- Works with plain 200 flows and x402 flows through the same interface.
- Global daily and monthly spend caps per wallet or agent.
- Per-service and per-endpoint budgets and request rates.
- Simple estimation hook:
estimateUsdForRequest(config). - Soft and hard thresholds with room for future alert hooks or webhooks.
- Minimal Solidity contract
Guard402Subscriptions.solthat tracks:- subscription plans (plan id, price, caps, metadata)
- active subscribers (address, plan, expiry)
- TypeScript wrapper that exposes:
createPlan,updatePlansubscribe,cancelisActive,getPlan
- Ready to back usage-based subscriptions where the on-chain plan is the source of truth and 402Guard is the local policy and analytics brain.
- In-memory store for quick experiments and tests.
- File or SQLite backed store for small production setups.
- Simple
UsageStoreinterface so you can plug in Postgres, Redis or any internal billing database. - Helpers to aggregate spend by service, agent and subscription.
- Network helpers wired for Avalanche Fuji testnet.
- Contract deployment scripts using Foundry.
- Designed to work with Avalanche-compatible x402 facilitators (example: thirdweb in the final demo).
- Policy engine that works across many merchants, not just one endpoint.
- Subscription registry plus invoices that are on-chain anchored but still app-friendly.
- Self-hosted analytics pages that any team can run next to their agents and APIs.
402Guard is split into small packages so you can adopt only what you need.
-
@402guard/client
Guarded HTTP clients and the policy engine. Wraps an axios instance and x402 helpers. -
@402guard/subscriptions
Solidity subscription contract plus TypeScript bindings and helpers to talk to it. -
@402guard/server(planned)
Express middlewares and helpers to build x402-enabled APIs with subscription checks on the server side.
- Provider deploys
Guard402Subscriptionson Avalanche Fuji. - Provider protects premium endpoints with a subscription check on the server side.
- Client wraps its x402-aware HTTP client with
createGuardedAxios. - When the provider responds with HTTP 402, 402Guard:
- checks policies and subscription state
- calls a facilitator if allowed
- retries the request with x402 payment headers
- All usage is recorded in a
UsageStoreand visible through invoices and summaries.
402guard/
apps/
web/ # Next.js demo app
src/app/200/ # Simple capped axios demo
src/app/x402-demo/ # x402 quote + payment + retry demo
src/app/subscriptions-demo/ # subscription caps + invoice demo
packages/
client/ # @402guard/client
src/policies.ts
src/store.ts
src/analytics.ts
src/x402.ts
subscriptions/ # @402guard/subscriptions
src/chain.ts # viem based contract wrapper
src/index.ts # helpers + invoice generator
contracts/
guard402-subscriptions/ # Foundry project for Guard402Subscriptions.sol
src/Guard402Subscriptions.sol
script/Deploy.s.sol
From the repo root:
# install workspace dependencies
bun install
# or
npm installFor contracts you also need Foundry:
# if you do not have foundryup yet
curl -L https://foundry.paradigm.xyz | bash
foundryupCreate a .env file at the repo root:
# Avalanche Fuji RPC (public RPC works for testing)
AVALANCHE_FUJI_RPC=https://api.avax-test.network/ext/bc/C/rpc
# optional, only if you want contract verification
SNOWTRACE_API_KEY=your_key_hereFor script-based deployment you also need a private key (test key only):
# never put a real mainnet key here
DEPLOYER_PRIVATE_KEY=0xabc123...Inside the contracts folder:
cd contracts/guard402-subscriptions
# install dependencies (openzeppelin, forge-std)
forge install
# check that compilation works
forge build
# deploy to Fuji using the rpc alias from foundry.toml
forge script script/Deploy.s.sol \
--rpc-url fuji \
--broadcastThe script will print the Guard402Subscriptions address.
Copy that into packages/subscriptions/src/Guard402Subscriptions.json (or your config file).
From the repo root:
cd apps/web
bun dev
# or
npm run devThen open:
http://localhost:3000/200– basic capped axios demohttp://localhost:3000/x402-demo– x402 402→pay→200 flow with CSV invoicehttp://localhost:3000/subscriptions-demo– subscription plans, daily caps and JSON invoices
import axios from "axios";
import { createGuardedAxios } from "@402guard/client";
const axiosInstance = axios.create();
const http = createGuardedAxios({
axiosInstance,
agentId: "my-agent-1",
policies: {
services: {
"api.myservice.com": {
dailyUsdCap: 5.0, // at most 5 USD per day for this service
},
},
global: {
monthlyUsdCap: 100.0, // optional global cap
},
},
// very simple estimator for the demo
estimateUsdForRequest: () => 0.01,
});async function fetchProfile() {
const res = await http.guardedRequest({
url: "https://api.myservice.com/profile",
method: "GET",
});
console.log(res.data);
}If the caps are exceeded, guardedRequest throws an error with a guard402 field:
try {
await fetchProfile();
} catch (err: any) {
if (err.guard402) {
console.error("Blocked by 402Guard:", err.guard402.reason);
} else {
console.error("Network error:", err);
}
}To use x402, you plug your existing facilitator hooks into 402Guard.
import {
pickFirstOption,
estimateUsdFromQuote,
payWithX402Local, // or your real facilitator wrapper
} from "@402guard/client";
const x402Http = createGuardedAxios({
agentId: "x402-demo-agent",
policies: {
services: {
"my-x402-api.com": {
dailyUsdCap: 1.0, // 1 USD per day
},
},
},
estimateUsdForRequest: undefined, // price comes from x402 quote
facilitatorId: "thirdweb-demo",
selectPaymentOption: pickFirstOption,
estimateUsdFromQuote,
payWithX402: payWithX402Local, // replace with real thirdweb integration
});
async function callPaidEndpoint() {
const res = await x402Http.guardedRequest({
url: "https://my-x402-api.com/endpoint",
method: "GET",
});
console.log(res.data);
}The client:
- Sends the request.
- Receives HTTP 402 plus an x402 quote.
- Checks local caps.
- Calls the facilitator.
- Retries the request with payment headers.
- Records usage in the UsageStore.
The subscription contract lives on Avalanche and tracks which address is on which plan and until when. 402Guard then applies additional caps per subscription id on top of the raw wallet-based policies.
import {
createSubscriptionAxios,
generateInvoice,
} from "@402guard/subscriptions";
const client = createSubscriptionAxios({
subscriptionId: "sub-starter", // logical id for this user or team
policies: {
global: {
dailyUsdCap: 0.03, // 3 calls at 0.01 USD
},
},
estimateUsdForRequest: () => 0.01,
});
await client.guardedRequest({
url: "https://jsonplaceholder.typicode.com/todos/1",
method: "GET",
});import type { UsageStore } from "@402guard/client";
const store = client.guard.store as UsageStore;
const todayStart = new Date();
todayStart.setHours(0, 0, 0, 0);
const todayEnd = new Date();
todayEnd.setHours(23, 59, 59, 999);
const invoice = generateInvoice({
store,
subscriptionId: "sub-starter",
periodStart: todayStart,
periodEnd: todayEnd,
});
console.log(JSON.stringify(invoice, null, 2));The subscriptions-demo page in the Next.js app does exactly this and exposes a Download invoice (today) button.
MIT