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:
on_after_payment_creationextracts thetx_hashfrom the signed payment payload and reports it to smart402.on_payment_creation_failurereportscreation_failedif the payment was never broadcast.
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:
- Approved — evaluations that passed policy checks
- Confirmed — the subset that made it on-chain successfully
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.
Deterministic policy engine for x402 payments. No LLM in the decision path.