Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install leoyeai-openclaw-master-skills-skills-guardrail-smart-accountsgit clone https://github.com/LeoYeAI/openclaw-master-skills.gitcp openclaw-master-skills/SKILL.MD ~/.claude/skills/leoyeai-openclaw-master-skills-skills-guardrail-smart-accounts/SKILL.md---
name: guardrail-smart-accounts
description: Give AI agents on-chain spending guardrails. Deploy ERC-4337 smart accounts with policy-enforced limits — agents cannot move funds beyond what you authorize, enforced at the contract level, not just in software.
version: 1.1.0
metadata:
openclaw:
requires:
env:
- GUARDRAIL_CHAIN_ID
- GUARDRAIL_RPC_URL
- GUARDRAIL_SIGNING_MODE
optionalSecrets:
- name: GUARDRAIL_API_URL
when: Using dashboard API for policy/permission management
sensitive: false
description: AgentGuardrail API base URL. Defaults to https://agentguardrail.xyz
- name: GUARDRAIL_SIGNER_ENDPOINT
when: GUARDRAIL_SIGNING_MODE is external_signer
sensitive: true
description: External signer service URL
- name: GUARDRAIL_SIGNER_AUTH_TOKEN
when: GUARDRAIL_SIGNING_MODE is external_signer
sensitive: true
description: Scoped, revocable auth token for the external signer
- name: GUARDRAIL_DASHBOARD_API_KEY
when: Using dashboard API for policy/permission management
sensitive: true
description: API key for AgentGuardrail management API at agentguardrail.xyz
primaryEnv: GUARDRAIL_RPC_URL
emoji: "\U0001F6E1"
homepage: https://agentguardrail.xyz
tags:
- ai-agents
- smart-accounts
- erc-4337
- defi
- guardrails
- policy-enforcement
- on-chain
- spending-limits
- permissions
- audit
---
# AgentGuardrail — On-Chain Spending Guardrails for AI Agents
> **Give your AI agents a wallet they can't abuse.** AgentGuardrail deploys ERC-4337 smart accounts with policy-enforced spending limits. Agents cannot move funds beyond what you authorize — enforcement happens at the contract level, not just in software.
**Homepage:** https://agentguardrail.xyz
---
## Why AgentGuardrail?
AI agents need to move money. The problem is trust: how do you let an agent trade, bridge, or pay for compute without risking runaway spending, compromised keys, or unauthorized actions?
AgentGuardrail solves this with:
- **On-chain enforcement** — `AgentSmartAccount.validateUserOp()` calls `PermissionEnforcer` before any transaction executes. Violating transactions revert. There is no override.
- **Policy-bound accounts** — every smart account is deployed against a policy that defines allowed actions, tokens, protocols, chains, and spend limits.
- **Non-custodial** — AgentGuardrail never holds your funds. Enforcement is in the contracts you deploy.
- **Full audit trail** — every intent, validation, and on-chain event is logged with tx hash and block number.
---
## Overview
Every agent gets an ERC-4337 smart account deployed via `AgentAccountFactory`. The account's `validateUserOp()` enforces your policy through `PermissionEnforcer` before any transaction reaches the blockchain. If the action violates the policy — wrong token, wrong protocol, spend limit exceeded — the UserOperation reverts.
**Execution path:**
```
Agent builds UserOperation
→ AgentSmartAccount.validateUserOp()
→ PermissionEnforcer.validateAction()
→ Policy constraints checked on-chain
→ EntryPoint executes (only if all checks pass)
```
The AgentGuardrail API at **https://agentguardrail.xyz** provides:
- A management interface for creating policies and granting permissions
- Pre-flight validation for simulation and dashboards
- Aggregated audit logs with on-chain event indexing
Most enforcement operations can be done directly against the contracts without the API. The API is most useful for policy management, pre-flight simulation, and audit log queries.
---
## Security & Credential Model (Required)
This skill performs on-chain operations that require JSON-RPC access and transaction signing.
**Private keys must never be provided in chat and must never be stored in unconstrained agent memory.**
### Signing Modes
#### 1. External Signer (Recommended)
The agent prepares a transaction. The runtime forwards it to a secure signer service (HSM, MPC, hosted signer). The signer enforces scope, rate limits, and allowlists. The agent never sees raw private keys.
#### 2. Wallet Connector / User-Approved Signing
Transactions are prepared by the agent. A user wallet (browser, hardware wallet) prompts for approval. Keys remain in the wallet.
#### 3. Scoped Session Keys (Advanced)
Session keys must be policy-restricted, short-lived, and rotated frequently. Never use a long-lived owner EOA private key as a session key.
### The Skill Must NOT
- Ask users to paste private keys or seed phrases
- Store private keys in memory, logs, or prompts
- Access unrelated environment variables or local files
- Request cloud credentials or system-level secrets
- Persist secrets beyond runtime execution
If secure signing is not configured, operate in **read-only mode** until proper signing is established.
---
## Runtime Configuration
Required (via secure secret storage, not chat):
| Variable | Description |
|----------|-------------|
| `GUARDRAIL_CHAIN_ID` | Target chain ID (e.g., `8453` for Base, `11155111` for Sepolia) |
| `GUARDRAIL_RPC_URL` | JSON-RPC endpoint — treat as sensitive, often contains an API key |
| `GUARDRAIL_SIGNING_MODE` | One of: `external_signer`, `wallet_connector`, `session_key` |
Optional:
| Variable | Description |
|----------|-------------|
| `GUARDRAIL_API_URL` | AgentGuardrail API base. Defaults to `https://agentguardrail.xyz` |
| `GUARDRAIL_SIGNER_ENDPOINT` | External signer URL — required when `GUARDRAIL_SIGNING_MODE=external_signer` |
| `GUARDRAIL_SIGNER_AUTH_TOKEN` | Auth token for the external signer — sensitive, store securely |
| `GUARDRAIL_DASHBOARD_API_KEY` | API key for agentguardrail.xyz management API |
The API URL default in all code examples below is `https://agentguardrail.xyz`. Override with `GUARDRAIL_API_URL` if self-hosting.
---
## Smart Contract Addresses
### Base Mainnet (Chain ID 8453)
| Contract | Address |
|----------|---------|
| IdentityRegistry | `0xc1fa477f991C74Cc665E605fC74f0e2B795b5104` |
| PolicyRegistry | `0x92cd41e6a4aA13072CeBCda8830d48f269F058c4` |
| PermissionEnforcer | `0xbF63Fa97cfBba99647B410f205730d63d831061c` |
| PriceOracle | `0xf3c8c6BDc54C60EDaE6AE84Ef05B123597C355B3` |
| GuardrailFeeManager | `0xD1B7Bd65F2aB60ff84CdDF48f306a599b01d293A` |
| AgentAccountFactory | `0xCE621A324A8cb40FD424EB0D41286A97f6a6c91C` |
| EntryPoint (v0.6) | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` |
### Sepolia Testnet (Chain ID 11155111)
| Contract | Address |
|----------|---------|
| IdentityRegistry | `0xc1fa477f991C74Cc665E605fC74f0e2B795b5104` |
| PolicyRegistry | `0x92cd41e6a4aA13072CeBCda8830d48f269F058c4` |
| PermissionEnforcer | `0x94991827135fbd0E681B3db51699e4988a7752f1` |
| PriceOracle | `0x052cDddba3C55A63F5e48F9e5bC6b70604Db93b8` |
| GuardrailFeeManager | `0x0f77fdD1AFCe0597339dD340E738CE3dC9A5CC12` |
| AgentAccountFactory | `0xA831229B58C05d5bA9ac109f3B29e268A0e5F41E` |
| EntryPoint (v0.6) | `0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789` |
> Start on Sepolia. Move to Base Mainnet when policies are validated.
---
## Core Capabilities
### 1. Deploy a Smart Account
Deploy a new ERC-4337 smart account via `AgentAccountFactory`. The account is bound to `PermissionEnforcer` at creation. Deployment is deterministic via CREATE2 — the same owner, agentId, and salt always produce the same address.
**One-time creation fee:** $10 USD equivalent in ETH.
**Direct contract call (recommended):**
```solidity
// Get required creation fee
uint256 fee = factory.getCreationFee();
// Deploy account (send fee as msg.value)
address account = factory.createAccount{value: fee}(
ownerAddress, // Controls the account
agentId, // bytes32 identifier for this agent
salt // bytes32 for CREATE2 determinism
);
```
**Via API:**
```javascript
const apiUrl = process.env.GUARDRAIL_API_URL ?? "https://agentguardrail.xyz";
const response = await fetch(`${apiUrl}/api/v1/agents/${agentId}/deploy-smart-account`, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}` },
});
const { smart_account_address } = await response.json();
```
The API path is useful when using dashboard-generated bot signers (the dashboard generates the keypair and handles deployment in one step).
---
### 2. Fund a Smart Account
Send ETH directly to the smart account address. Inbound transfers are free — no fee, no contract call needed.
```javascript
await walletClient.sendTransaction({
to: smartAccountAddress,
value: parseEther("1.0"),
});
```
---
### 3. Execute from a Smart Account
Agent executes a transaction from its smart account. `validateUserOp()` enforces the policy before the transaction reaches the chain — no override exists.
**Outbound transfer fee:** 10 bps (0.10%), capped at $100 USD per transaction.
```javascript
// Build the UserOperation
const callData = encodeFunctionData({
abi: agentSmartAccountABI,
functionName: "execute",
args: [destinationAddress, parseEther("1.0"), "0x"],
});
// Submit via ERC-4337 EntryPoint
// The EntryPoint calls validateUserOp → PermissionEnforcer before execution
```
Fee enforcement occurs inside `GuardrailFeeManager`. Fee is deducted from the transaction value automatically.
| Transfer Amount | Fee |
|----------------|-----|
| $1,000 | $1.00 |
| $10,000 | $10.00 |
| $100,000+ | $100.00 (cap) |
---
### 4. Read Contract State (No Signing Required)
```javascript
// Get account owner
const owner = await publicClient.readContract({
address: smartAccountAddress,
abi: agentSmartAccountABI,
functionName: "owner",
});
// Get smart account creation fee
const fee = await publicClient.readContract({
address: factoryAddress,
abi: agentAccountFactoryABI,
functionName: "getCreationFee",
});
// Calculate transfer fee before executing
const transferFee = await publicClient.readContract({
address: feeManagerAddress,
abi: guardrailFeeManagerABI,
functionName: "calculateTransferFee",
args: [parseEther("10.0")],
});
// Check if a permission is active on-chain
const isActive = await publicClient.readContract({
address: policyRegistryAddress,
abi: policyRegistryABI,
functionName: "isPermissionActive",
args: [agentAddress, permissionId],
});
```
---
### 5. Policy Management
Policies define what an agent is allowed to do: which actions, tokens, protocols, chains, and spend limits. Policies are stored on-chain in `PolicyRegistry` and enforced by `PermissionEnforcer`.
**On-chain (direct):**
```solidity
// Register a policy on-chain
bytes32 policyId = policyRegistry.registerPolicy(
bytes32(policyHash), // Unique identifier
allowedActions, // bytes32[] action type hashes
allowedTokens, // address[] token contracts
allowedProtocols, // address[] protocol contracts
allowedChains, // uint256[] chain IDs
maxValuePerTx, // uint256 in wei
maxDailyVolume, // uint256 in wei
expiresAt // uint256 unix timestamp
);
```
**Via API (recommended for most use cases — handles on-chain registration automatically):**
```javascript
const apiUrl = process.env.GUARDRAIL_API_URL ?? "https://agentguardrail.xyz";
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}`,
};
// Create and activate a policy
const policy = await fetch(`${apiUrl}/api/v1/policies`, {
method: "POST",
headers,
body: JSON.stringify({
name: "DeFi Trading Policy",
description: "Allow swaps and transfers with daily limits",
definition: {
actions: ["swap", "transfer"],
assets: {
tokens: ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
protocols: ["*"],
chains: [1, 8453],
},
constraints: {
maxValuePerTx: "1000000000000000000", // 1 ETH
maxDailyVolume: "10000000000000000000", // 10 ETH
maxTxCount: 100,
requireApproval: false,
},
duration: {
validFrom: "2026-01-01T00:00:00Z",
validUntil: "2026-12-31T23:59:59Z",
},
},
}),
}).then((r) => r.json());
// Activate it (registers on-chain via PolicyRegistry)
await fetch(`${apiUrl}/api/v1/policies/${policy.id}/activate`, {
method: "POST",
headers,
});
```
**PolicyDefinition fields:**
| Field | Type | Description |
|-------|------|-------------|
| `actions` | `string[]` | `swap`, `transfer`, `approve`, `stake`, `unstake`, `deposit`, `withdraw`, `mint`, `burn`, `bridge`, `claim`, `vote`, `delegate`, `lp_add`, `lp_remove`, `borrow`, `repay`, `liquidate`, `*` |
| `assets.tokens` | `string[]` | Token contract addresses, or `["*"]` for all |
| `assets.protocols` | `string[]` | Protocol addresses, or `["*"]` for all |
| `assets.chains` | `number[]` | Allowed chain IDs |
| `constraints.maxValuePerTx` | `string` | Max per-tx value in wei |
| `constraints.maxDailyVolume` | `string` | Max daily volume in wei |
| `constraints.maxWeeklyVolume` | `string` | Max weekly volume in wei |
| `constraints.maxTxCount` | `number` | Max transactions within the duration |
| `duration.validFrom` / `validUntil` | `string` | ISO 8601 |
| `conditions` | `array` | Advanced rules: `{ field, operator, value }`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `not_in`, `contains`, `regex` |
**Other policy operations:**
```javascript
// Update (draft policies update in place; active policies create a new version)
await fetch(`${apiUrl}/api/v1/policies/${policyId}`, { method: "PUT", headers, body: JSON.stringify({...}) });
// Revoke (disables on-chain — active permissions using this policy stop validating)
await fetch(`${apiUrl}/api/v1/policies/${policyId}/revoke`, { method: "POST", headers });
// Reactivate
await fetch(`${apiUrl}/api/v1/policies/${policyId}/reactivate`, { method: "POST", headers });
// List / Get / Delete (draft only)
await fetch(`${apiUrl}/api/v1/policies`, { headers });
await fetch(`${apiUrl}/api/v1/policies/${policyId}`, { headers });
await fetch(`${apiUrl}/api/v1/policies/${policyId}`, { method: "DELETE", headers });
```
---
### 6. Permission Management
Permissions link an agent to a policy for a defined period. On-chain, `PolicyRegistry.grantPermission()` registers the link. `PermissionEnforcer` reads active permissions during `validateUserOp`.
**On-chain (direct):**
```solidity
// Grant permission on-chain
bytes32 permissionId = policyRegistry.grantPermission(
agentAddress, // The smart account address
policyId, // bytes32 policy identifier
validFrom, // uint256 unix timestamp
validUntil // uint256 unix timestamp
);
```
**Revoke on-chain:**
```solidity
policyRegistry.revokePermission(permissionId);
```
**Via API (handles on-chain registration + constraint sync to PermissionEnforcer):**
```javascript
const apiUrl = process.env.GUARDRAIL_API_URL ?? "https://agentguardrail.xyz";
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}`,
};
// Grant a permission
const permission = await fetch(`${apiUrl}/api/v1/permissions`, {
method: "POST",
headers,
body: JSON.stringify({
agent_id: "agent-uuid",
policy_id: "policy-uuid",
valid_from: "2026-01-01T00:00:00Z",
valid_until: "2026-12-31T23:59:59Z",
}),
}).then((r) => r.json());
// Mint it on-chain (registers in PolicyRegistry, syncs constraints to PermissionEnforcer)
const minted = await fetch(`${apiUrl}/api/v1/permissions/${permission.id}/mint`, {
method: "POST",
headers,
}).then((r) => r.json());
// minted.onchain_token_id — the on-chain token ID
// Revoke
await fetch(`${apiUrl}/api/v1/permissions/${permission.id}`, { method: "DELETE", headers });
// List (filter by agent or policy)
await fetch(`${apiUrl}/api/v1/permissions?agent_id=${agentId}`, { headers });
```
> Use the API path when you need the `PermissionEnforcer` constraints to sync automatically. The direct contract path is sufficient if you are managing `PermissionEnforcer` constraint updates yourself.
---
### 7. Action Validation
**On-chain enforcement (primary):**
Validation happens automatically inside `AgentSmartAccount.validateUserOp()` via `PermissionEnforcer`. You do not call this directly — it runs as part of every UserOperation. Transactions that violate policy constraints revert before execution.
**Off-chain pre-flight (via API — useful for dashboards, simulation, agent planning):**
```javascript
const apiUrl = process.env.GUARDRAIL_API_URL ?? "https://agentguardrail.xyz";
// Pre-flight check before building a UserOperation
const result = await fetch(`${apiUrl}/api/v1/validate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}`,
},
body: JSON.stringify({
agent_id: "agent-uuid",
action: {
type: "swap",
token: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
protocol: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
amount: "500000000000000000",
chain: 8453,
to: "0xDef1C0ded9bec7F1a1670819833240f027b25EfF",
},
}),
}).then((r) => r.json());
// result.allowed — boolean
// result.reason — explanation if denied
// result.permission_id — matching permission
// result.policy_id — matching policy
// result.constraints — active constraints
// result.request_id — audit trail reference
```
**Simulate (dry-run, no audit record):**
```javascript
const sim = await fetch(`${apiUrl}/api/v1/validate/simulate`, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}` },
body: JSON.stringify({
agent_id: "agent-uuid",
action: { type: "transfer", amount: "1000000000000000000", chain: 1 },
}),
}).then((r) => r.json());
// sim.would_allow — boolean
// sim.current_usage — current period usage
// sim.remaining_quota — remaining allowance
// sim.recommendations — suggested policy adjustments
```
**Batch validate:**
```javascript
// POST /api/v1/validate/batch
// Body: { actions: [...] } — same structure as single validate
```
---
### 8. Audit & Monitoring
**On-chain events (source of truth):**
The AgentGuardrail indexer polls contracts every 12 seconds and writes events to the audit log with `tx_hash` and `block_number`. Events emitted by the contracts:
| Event | Contract | Description |
|-------|----------|-------------|
| `EnforcementResult` | PermissionEnforcer | Every validateUserOp result |
| `ConstraintViolation` | PermissionEnforcer | Policy constraint breached |
| `UsageRecorded` | PermissionEnforcer | Spend/volume tracked |
| `Executed` | AgentSmartAccount | Transaction executed |
| `AccountCreated` | AgentAccountFactory | New smart account deployed |
**Query via API:**
```javascript
const apiUrl = process.env.GUARDRAIL_API_URL ?? "https://agentguardrail.xyz";
// List audit logs
const logs = await fetch(
`${apiUrl}/api/v1/audit?agent_id=${agentId}&source=onchain&start_date=2026-01-01T00:00:00Z`,
{ headers: { Authorization: `Bearer ${process.env.GUARDRAIL_DASHBOARD_API_KEY}` } }
).then((r) => r.json());
// Each log entry includes: source ('onchain'|'offchain'), tx_hash, block_number, event_type
// Filter by source
// source=onchain — events from contract indexer (tx_hash + block_number included)
// source=offchain — API validation requests
// Export (JSON or CSV)
const csvUrl = `${apiUrl}/api/v1/audit/export?format=csv&start_date=2026-01-01T00:00:00Z`;
```
Event types: `policy.created`, `policy.activated`, `policy.revoked`, `permission.created`, `permission.minted`, `permission.revoked`, `validation.request`.
---
## Enforcement Model
All agents are **ERC-4337 smart accounts with enforced on-chain policy enforcement**. There is no advisory or EOA mode.
`AgentSmartAccount.validateUserOp()` calls `PermissionEnforcer` on every UserOperation. Transactions that violate policy constraints revert before execution. The agent cannot bypass enforcement — it is built into the account's validation logic.
Off-chain validation (`/api/v1/validate`) runs as a pre-flight simulation for dashboards, SDK use, and agent planning. The on-chain `PermissionEnforcer` performs the final, authoritative enforcement.
---
## Recommended Setup Flow
```
1. Deploy smart account (AgentAccountFactory.createAccount)
2. Create policy (API) → activate (registers on-chain via PolicyRegistry)
3. Grant permission (API) → mint (syncs constraints to PermissionEnforcer)
4. Agent builds UserOperations — enforcement is automatic
5. Monitor via audit logs or on-chain events
```
---
## Autonomy & Safety Guidance
1. **Start on Sepolia.** All contract addresses are provided above.
2. Fund accounts with small amounts while validating policies.
3. Use strict policies — prefer explicit token/protocol allowlists over wildcards.
4. Enable autonomous execution only with secure signing configured.
5. Apply rate limits and allowlists at the signer layer as a second line of defense.
---
## Privacy and Data Handling
- This skill does not store, log, or transmit private keys, seed phrases, or signer tokens.
- `GUARDRAIL_RPC_URL` may contain an embedded API key. Treat it as sensitive.
- `GUARDRAIL_SIGNER_AUTH_TOKEN` grants signing capability. Store in secure secret storage — never expose in logs, prompts, or chat.
- On-chain transactions are public by nature. The skill adds no off-chain data collection beyond what the blockchain records.
- The skill does not access local files, browser storage, or environment variables beyond those declared in the manifest.
---
## Design Principles
1. **Contract-first** — All enforcement is on-chain. The API is a convenience layer, not the authority.
2. **Policy-bound by default** — Every account is bound to a policy at creation. No account is unconstrained.
3. **Non-custodial** — AgentGuardrail never holds funds. Enforcement lives in contracts you can verify.
4. **Least privilege** — Signing must use scoped, secure integrations. Never expose long-lived owner keys.
5. **Agent and human neutral** — Authority derives from ownership and policy, not caller identity.
6. **Infrastructure-grade fees** — Fees are enforced at the contract layer. No software bypass exists.
---
## Dashboard
All operations are available via the web dashboard at **https://agentguardrail.xyz** — manage agents, policies, permissions, and audit logs visually. API keys and bot signer keypairs generated by the dashboard should be stored in secure secret storage and never pasted into chat.