Skip to content

SDK Integration Guide

Audience and boundary

This guide is for developers building AI products with vibe coding, LangChain, the OpenAI SDK, or a custom Agent runtime. The open SDK governs spend and paid capability calls. The private X-Agent Commerce Gateway will own end-user credits, top-ups, provider routing, and durable accounting.

  1. Start with Xpense in dry-run mode and validate Payment Intent/budget behavior.
  2. Add createPayFetch around paid external APIs; only server code may call wallet or backend signing.
  3. Use createXAgentClient() with a short-lived end-user session and choose an approved OpenRouter model in chat(). Do not implement real reserve/settle in the application or browser.
  4. Add LangChain or MCP adapters with a budget per Agent task.

Payment Intent and policy

A Payment Intent is an auditable policy object, not a private key or blockchain transaction. Treat rejection, approval, and revocation as first-class product states.

ts
const xpense = new Xpense({
  mode: "dry-run",
  budget: { perTxn: { amount: "2", currency: "USDC" } }
});

await xpense.emit({
  reason: { category: "data", description: "Dataset access" },
  counterparty: { kind: "merchant", name: "Acme Data" },
  amount: { kind: "fixed", value: { amount: "1.20", currency: "USDC" } },
  approval: { mode: "policy" },
  policy: { allowedCurrencies: ["USDC"] }
});

HTTP 402 requirements

text
Request → 402 → validate offer → authorize policy/budget → backend signing
→ retry once with credential → resource or receipt
  • Use allowlisted merchants and validated resources only.
  • For POST, use a business idempotency key and enable replay only if the provider documents idempotency support.
  • Preserve identifiers for reconciliation when delivery or payment status is unknown.
  • Perform wallet signing only in a server-side trusted execution boundary.

Runtime and private Gateway

ts
const xagent = createXAgentClient({ baseUrl, sessionToken });
await xagent.chat({
  requestId: "chat_01J...",
  provider: "openrouter",
  model: "anthropic/claude-sonnet-4", // developer-selected model
  messages: [{ role: "user", content: "Draft a release note" }]
});

provider currently accepts openrouter. The Gateway checks the project's provider/model allowlist, output limits, and price policy. A client-supplied model is a preference, never an authorization to spend.

The SDK createXAgent() ports (BillingPort and ModelProvider) define the expected safety state machine and support SDK testing. They are trusted server-side ports, not browser integration points.

The Gateway must enforce:

InvariantRequirement
Tenant isolationDerive tenant/project/user from session claims; include them in database constraints.
Correct balancesAppend-only credit ledger; transactional reserve, settle, and release.
No duplicate executionOne execution/provider attempt for a tenant + project + user + idempotency key + request hash.
Unknown outcomesPersist provider attempt ID, deadline, receipt, and delivery state; reconcile before replay.
Authoritative priceCalculate admission and end-user price from private project policy, model, and output limits.

Production checklist

  • Keep project secrets in the application backend only.
  • Mint short-lived, revocable, audience-scoped end-user sessions.
  • Keep provider credentials and wallet keys inside the Gateway.
  • Enforce object-level authorization on usage, balances, and receipts.
  • Verify webhook signatures, time windows, replay protection, and idempotency.
  • Use request/receipt IDs for redacted observability.
  • Set provider timeouts, AbortSignal, concurrency limits, and provider-level idempotency keys.

Current limitation

This repository does not yet provide real top-ups, user accounts, model routing, a durable ledger, or a Gateway HTTP client. InMemoryBilling is test-only and must not be used as a wallet or multi-instance ledger.

See the Chinese guide and development plan.

Proprietary software. All rights reserved.