Advanced Topics
Custom Policy Logic

Custom Policy Logic

Build custom validation and policy logic on top of Aegis.

Overview

While Aegis provides daily limits and whitelists on-chain, you can add additional custom policies in your application layer.

Pre-Transaction Validation

Time-Based Limits

Restrict transactions to specific time windows:

class TimeRestrictedVault {
  private allowedHours = { start: 9, end: 17 }; // 9 AM - 5 PM
 
  async executeWithTimeCheck(params: ExecuteAgentOptions) {
    const hour = new Date().getHours();
 
    if (hour < this.allowedHours.start || hour >= this.allowedHours.end) {
      throw new Error('Transactions only allowed during business hours');
    }
 
    return await this.client.executeAgent(params);
  }
}

Amount Limits Per Destination

Track spending per recipient:

class PerRecipientLimits {
  private spendingTracker = new Map<string, number>();
  private perRecipientLimit = 1 * LAMPORTS_PER_SOL;
 
  async executeWithRecipientLimit(params: ExecuteAgentOptions) {
    const spent = this.spendingTracker.get(params.destination) || 0;
 
    if (spent + params.amount > this.perRecipientLimit) {
      throw new Error(`Exceeds per-recipient limit for ${params.destination}`);
    }
 
    const signature = await this.client.executeAgent(params);
 
    this.spendingTracker.set(
      params.destination,
      spent + params.amount
    );
 
    return signature;
  }
}

Velocity Checks

Prevent rapid successive transactions:

class VelocityCheck {
  private lastTransaction = 0;
  private minimumDelay = 60000; // 1 minute
 
  async executeWithVelocityCheck(params: ExecuteAgentOptions) {
    const now = Date.now();
    const timeSinceLastMSec = now - this.lastTransaction;
 
    if (timeSinceLastTx < this.minimumDelay) {
      throw new Error(`Must wait ${this.minimumDelay / 1000}s between transactions`);
    }
 
    const signature = await this.client.executeAgent(params);
    this.lastTransaction = now;
 
    return signature;
  }
}

Multi-Signature Approval

Require multiple approvals for large transactions:

class MultiSigPolicy {
  private pendingApprovals = new Map<string, Set<string>>();
  private requiredSignatures = 2;
 
  async requestApproval(txId: string, approver: string, params: ExecuteAgentOptions) {
    if (!this.pendingApprovals.has(txId)) {
      this.pendingApprovals.set(txId, new Set());
    }
 
    const approvals = this.pendingApprovals.get(txId)!;
    approvals.add(approver);
 
    if (approvals.size >= this.requiredSignatures) {
      // Execute transaction
      const signature = await this.client.executeAgent(params);
      this.pendingApprovals.delete(txId);
      return signature;
    }
 
    return { status: 'pending', approvals: approvals.size };
  }
}

Risk Scoring

Score transactions by risk level:

interface RiskFactors {
  isNewRecipient: boolean;
  isLargeAmount: boolean;
  isOffHours: boolean;
  velocityHigh: boolean;
}
 
class RiskBasedPolicy {
  calculateRiskScore(params: ExecuteAgentOptions, factors: RiskFactors): number {
    let score = 0;
 
    if (factors.isNewRecipient) score += 3;
    if (factors.isLargeAmount) score += 5;
    if (factors.isOffHours) score += 2;
    if (factors.velocityHigh) score += 4;
 
    return score;
  }
 
  async executeWithRiskCheck(params: ExecuteAgentOptions) {
    const factors = this.assessFactors(params);
    const riskScore = this.calculateRiskScore(params, factors);
 
    if (riskScore >= 10) {
      // High risk - require manual approval
      await this.requestManualApproval(params, riskScore);
      throw new Error('High risk transaction - manual approval required');
    }
 
    if (riskScore >= 5) {
      // Medium risk - add delay
      await this.delay(60000); // 1 minute delay
    }
 
    // Low risk - execute immediately
    return await this.client.executeAgent(params);
  }
}

Compliance Rules

Implement compliance requirements:

class CompliancePolicy {
  private sanctionedAddresses = new Set<string>();
  private maxTransactionSize = 10 * LAMPORTS_PER_SOL;
 
  async executeWithCompliance(params: ExecuteAgentOptions) {
    // Sanctions screening
    if (this.sanctionedAddresses.has(params.destination)) {
      await this.reportViolation('SANCTIONED_ADDRESS', params);
      throw new Error('Destination is on sanctions list');
    }
 
    // Large transaction reporting
    if (params.amount > this.maxTransactionSize) {
      await this.reportLargeTransaction(params);
    }
 
    // Execute with audit trail
    const signature = await this.client.executeAgent(params);
 
    await this.logComplianceEvent({
      signature,
      destination: params.destination,
      amount: params.amount,
      timestamp: new Date(),
    });
 
    return signature;
  }
}

Combined Policies

Combine multiple policies:

class AdvancedVault {
  private policies = [
    new TimeRestrictedVault(),
    new VelocityCheck(),
    new RiskBasedPolicy(),
    new CompliancePolicy(),
  ];
 
  async execute(params: ExecuteAgentOptions) {
    // Run all policy checks
    for (const policy of this.policies) {
      await policy.validate(params);
    }
 
    // All checks passed - execute
    return await this.client.executeAgent(params);
  }
}

Next Steps