Program Reference
Anchor 0.30.1 Solana program that enforces agent policies on-chain. Program ID: ENzC6oJhL2bVELvRCZqN4JizFNPTCTfMR5Gz1YJb4u76
The program is deployed on Solana devnet.
Accounts
PermissionPolicy
PDA seeds: ["policy", owner, agent]. Size: 685 bytes. Stores all policy configuration, spend state, and pause metadata for a single agent.
| Field | Type | Description |
|---|---|---|
owner | Pubkey | Wallet that created and controls the policy |
agent | Pubkey | Public key of the AI agent keypair |
allowedPrograms | Vec<Pubkey> (max 10) | Whitelisted program IDs for CPI |
maxTxLamports | u64 | Per-transaction SOL cap in lamports |
maxTxTokenUnits | u64 | Per-transaction token unit cap |
dailyBudgetLamports | u64 | Rolling 24-hour budget in lamports |
dailySpentLamports | u64 | Lamports spent in the current 24h window |
lastResetTs | i64 | Timestamp of the last budget window reset |
sessionExpiry | i64 | Unix timestamp when the agent session expires |
isActive | bool | Whether the agent is active (false when paused) |
pausedBy | Option<Pubkey> | Who triggered the kill switch (if paused) |
pausedReason | [u8; 64] | UTF-8 encoded reason string (if paused) |
squadsMultisig | Option<Pubkey> | Squads v4 multisig address for escalation |
escalationThreshold | u64 | Amount in lamports that triggers multisig escalation |
authorizedMonitors | Vec<Pubkey> (max 3) | Keypairs authorized to call pause_agent |
anomalyScore | u8 | Guardian Agent anomaly score (0–100) |
bump | u8 | PDA bump seed |
SpendTracker
PDA seeds: ["tracker", policy]. Tracks rolling spend counters, transaction frequency, and behavioral signals used by the monitoring pipeline.
| Field | Type | Description |
|---|---|---|
policy | Pubkey | Associated PermissionPolicy PDA |
windowStart | i64 | Start of the current 24h tracking window |
txnCount24h | u64 | Total transactions in the current 24h window |
lamportsSpent24h | u64 | Total lamports spent in the current 24h window |
lastTxnTs | i64 | Timestamp of the most recent transaction |
lastTxnProgram | Pubkey | Target program of the most recent transaction |
uniqueDestinations24h | u64 | Unique destination accounts in 24h (heuristic) |
maxSingleTxnLamports | u64 | Largest single transaction in the current window |
failedTxnCount24h | u64 | Failed guarded_execute attempts in 24h |
uniquePrograms24h | u64 | Unique target programs invoked in 24h |
lamportsSpent1h | u64 | Lamports spent in the current 1h window |
windowStart1h | i64 | Start of the current 1h tracking window |
consecutiveHighAmountCount | u64 | Sequential transactions above 50% of per-tx limit |
bump | u8 | PDA bump seed |
Instructions
| Instruction | Signer | Description |
|---|---|---|
initialize_policy | Owner | Creates policy + tracker PDAs with initial configuration |
update_policy | Owner | Modifies limits, allowed programs, monitors, or multisig settings |
guarded_execute | Agent | Core CPI with 12-step validation pipeline |
pause_agent | Owner / Monitor | Activates the kill switch, freezing all agent activity |
resume_agent | Owner only | Deactivates the kill switch, re-enabling agent execution |
rotate_agent_key | Owner | Swaps agent keypair atomically, migrating all state to new PDAs |
close_policy | Owner | Permanent deletion of policy + tracker, refunds remaining lamports |
multisig_execute | Owner | Squads-approved execution bypassing standard budget checks |
escalate_to_squads | — | Stub for future Squads proposal creation |
update_anomaly_score | Monitor | Sets the Guardian Agent anomaly score (0–100) |
wrap_sol | Owner / Agent | Converts SOL to wrapped SOL (wSOL) for SPL interactions |
unwrap_sol | Owner / Agent | Converts wrapped SOL (wSOL) back to native SOL |
guarded_execute: 12-Step Flow
Every agent transaction passes through the following validation pipeline before the CPI is executed. If any step fails, the transaction is rejected and a GuardedTxnRejected event is emitted.
- Load policy + tracker PDAs and verify account ownership
- Kill switch check — reject if
isActiveis false (PolicyPaused) - Session expiry check — reject if current timestamp exceeds
sessionExpiry - Program whitelist check — reject if target program is not in
allowedPrograms - Amount verification + parsing — validate
amountHintagainst account balances - Budget window roll — reset counters if 24h has elapsed since
lastResetTs - Daily budget check — reject if spend + amount exceeds
dailyBudgetLamports - Squads escalation check — escalate if amount exceeds
escalationThreshold - Emit
GuardedTxnAttemptedevent with pre-execution metadata - Execute CPI via
invoke_signedto the target program - Update spend counters on tracker and emit
GuardedTxnExecuted - Return success
Events
The program emits Anchor events that are indexed by Helius webhooks and forwarded to the server monitoring pipeline.
| Event | Fields | When Emitted |
|---|---|---|
GuardedTxnAttempted | policy, agent, targetProgram, amountHint, timestamp | Before CPI execution (step 9) |
GuardedTxnExecuted | policy, agent, targetProgram, amount, timestamp | After successful CPI execution (step 11) |
GuardedTxnRejected | policy, agent, reason code, timestamp | On validation failure (steps 2–8) |
AgentPaused | policy, pausedBy, reason, timestamp | When pause_agent is called |
AgentResumed | policy, resumedBy, timestamp | When resume_agent is called |
EscalatedToSquads | policy, squadsProposal, amount | When transaction exceeds escalation threshold |
AgentKeyRotated | oldPolicy, newPolicy, oldAgent, newAgent, timestamp | When rotate_agent_key completes |
MultisigTxnExecuted | policy, owner, targetProgram, amount, squadsProposal, timestamp | After successful multisig execution |
PolicyClosed | policy, owner, refundedLamports, timestamp | When close_policy completes |
Error Codes
| Code | Name | Message |
|---|---|---|
| 6000 | PolicyPaused | Agent is paused by kill switch |
| 6001 | SessionExpired | Agent session has expired |
| 6002 | ProgramNotWhitelisted | Target program is not in the allow list |
| 6003 | AmountExceedsLimit | Transaction amount exceeds per-tx limit |
| 6004 | DailyBudgetExceeded | Daily spending budget has been exhausted |
| 6005 | UnauthorizedPauser | Signer is not authorized to pause this agent |
| 6006 | ResumeRequiresOwner | Only the policy owner can resume an agent |
| 6007 | EscalatedToMultisig | Transaction requires multisig approval |
| 6008 | TooManyAllowedPrograms | Allowed programs list exceeds maximum of 10 |
| 6009 | TooManyMonitors | Authorized monitors list exceeds maximum of 3 |
| 6010 | SessionExpiryInPast | Session expiry timestamp is in the past |
| 6011 | TxLimitExceedsDailyBudget | Per-tx limit cannot exceed daily budget |
| 6012 | AmountMismatch | Amount hint does not match actual account delta |
| 6013 | CpiExecutionFailed | Cross-program invocation returned an error |
| 6014 | InsufficientLamports | Insufficient lamports for the transaction |
| 6015 | UnauthorizedCaller | Signer is not the expected owner or agent |
| 6016 | InvalidWsolAccount | wSOL account does not match expected address |
| 6017 | InvalidInputAccountIndex | Input account index is out of bounds |
| 6018 | InputAccountIndexRequired | Input account index is required for this instruction |
| 6019 | PolicyNotPaused | Policy must be paused before this action |
| 6020 | NotYetImplemented | This feature is not yet implemented |
| 6021 | SameAgentKey | New agent key must differ from the current key |
| 6022 | InvalidSquadsProposal | Squads proposal account is invalid |
| 6023 | MultisigMismatch | Proposal multisig does not match policy multisig |
| 6024 | ProposalNotApproved | Squads proposal has not been approved |
| 6025 | NoMultisigConfigured | No multisig is configured on this policy |