Skip to content

AffixIO/Agentic-Trust

Repository files navigation

@affix-io/agentic-trust

TypeScript SDK for the AffixIO agentic trust and verification API. Designed for AI agents, issuer processors, and fintech / payments teams that need reliable agent identity, consent verification, and trusted payment authorization across high-risk transactions.

Features

  • Agentic payments ready: Purpose-built helpers for issuer authorizations, merchant checkouts, and high-value payment flows.
  • AI agent verification: Verify that an AI agent or automation is allowed to act on behalf of a human or business.
  • Consent & policy enforcement: Check consent references and business rules before executing transactions.
  • Composite verification circuits: Chain multiple circuits (e.g. agentic-payment-permission, finance-account-standing, finance-fraud-indicator) into one decision.
  • Production-grade error handling: Distinct error types for transport, API, and validation failures.
  • Full TypeScript support: Strongly-typed client, inputs, and responses.
  • Stateless architecture: Each verification call is independent; easy to scale horizontally.
  • Minimal dependencies: Uses native fetch; ideal for Node.js services, edge runtimes, and serverless.

Use cases: AI agent payments, autonomous procurement, agentic checkout, delegated card controls, high-risk transaction decisioning.

Installation

npm install @affix-io/agentic-trust

or with pnpm / yarn:

pnpm add @affix-io/agentic-trust
yarn add @affix-io/agentic-trust

Quick Start

Basic Setup

import { AffixioClient } from '@affix-io/agentic-trust';

// Initialize with API key
const client = new AffixioClient({
  apiKey: process.env.AFFIXIO_API_KEY!,
  baseUrl: 'https://api.affix-io.com', // optional, default shown
  timeoutMs: 5000, // optional, default shown
});

// Or load from environment variables: AFFIXIO_API_KEY, AFFIXIO_BASE_URL, AFFIXIO_TIMEOUT_MS
const clientFromEnv = AffixioClient.fromEnv();

Issuer Agent Authorization (Agentic Payments)

Verify if an AI agent / processor is authorized to perform a payment on behalf of an account holder:

const result = await client.verifyIssuerAgentAuthorization({
  agentId: 'agent:procurement-001',
  accountId: 'acct_12345',
  consentReference: 'consent_abc_xyz',
  amount: 14900, // in minor units (cents)
  currency: 'USD',
  merchantCategory: 'software_subscription',
  merchantId: 'merchant_xyz',
  channel: 'account_to_account',
  additionalRiskContext: {
    ip_country: 'US',
    device_trust_score: 0.95,
  },
});

if (result.eligible) {
  console.log('Agent authorized; proof:', result.proof);
  // Proceed with payment
} else {
  console.log('Agent not authorized');
  // Decline or step up authentication
}

Merchant Agent Checkout

Verify if an agent can safely proceed with a checkout on behalf of a merchant:

const result = await client.verifyMerchantAgentCheckout({
  agentId: 'agent:checkout-bot-001',
  customerId: 'cust_456',
  basketTotalCents: 5999,
  currency: 'USD',
  merchantId: 'merchant_xyz',
  merchantCategory: 'software_subscription',
  basketCategories: ['licenses', 'support'],
  sessionId: 'sess_789',
  policyReference: 'policy_tier_2',
});

if (result.eligible) {
  // Safe to process checkout
  recordTransaction(result.proof);
} else {
  // Require merchant approval or additional steps
}

Consent Verification for AI Agents

Verify that valid consent exists for an agentic transaction:

const result = await client.verifyAgentConsent({
  agentId: 'agent:travel-planner',
  consentReference: 'consent_flight_booking_2024',
  transactionContext: {
    amount_cents: 2500,
    currency: 'USD',
    merchant_category: 'travel_agency',
    purpose: 'flight_booking',
  },
});

if (result.eligible) {
  // Consent is valid; proceed
} else {
  // Require fresh consent
}

Composite Verification (Multi‑Circuit)

Chain multiple circuits and get a single overall eligibility decision. Useful for high-value or high-risk payments where you want to verify multiple risk factors in sequence:

const result = await client.verifyAgentPaymentComposite({
  agentId: 'agent:high-value-processor',
  accountId: 'acct_hv_001',
  consentReference: 'consent_ref_xyz',
  transactionContext: {
    amount_cents: 500000, // $5,000
    currency: 'USD',
    merchant_category: 'travel_agency',
    merchant_id: 'merchant_luxury',
  },
  // Optional: specify custom circuits; defaults to:
  // ['agentic-payment-permission', 'finance-account-standing', 'finance-fraud-indicator']
  circuits: [
    'agentic-payment-permission',
    'finance-account-standing',
    'finance-fraud-indicator',
  ],
});

if (result.overallEligible) {
  console.log('All checks passed; aggregate proof:', result.aggregatedProof);
  // Proceed with payment
} else {
  console.log('At least one circuit failed:');
  result.perCircuit.forEach((r) => {
    console.log(`  ${r.circuitId}: ${r.eligible ? 'PASS' : 'FAIL'}`);
  });
  // Decline or escalate
}

