Skip to main content
The Arbiter SDK includes built-in support for AI-powered dispute resolution through evaluation hooks and a webhook handler. You can plug in any AI model — LLMs, rule engines, or hybrid systems — to automatically evaluate and decide on refund requests.

Core Concepts

The AI integration is built around three types:
  1. CaseEvaluationContext — the data your AI receives for each case
  2. DecisionResult — the decision your AI returns
  3. createWebhookHandler — wires your AI evaluation function to the arbiter

Case Evaluation Context

When a case needs evaluation, the handler provides a structured context:
interface CaseEvaluationContext {
  /** The payment information struct */
  paymentInfo: PaymentInfo;

  /** The record index (nonce) identifying which charge */
  nonce: bigint;

  /** Current payment state */
  paymentState: PaymentState;

  /** Current refund request status */
  refundStatus: number;

  /** Unique hash of the payment */
  paymentInfoHash: `0x${string}`;

  /** Amount being requested for refund */
  refundAmount?: bigint;

  /** Optional evidence/metadata */
  evidence?: unknown;
}

Decision Result

Your AI evaluation function returns a DecisionResult:
interface DecisionResult {
  /** The decision: approve or deny */
  decision: 'approve' | 'deny';

  /** Optional reasoning for the decision */
  reasoning?: string;

  /** Optional partial refund amount */
  refundAmount?: bigint;

  /** Confidence score (0-1) */
  confidence?: number;
}

Create a Webhook Handler

Use createWebhookHandler to connect your evaluation function to the arbiter:
import { createWebhookHandler } from '@x402r/arbiter';
import type { CaseEvaluationContext, DecisionResult } from '@x402r/arbiter';

const handler = createWebhookHandler({
  arbiter,
  evaluationHook: async (context: CaseEvaluationContext): Promise<DecisionResult> => {
    // Your AI evaluation logic here
    const result = await myAIModel.evaluate(context);

    return {
      decision: result.shouldApprove ? 'approve' : 'deny',
      reasoning: result.explanation,
      confidence: result.confidence,
    };
  },
  autoSubmitDecision: true,   // Auto-submit approve/deny on-chain
  confidenceThreshold: 0.9,   // Only auto-submit if confidence >= 0.9
});
Setting autoSubmitDecision: true calls approveRefundRequest or denyRefundRequest on-chain automatically. This submits the decision only — executing the actual refund transfer via executeRefundInEscrow is a separate step you handle after approval.

Webhook Handler Configuration

interface WebhookHandlerConfig {
  /** X402rArbiter instance */
  arbiter: X402rArbiter;

  /** Your evaluation function */
  evaluationHook: ArbiterHook;

  /** Auto-submit decisions on-chain (default: false) */
  autoSubmitDecision?: boolean;

  /** Minimum confidence for auto-submission (default: 0.8) */
  confidenceThreshold?: number;
}
The handler returns a WebhookResult that extends DecisionResult:
interface WebhookResult extends DecisionResult {
  /** Transaction hash if auto-submitted */
  txHash?: `0x${string}`;

  /** Whether the decision was submitted on-chain */
  executed: boolean;
}

Watch and Auto-Evaluate Pattern

The most common pattern combines watchNewCases with the webhook handler to automatically evaluate incoming refund requests:
import { X402rArbiter, createWebhookHandler } from '@x402r/arbiter';
import type { CaseEvaluationContext, DecisionResult, RefundRequestEventLog } from '@x402r/arbiter';
import { PaymentState, RequestStatus } from '@x402r/core';
import type { PaymentInfo } from '@x402r/core';

// Step 1: Create the webhook handler with your AI evaluation
const handler = createWebhookHandler({
  arbiter,
  evaluationHook: async (context: CaseEvaluationContext): Promise<DecisionResult> => {
    return evaluateWithAI(context);
  },
  autoSubmitDecision: true,
  confidenceThreshold: 0.85,
});

// Step 2: Watch for new cases and feed them to the handler
const { unsubscribe } = arbiter.watchNewCases(async (event: RefundRequestEventLog) => {
  const paymentInfoHash = event.args.paymentInfoHash!;
  const nonce = event.args.nonce ?? 0n;

  console.log(`[NEW CASE] ${paymentInfoHash} (nonce: ${nonce})`);

  // Build the evaluation context
  // NOTE: You need to reconstruct the full PaymentInfo from your database or event logs
  const paymentInfo = await lookupPaymentInfo(paymentInfoHash);

  const context: CaseEvaluationContext = {
    paymentInfo,
    nonce,
    paymentState: PaymentState.InEscrow,
    refundStatus: RequestStatus.Pending,
    paymentInfoHash,
    refundAmount: event.args.amount,
  };

  // Evaluate and optionally auto-submit
  const result = await handler(context);

  console.log(`[DECISION] ${result.decision} (confidence: ${result.confidence})`);
  console.log(`[REASONING] ${result.reasoning}`);

  if (result.executed) {
    console.log(`[ON-CHAIN] Decision submitted: ${result.txHash}`);

    // If approved, execute the refund transfer
    if (result.decision === 'approve') {
      const { txHash } = await arbiter.executeRefundInEscrow(
        paymentInfo,
        result.refundAmount // partial refund if specified
      );
      console.log(`[REFUND] Executed: ${txHash}`);
    }
  } else {
    console.log('[SKIPPED] Confidence below threshold, requires manual review');
  }
});

// Graceful shutdown
process.on('SIGINT', () => {
  unsubscribe();
  process.exit();
});

Evaluation Patterns

The evaluationHook function receives a CaseEvaluationContext and returns a DecisionResult. Three common patterns:
  • LLM-based — Send the structured context to an LLM (GPT-4, Claude, etc.) with a system prompt that outputs JSON {decision, reasoning, confidence}. Sanitize inputs to prevent prompt injection.
  • Rule-based — Apply deterministic rules (amount thresholds, blocklists) for predictable, high-confidence decisions. Best for clear-cut cases.
  • Hybrid — Apply hard rules first; if no rule matches with high confidence, fall back to LLM evaluation. Deny and flag for manual review when confidence is low.
AI-powered dispute resolution handles financial decisions. Always implement prompt injection protection, input validation, and confidence thresholds before deploying to production.

Next Steps

Event Subscriptions

Watch for new cases to evaluate in real-time.

Batch Operations

Process queued AI decisions in batches.

Decision Submission

Approve/deny individual cases and execute refunds.

Registry

Register your AI arbiter for on-chain discovery.