In our last post, we described what happened when we dogfooded smart402 against twit.sh on Base mainnet. One of the things we found: tx_hash was not flowing correctly into the dashboard, and confirmed spend was being underreported. We shipped a fix in the same breath that we published the post.

0.4.0 (live now) is the full architecture that fix became. Here is what it does and why it matters for anyone running AI agent spending controls in production.

The problem with "approved"

We're building a world-class agent spending controls layer, and realized that to do this properly, the engine must know what actually happened with a payment — not just what was authorized. Before 0.4.0, smart402's evaluation was the last thing we registered: after approve, smart402 had no visibility into whether the payment was broadcast, confirmed, or dropped.

That created a real problem: budget windows (daily_budget, monthly_budget, and so on) were counting approved spend. A payment that got approved but never broadcast, or approved and then reverted on-chain, still consumed an agent's allowance.

0.4.0 fixes this. The smart402 dashboard now reflects confirmed on-chain spend. If a transaction is dropped, the budget is updated to free up that amount automatically.

What shipped

One argument added to as_hook().

# Before (0.3.x)
client.on_before_payment_creation(guard.as_hook())

# After (0.4.0)
client.on_before_payment_creation(guard.as_hook(x402_client=client))

That single argument registers two fire-and-forget hooks on the x402 client:

Both hooks are completely non-blocking. If they fail for any reason — network error, timeout — the payment flow is never affected.

The state machine

When smart402 receives a tx_hash, it calls eth_getTransactionReceipt against the Base RPC directly. No Etherscan API key required. The result drives a five-state machine:

State Meaning Budget rehydrated?
reported Hash received, verification pending No
confirmed On-chain with status=1 (success) No — spend counts
chain_failed Transaction reverted (status=0) Yes
unverifiable 3 attempts exhausted (5 min, 30 min, 30 min backoff) No — funds may have moved
creation_failed Payment was never broadcast Yes

We use a state machine instead of a boolean because unverifiable is an actual state. A transaction that exists on-chain but cannot be confirmed after three attempts is different from a transaction that never happened. We rehydrate the budget for chain_failed and creation_failed. We do not rehydrate for unverifiable, because the funds may have moved.

Budget rehydration

If a payment fails (creation_failed or chain_failed), the approved spend is removed from both the Redis velocity cache and the SQL budget windows. Your agent gets that allowance back automatically — no manual intervention required.

This makes x402 budget policy behave the way it should: the numbers reflect real money that moved, not authorization events that may or may not have resulted in a transfer.

The dashboard

The agent detail view now shows two distinct numbers:

This distinction is what makes AI agent spending controls auditable in practice. Approved tells you how active your agent is. Confirmed tells you how much real money moved. For most well-functioning agents the gap will be small. When it is not, that is the signal worth investigating.

Upgrading

pip install --upgrade smart402

One argument added to as_hook(). No other changes required. Agents already running 0.3.x get confirmed spend tracking automatically on upgrade.

The TypeScript SDK aligns to 0.4.0 on the same release. No functional changes on the TypeScript side for this version.

Get started at app.smart402.com or file an issue on GitHub (Python / JS) if something feels rough.

Frequently asked questions

What happens if the tx_hash reporting hook fails?

Nothing, from the agent's perspective. Both hooks are fire-and-forget and run off the critical path. If a hook fails due to a network error or timeout, the payment has already completed and the hook failure is logged silently. The evaluation stays in reported state and the background retry loop picks it up at the 5-minute interval.

Does smart402 0.4.0 change how policy evaluation works?

No. The evaluation logic, policy types, response format, and SDK interface are unchanged. The only addition is the optional x402_client argument to as_hook(), which enables outcome tracking. Agents that do not pass x402_client continue to work exactly as before, without confirmed spend tracking.

What is smart402?

smart402 is a deterministic policy engine for x402 payments. It sits between your agent and any x402-protected API, evaluating every payment request against your configured rules before execution. No LLM in the decision path: same inputs always produce the same output.

Try smart402

Deterministic policy engine for x402 payments. No LLM in the decision path.

Previous post All posts