API REFERENCE

    Complete API documentation for @vanar/xbpp.

    FUNCTIONS

    evaluate(request, policy)

    Evaluates a payment request against a policy and returns a verdict. This is the core function of the SDK.

    evaluate(request: PaymentRequest, policy: Policy): Verdict

    Runs 12 policy checks in order. Block checks take priority over escalation checks. If any block reason exists, the verdict is BLOCK regardless of escalation reasons.

    Side effects: Records the transaction in an in-memory history for budget tracking and pattern detection. History is pruned to the last 24 hours.

    wrap(fetchFn, policy)

    Wraps a fetch-compatible function with xBPP policy evaluation. Intercepts x402 payment headers and evaluates them before the request is sent.

    wrap(fetchFn: typeof fetch, policy: Policy): typeof fetch

    Non-payment requests (no x402 headers) pass through unchanged with zero overhead. Throws BlockedError on BLOCK or EscalateError on ESCALATE.

    TYPES

    typePaymentRequest

    interface PaymentRequest {
      amount: number           // Required - the transaction value
      currency?: string        // e.g., 'USD', 'USDC', 'EUR'
      recipient?: string       // email, domain, or URL
      metadata?: Record<string, unknown>  // custom data
    }

    typePolicy

    interface Policy {
      maxSingle?: number              // Max per transaction
      dailyBudget?: number            // Max per rolling 24h
      hourlyBudget?: number           // Max per rolling 1h
      askMeAbove?: number             // Escalate above this amount
      trustedRecipients?: string[]    // Allowed recipients
      blockedDomains?: string[]       // Blocked domains
      allowedCurrencies?: string[]    // Allowed currencies
      maxRequestsPerMinute?: number   // Rate limit
      operatingHours?: OperatingHours // Time-of-day restrictions
      expiresAt?: Date                // Policy expiration
    }

    typeVerdict

    interface Verdict {
      decision: 'ALLOW' | 'BLOCK' | 'ESCALATE'
      reasons: PolicyReason[]   // Why this decision was made
      message: string           // Human-readable explanation
      request: PaymentRequest   // Echo of original request
      timestamp: Date           // When evaluated
    }

    typeDecision

    type Decision = 'ALLOW' | 'BLOCK' | 'ESCALATE'

    typePolicyReason

    type PolicyReason =
      | 'EXCEEDS_SINGLE_LIMIT'        // amount > maxSingle
      | 'EXCEEDS_DAILY_BUDGET'        // rolling 24h total exceeded
      | 'EXCEEDS_HOURLY_BUDGET'       // rolling 1h total exceeded
      | 'UNFAMILIAR_RECIPIENT'        // not in trustedRecipients
      | 'BLOCKED_DOMAIN'              // domain in blockedDomains
      | 'SUSPICIOUS_PATTERN'          // 3+ same recipient in 5min
      | 'CURRENCY_MISMATCH'           // not in allowedCurrencies
      | 'RATE_LIMIT_EXCEEDED'         // > maxRequestsPerMinute
      | 'ABOVE_ESCALATION_THRESHOLD'  // amount > askMeAbove
      | 'OUTSIDE_OPERATING_HOURS'     // outside operatingHours
      | 'AMOUNT_ZERO_OR_NEGATIVE'     // amount <= 0
      | 'POLICY_EXPIRED'              // past expiresAt

    typeOperatingHours

    interface OperatingHours {
      start: string      // "HH:MM" format, e.g., "09:00"
      end: string        // "HH:MM" format, e.g., "17:00"
      timezone?: string  // IANA timezone, e.g., "America/New_York"
    }

    ERROR CLASSES

    BlockedError

    Thrown by wrap() when the verdict is BLOCK.

    class BlockedError extends Error {
      reasons: PolicyReason[]
      verdict: Verdict
    }

    EscalateError

    Thrown by wrap() when the verdict is ESCALATE. Provides callbacks to resume or cancel the request after human review.

    class EscalateError extends Error {
      reasons: PolicyReason[]
      verdict: Verdict
      onApprove(): Promise<Response>  // Resume the original request
      onDeny(): void                  // Cancel
    }