Error Handling

The SDK distinguishes between three error types:

Transport Errors

Network failures, timeouts, or connection issues:

import { AffixioTransportError } from '@affix-io/agentic-trust';

try {
  await client.verifyIssuerAgentAuthorization({ /* ... */ });
} catch (error) {
  if (error instanceof AffixioTransportError) {
    console.error('Network issue:', error.message);
    // Retry with backoff; consider fallback
  }
}

API Errors

4xx or 5xx responses from the server:

import { AffixioApiError } from '@affix-io/agentic-trust';

try {
  await client.verifyIssuerAgentAuthorization({ /* ... */ });
} catch (error) {
  if (error instanceof AffixioApiError) {
    console.error(`API error ${error.status}:`, error.body);
    console.error('Request ID:', error.requestId); // Use for support requests
    // Log for alerting and debugging
  }
}

Validation Errors

Missing or invalid fields on the client side:

import { AffixioValidationError } from '@affix-io/agentic-trust';

try {
  await client.verifyIssuerAgentAuthorization({
    agentId: 'agent:test',
    // Missing required fields...
  });
} catch (error) {
  if (error instanceof AffixioValidationError) {
    console.error(`Validation failed on ${error.field}: ${error.message}`);
    // Fix your input and retry
  }
}

Logging and Proofs

All verification responses include a proof field—a cryptographic proof or hash that uniquely identifies the verification. Use this for audit trails and transaction reconciliation:

const result = await client.verifyIssuerAgentAuthorization({...});

// Persist the proof with your transaction record
recordTransaction({
  agentId: 'agent:procurement-001',
  accountId: 'acct_12345',
  verificationProof: result.proof,
  circuitId: result.circuit_id,
  latency_ms: result.latency_ms,
  timestamp: new Date().toISOString(),
});

For composite verifications, aggregatedProof combines proofs from all circuits:

const result = await client.verifyAgentPaymentComposite({...});

// Log composite result with per-circuit breakdown
logPaymentVerification({
  overallEligible: result.overallEligible,
  aggregatedProof: result.aggregatedProof,
  circuitResults: result.perCircuit.map((r) => ({
    circuitId: r.circuitId,
    eligible: r.eligible,
    proof: r.proof,
    latencyMs: r.latency_ms,
  })),
});

Configuration

Environment Variables

Set these to use AffixioClient.fromEnv():

  • AFFIXIO_API_KEY (required): Bearer token for API authentication
  • AFFIXIO_BASE_URL (optional): API endpoint; defaults to https://api.affix-io.com
  • AFFIXIO_TIMEOUT_MS (optional): Request timeout in milliseconds; defaults to 5000

Custom Logger

Provide a logger to track SDK activity:

const client = new AffixioClient({
  apiKey: process.env.AFFIXIO_API_KEY!,
  logger: {
    info: (message, metadata) => console.log(`[INFO] ${message}`, metadata),
    warn: (message, metadata) => console.warn(`[WARN] ${message}`, metadata),
    error: (message, metadata) => console.error(`[ERROR] ${message}`, metadata),
  },
});

Type Reference

VerifyResponse

Returned by all verification methods.

interface VerifyResponse {
  eligible: boolean; // Is the agent/user eligible?
  proof: string; // Cryptographic proof of the verification
  circuit_id: string; // Which circuit ran?
  latency_ms?: number; // How long did the verification take?
  logged?: boolean; // Was the result logged server-side?
  raw?: unknown; // Raw API response (if needed for custom handling)
}

AgentPaymentCompositeResponse

Returned by verifyAgentPaymentComposite().

interface AgentPaymentCompositeResponse {
  overallEligible: boolean; // Synthesis of all circuits
  perCircuit: CompositeCircuitResult[];
  aggregatedProof: string; // Combined proof from all circuits
}

Development

Build

npm run build

Compiles TypeScript to ./dist with type declarations.

Tests

npm test

Runs unit tests covering:

  • Happy path verification calls
  • Error handling and mapping
  • Validation of required fields
  • Composite verification logic

Architecture

The SDK is organized as:

  • client.ts: Main AffixioClient class with public verification methods
  • types.ts: TypeScript type definitions (no runtime code)
  • errors.ts: Custom error classes (Transport, API, Validation)
  • http.ts: Low-level HTTP abstraction using native fetch
  • helpers.ts: Request builders and utility functions
  • index.ts: Public API exports

Zero dependencies beyond Node.js built-ins and TypeScript.

Design Principles

  1. Stateless: No sessions or stored state. Each call is independent.
  2. Strongly typed: Full TypeScript for safety and IDE support.
  3. Minimal: No unnecessary abstractions. One method per use case.
  4. Portable: Pattern is designed to be ported to Go, Java, Python with minimal changes.
  5. Observable: Every call generates a proof and optional latency metrics for audit trails.

License

MIT