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-2022TransferChecked 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:
- Policy is active —
is_activemust betrue - Amount within single-transaction limit — If
max_single_transactionis set, the amount must not exceed it - Rolling window budget — The cumulative spend in the last 24 hours plus this amount must not exceed
daily_limit - Whitelist membership — If a whitelist is configured, the recipient must pass verification
- Minimum transfer amount — Amount must be ≥ 100 micro-units (anti-dust)
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.
record_blink
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
["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:- On each transfer, expired entries (older than
ROLLING_WINDOW_SECONDS = 86,400) are pruned - The sum of remaining entries is computed as
current_spend - If
current_spend + amount > daily_limit, the transfer is rejected - On success, a new
SpendingEntryis appended - Maximum entries capped at
MAX_ROLLING_WINDOW_ENTRIES = 144(~one per 10 minutes)
Whitelist Modes
- None
- Merkle
- Bloom
- Domain
No whitelist — the agent can transfer to any recipient.