On-chain spending limits for AI agents.
Uniagent enforces hard spend limits for autonomous AI agents at the Uniswap v4 hook level — before a swap clears, not after. Hook enforcement and tracking are live today. Automatic pay-backs when an agent breaches its budget are the next layer, in development. No changes to your agent's logic.
Introduction
Every week an AI agent somewhere drains a treasury. Long-running loops, a compromised API key, a tool that calls itself — the failure modes are many and the outcome is the same: a wallet empties, an invoice arrives, nobody is watching.
Uniagent sits at the protocol layer. Spending rules you define are enforced by a Uniswap v4 hook that runs inside every pool your agent touches. When the agent tries to swap past its limit, the hook reverts the transaction before it settles. The next layer — automatic pay-backs from the $UAGNT underwriting pool when a breach slips through a non-hook path — is in development.
Quickstart
Most teams are covered in under ten minutes. You'll need an Ethereum wallet (0x…) with signing permission over your agent's treasury and at least 50 $UAGNT to stake.
-
Create an account
Sign up at tryuniagent.xyz/signup and connect the wallet that controls your agent's treasury.
-
Define a policy
Pick your spend ceilings: per-tx, per-day, per-week. Optional allowlists for recipients and pools.
-
Stake $UAGNT
Deposit $UAGNT to activate the policy. The stake backs your payout and earns yield while idle.
-
Attach the hook
Point your agent's swaps through a Uniagent-enabled v4 pool, or drop the SDK into your codebase. No logic changes required.
How it works
Uniagent is not a wrapper around your agent — enforcement lives in a Uniswap v4 hook attached to the pools your agent swaps through. Four things happen on every transaction:
1. beforeSwap
The hook reads your policy from storage and checks the pending swap against your per-tx, daily and weekly ceilings.
2. Enforcement
If the swap would breach a hard limit, the hook reverts the transaction in-block. Soft limits emit an event and fire a webhook.
3. Settlement · coming soon
If a breach clears through a non-hook path, Alchemy webhooks flag it and the $UAGNT pool auto-pays the insured amount. This pay-back layer is in development.
4. Attestation
Every enforced swap is recorded on-chain via the hook's emitted events. The audit trail lives in one queryable ledger.
The Uniswap v4 hook
This is what makes Uniagent different from an off-chain monitor. Uniswap v4 lets a pool delegate logic to a hook contract at defined lifecycle points. Uniagent registers a hook on the beforeSwap and afterSwap permissions.
- beforeSwap — runs before the swap math. Uniagent loads the agent's policy, prices the swap in USD against an on-chain feed, and reverts with
LimitExceededif it would cross a hard ceiling. Enforcement is atomic with the swap — there is no window where the agent can sneak a transaction past. - afterSwap — runs after settlement. Uniagent accrues the spent amount into the agent's rolling windows (per-day, per-week) and emits a
SpendRecordedevent that the indexer and webhooks consume.
Because the rule lives in the pool, it holds no matter which client, bot framework or RPC writes the transaction. There is nothing to bypass at the application layer.
// Simplified — the on-chain check inside beforeSwap
function beforeSwap(address agent, PoolKey key, SwapParams params)
external returns (bytes4)
{
Policy memory p = policyOf[agent];
uint256 usd = priceInUsd(key, params.amountSpecified);
if (usd > p.perTxUsd) revert LimitExceeded("per_tx");
if (spentToday(agent) + usd > p.perDayUsd) revert LimitExceeded("per_day");
return BaseHook.beforeSwap.selector;
}
Policies
A policy is a signed object that declares the rules for an agent's wallet. It is committed to the hook's storage so the same rules apply regardless of which client writes the transaction.
{
"agent_id": "ag_8fnZ4qpL",
"wallet": "0xd8dA6BF26964af9D7eEd9e03E53415D37aA96045",
"limits": {
"per_tx_usd": 50,
"per_day_usd": 1500,
"per_week_usd": 7000
},
"allow_pools": ["ETH/USDC", "USDC/USDT"],
"payout_recipient": "0xHrAx2pR…aLp7",
"coverage_usd": 5000
}
On-chain limits
Limits are denominated in USD and computed at swap time inside the hook using an on-chain price feed. You can set:
- Per-transaction cap — reverts any single swap above the value
- Daily / weekly — rolling windows, reset at sliding boundaries
- Pool allowlists — only swap through named Uniswap v4 pools
- Recipient blocklists — block specific counterparties
$UAGNT staking · coming soon
The pay-back layer is underwritten by the $UAGNT token pool. At launch, activating a policy will deposit $UAGNT equal to 2% of your coverage amount. In exchange:
- Your policy is backed up to the full coverage amount
- The stake earns base yield from pool fees (currently ~6.8% APR)
- Unused stake is withdrawable after a 48-hour cooldown
Claims & pay-backs · coming soon
At launch, pay-backs will be automatic: when Uniagent's indexer detects a confirmed breach (via Alchemy webhooks on the agent's wallet), a payout transaction is signed by the pool and sent to your payout_recipient within one block.
Disputed claims (edge cases, partial breaches) go to the DAO review queue and settle within 72 hours.
JavaScript SDK
The SDK wraps any signer with policy enforcement and routes swaps through Uniagent-enabled v4 pools. It works with viem, ethers wallets, and remote signers.
// npm install @uniagent/sdk
import { UniagentSigner } from "@uniagent/sdk";
import { privateKeyToAccount } from "viem/accounts";
const signer = new UniagentSigner({
account: privateKeyToAccount(process.env.AGENT_KEY),
apiKey: process.env.UNIAGENT_API_KEY,
agentId: "ag_8fnZ4qpL",
});
// use it anywhere you'd use a normal signer
const hash = await signer.sendTransaction(tx);
Webhooks
Uniagent posts to your webhook URL whenever a policy event fires. Events are signed with an HMAC header (X-Uniagent-Signature) derived from your webhook secret. On-chain activity is sourced from Alchemy address-activity webhooks.
| Event | Triggered when |
|---|---|
swap.reverted | The hook reverted a swap over a hard limit |
limit.soft_hit | Soft limit reached, swap still passed |
spend.recorded | A swap was accounted into a rolling window |
payout.sent | Insurance payout confirmed on-chain |
policy.updated | Policy changed |
POST /your-webhook HTTP/1.1
X-Uniagent-Signature: t=1713589200,v1=3a8b...
{
"event": "swap.reverted",
"agent_id": "ag_8fnZ4qpL",
"tx_hash": "0x5gQR…Zx2",
"reason": "per_tx_usd exceeded",
"amount_usd": 82.14
}
CLI
The CLI is useful for scripting and CI — you can apply policies from JSON files, tail event streams, and simulate swaps locally.
# install
npm install -g @uniagent/cli
# authenticate
uniagent login
# apply a policy file
uniagent policy apply ./agent-policy.json
# tail events in real time
uniagent events tail --agent ag_8fnZ4qpL
REST API
Base URL: https://api.tryuniagent.xyz/v1. Authenticate with a bearer token — issued per-project under Settings → API keys.
| Method | Path | Purpose |
|---|---|---|
POST | /policies | Create a new policy |
GET | /policies/:id | Read an existing policy |
PATCH | /policies/:id | Update limits or allowlists |
GET | /events | Paginated event history |
POST | /simulate | Simulate a swap against the policy |
Errors
The API uses conventional HTTP codes. Body is always JSON with code, message, and optional details.
| Code | Meaning |
|---|---|
400 | Invalid policy or malformed body |
401 | Missing or invalid API key |
402 | Insufficient $UAGNT stake |
409 | Policy conflict — agent already has an active policy |
429 | Rate limited — 100 req/min per project |
5xx | Retry with exponential backoff |
FAQ
Does Uniagent custody my funds?
No. Your agent's wallet stays under your signer. Uniagent enforces limits inside a Uniswap v4 hook — it never holds the principal.
What if my agent swaps through a pool without the hook?
Hook enforcement only applies to Uniagent-enabled v4 pools. For swaps outside them, Alchemy webhooks detect the breach after the fact — and once the pay-back layer ships, the $UAGNT pool will cover the insured amount. Use pool allowlists to keep agents on enforced routes today.
Can I use Uniagent without $UAGNT?
You can run in monitor-only mode for free — you get the on-chain attestations and events but no payout coverage. Staking $UAGNT unlocks the insurance layer.
How are limits priced in USD?
At swap time the hook prices the trade against an on-chain feed (Chainlink for majors, the pool's own TWAP as fallback) with a 2% safety margin.
Is this audited?
The v4 hook and underwriting contracts are under audit ahead of the full mainnet rollout. The report will be published on our GitHub.