Skip to content
Tollgate Docs

@tollgatepay/agent

The client SDK for AI agents. Runtime-agnostic: Node, Deno, Bun, browser, Cloudflare Workers, Vercel Edge. Depends only on viem (for the signTypedData shape) and @tollgatepay/core.

Drop-in fetch

import { TollgateClient, makeWallet, usd } from "@tollgatepay/agent";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`);
const client = new TollgateClient({
  wallet: makeWallet(account),
  maxSpendPerSession: usd("10.00"),
});

// Drop-in replacement for fetch — signs 402 challenges automatically.
const response = await client.fetch("https://api.example.com/premium");
const data = await response.json();

Flow

  1. GET the target URL.
  2. On 402, parse the PaymentRequiredResponse.
  3. Budget check (request / session / per-developer caps).
  4. Build and sign the IOU (EIP-712 typed data).
  5. Retry with x-tollgate-iou set. On success, commit budget + nonce.

Configuration

new TollgateClient({
  wallet: makeWallet(viemLocalAccount),       // or walletPool
  maxSpendPerRequest?: MicroUSDC,             // default $1.00
  maxSpendPerSession?: MicroUSDC,             // default $10.00
  perDeveloperCap?: ReadonlyMap<Address, MicroUSDC>,
  defaultChainId?: SupportedChainId,          // default Base
  fetch?: typeof fetch,                       // default globalThis.fetch
  nonceStore?: NonceStore,                    // default InMemoryNonceStore
  retry?: RetryOptions,
  logger?: AgentLogger,                       // narrow interface Logger satisfies
  onProgress?: (event: ProgressEvent) => void,
  iouDeadlineSeconds?: number,                // 1..120, default 110
});

Budgets

Three scopes: per-request, per-session, per-developer. Defaults ship opinionated ($1/req, $10/session). check() runs before signing; commit() runs only on response.ok, so a 5xx from the developer doesn't deduct budget.

Wallet abstraction

AgentSigner is a narrow viem-compatible interface (address + signTypedData(args)). Any Privy / Dynamic / hardware wallet client that exposes those two primitives plugs in via makeWallet().

Rotation is offered, not a defence

createWalletPool supports round-robin rotation for operational reasons (per-wallet caps, HSM key lifecycle). It doesnot defend against the approve-revoke-rotate attack — the defence lives developer-side (blacklist, graduated trust, exposure caps). See AUDIT_FALSE_POSITIVES.md §8.

See also