@warns/sdk
v0.1.1
Published
Stops an AI agent from making a payment it should not make. Guards x402 payments before anything is signed.
Maintainers
Readme
@warns/sdk
Stops an AI agent from making a payment it should not make.
Your agent pays over x402. A merchant can raise its price a thousand times, swap the address it gets paid at, ask for an authorization that stays valid for an hour, or slip an instruction into a response that your model obeys. Warns evaluates every payment against your policy before anything is signed, and refuses to sign what you did not approve.
npm i @warns/sdkEarly access. The hosted decision service is opening to the first testers. Ask for a key at warns.xyz.
import { createGuard } from "@warns/sdk"
const guard = createGuard({
apiKey: process.env.WARNS_KEY!,
agentId: "research-agent",
baseUrl: "https://api.warns.xyz",
rootAddress: "0xA26aa29cF9b429AD85E7a0F7FA6aBd8edE301e8a", // pinned; also served at https://api.warns.xyz/.well-known/warns-keys.json
})
// A drop-in replacement for the fetch you already pass to the x402 client.
const pay = guard.x402Fetch(signer, {
intent: () => ({ expectedMaxUsd: 0.05, purpose: "market-data" }),
})
const res = await pay("https://data.vendor.com/quote")What you get back
The guard throws rather than paying, so a refusal can never be mistaken for a success.
| Error | What happened |
| --- | --- |
| PaymentBlockedError | The payment was evaluated and refused. reasons says why, in plain language. |
| PaymentReviewRequiredError | A human has to approve it. Retry the same request after approval. |
| GuardConfigurationError | Your key, agent id or scope is wrong. Not a dangerous payment, a setup mistake. |
| GuardUnavailableError | The decision service was unreachable and your fallback rules do not cover this payment. |
| BindingViolationError | Something tried to sign a payment that no decision approved. |
It also guards the signer
guard.wrapSigner(signer) refuses any EIP-3009 authorization that does not match an approved
decision, field by field, and refuses Permit and Permit2 typed data outright. So a payment that
goes around the guarded fetch still cannot be signed.
When the decision service is down
By default the guard fails closed: no decision, no payment. If a short outage must not stop your agent, you can let small payments through under an hourly ceiling:
createGuard({
// ...
fallback: {
default: "closed",
rules: [{ maxUsd: 0.05, mode: "open_after_local_checks" }],
localBucket: { usdPerHour: 1 },
},
})Those payments still pass the local checks (asset, amount, authorization window, signer binding), and the guard uploads them for reconciliation as soon as it reaches the service again.
Peer dependencies
viem, @x402/evm and @x402/fetch stay yours: the guard uses the signer and client you already
have rather than bundling a second copy.
Docs and dashboard: warns.xyz
