Skip to main content

PolicyManager

The PolicyManager class handles all agent policy operations — initialization, updates, spend tracking, whitelist construction, and policy presets.
import { PolicyManager } from '@x0-protocol/sdk';

const policyManager = new PolicyManager(connection);
// or access via client:
const policyManager = client.policy;

PDA Derivation

derivePolicyAddress(owner)

const policyPda = policyManager.derivePolicyAddress(ownerPubkey);
Seeds: ["agent_policy", owner.toBytes()]

Fetching Policies

fetchPolicy(policyAddress)

const policy = await policyManager.fetchPolicy(policyPda);
Returns: AgentPolicyAccount | null

fetchPolicyByOwner(owner)

const policy = await policyManager.fetchPolicyByOwner(ownerPubkey);

AgentPolicyAccount

FieldTypeDescription
ownerPublicKeyPolicy owner (human)
agentSignerPublicKeyAuthorized agent key
dailyLimitBNRolling 24h spend limit
spendLimitBN?Optional total spend limit
txLimitBN?Optional per-transaction limit
maxSingleTransactionBNMaximum single transaction amount
currentSpendBNCurrent rolling spend
privacyLevelnumber0 = Public, 1 = Confidential
whitelistModenumber0 = None, 1 = Merkle, 2 = Bloom, 3 = Domain
whitelistDataUint8ArrayEncoded whitelist data
isActivebooleanWhether policy is active
requireDelegationbooleanEnforce delegation model
boundTokenAccountPublicKey?Token account bound to this policy
rollingWindowSpendingEntry[]Rolling spend window entries
lastUpdatednumberLast policy update timestamp
bumpnumberPDA bump seed

Building Instructions

buildInitializePolicyInstruction(owner, agentSigner, config)

const { instruction, policyAddress } = await policyManager.buildInitializePolicyInstruction(
  ownerPubkey,
  agentPubkey,
  {
    dailyLimit: new BN(100_000_000),
    whitelist: { mode: 0 },
    privacy: { level: 0 },
  }
);

buildUpdatePolicyInstruction(owner, policyAddress, updates)

const ix = policyManager.buildUpdatePolicyInstruction(
  ownerPubkey,
  policyPda,
  { dailyLimit: new BN(500_000_000) }
);

buildUpdateAgentSignerInstruction(owner, policyAddress, newSigner)

Rotate the agent signing key.

buildRevokeAgentAuthorityInstruction(owner, policyAddress)

Kill switch — disable the agent.

buildSetPolicyActiveInstruction(owner, policyAddress, active)

Pause or resume the agent’s policy.

buildRecordBlinkInstruction(agent, policyAddress, treasury, amount, recipient, reason)

Record a Blink generation on-chain.

Spend Tracking

getCurrentSpend(policyAddress)

const { currentSpend, remaining, oldestExpiry } = await policyManager.getCurrentSpend(policyPda);

getRemainingSpendCapacity(policy)

const remaining = policyManager.getRemainingSpendCapacity(policy);

wouldExceedSpendLimit(policy, amount)

if (policyManager.wouldExceedSpendLimit(policy, transferAmount)) {
  // Generate Blink for human approval
}

wouldExceedTxLimit(policy, amount)

Check if a single transaction exceeds the per-transaction limit.

Whitelist Construction

buildMerkleWhitelist(addresses)

Build a Merkle tree root from a list of allowed addresses.
const merkleRoot = policyManager.buildMerkleWhitelist([
  new PublicKey('Addr1...'),
  new PublicKey('Addr2...'),
  new PublicKey('Addr3...'),
]);

// Use in policy config:
const config = {
  dailyLimit: new BN(100_000_000),
  whitelist: { mode: 1, root: merkleRoot }, // 1 = Merkle
  privacy: { level: 0 },
};

buildBloomWhitelist(addresses, sizeBytes?, hashCount?)

Build a Bloom filter for probabilistic whitelist checking.
const bloomBits = policyManager.buildBloomWhitelist(addresses, 4096, 7);

buildDomainWhitelist(domains)

Build a domain-prefix whitelist.
const domainData = policyManager.buildDomainWhitelist([
  'merchant',
  'exchange',
  'service_',
]);

Policy Presets

Three built-in presets for common risk profiles:
const conservative = policyManager.getConservativePreset();
// { dailyLimit: 100 USDC, txLimit: 10 USDC }

const moderate = policyManager.getModeratePreset();
// { dailyLimit: 1,000 USDC, txLimit: 100 USDC }

const permissive = policyManager.getPermissivePreset();
// { dailyLimit: 10,000 USDC, txLimit: 1,000 USDC }
Use a preset as a starting point:
const { policyAddress } = await client.initializePolicy(agentPubkey, {
  ...policyManager.getModeratePreset(),
  whitelist: { mode: 1, root: merkleRoot },
  privacy: { level: 0 },
});
Last modified on February 8, 2026