Skip to main content
Program ID: 2uYGW3fQUGfhrwVbkupdasXBpRPfGYBGTLUdaPTXU9vP x0-guard is the protocol’s policy enforcement layer. It implements the SPL Transfer Hook interface, meaning every Token-2022 transfer is intercepted and validated against the sender’s AgentPolicy before the transfer can settle.

How It Works

When a Token-2022 TransferChecked instruction executes on a mint configured with x0-guard as its transfer hook, Solana automatically invokes x0-guard’s validate_transfer handler. The guard loads the agent’s policy PDA and checks:
  1. Policy is activeis_active must be true
  2. Amount within single-transaction limit — If max_single_transaction is set, the amount must not exceed it
  3. Rolling window budget — The cumulative spend in the last 24 hours plus this amount must not exceed daily_limit
  4. Whitelist membership — If a whitelist is configured, the recipient must pass verification
  5. Minimum transfer amount — Amount must be ≥ 100 micro-units (anti-dust)
If any check fails, the transfer is rejected at the runtime level — the entire transaction reverts.

Instructions

initialize_policy

Creates a new AgentPolicy PDA for an owner-agent pair.

update_policy

Updates an existing policy. Rate-limited to one update per ~5 minutes (POLICY_UPDATE_COOLDOWN_SLOTS = 750).

update_agent_signer

Rotates the agent’s signing key. The old key is immediately invalidated.

revoke_agent_authority

Emergency revocation — immediately invalidates the agent’s key and sets is_active = false. Only the policy owner can call this.

set_policy_active

Pauses or unpauses an agent policy without destroying it.

validate_transfer

The Transfer Hook entry point. Called automatically by Token-2022 on every transfer. Not callable directly by users.
Records a Blink (human-approval request) generation event. Rate-limited to MAX_BLINKS_PER_HOUR = 3.

get_current_spend

View instruction — returns the current rolling window spend, remaining allowance, and oldest entry expiry.

State Accounts

AgentPolicy

PDA Seeds: ["agent_policy", owner, agent_signer]

SpendingEntry

Each entry in the rolling window tracks one transfer:

Rolling Window Algorithm

The spend limit uses a sliding 24-hour window rather than a fixed daily reset:
  1. On each transfer, expired entries (older than ROLLING_WINDOW_SECONDS = 86,400) are pruned
  2. The sum of remaining entries is computed as current_spend
  3. If current_spend + amount > daily_limit, the transfer is rejected
  4. On success, a new SpendingEntry is appended
  5. Maximum entries capped at MAX_ROLLING_WINDOW_ENTRIES = 144 (~one per 10 minutes)
This prevents the “midnight boundary” attack where an agent spends the daily limit at 23:59 and again at 00:01.

Whitelist Modes

No whitelist — the agent can transfer to any recipient.

Privacy Levels

Events Emitted

Last modified on February 8, 2026