Agent Payments
Build autonomous AI agents that can make payments using the Veridex Agent SDK (@veridex/agentic-payments). This guide covers both a beginner-friendly walkthrough and references to a production-grade advanced example.
Passkey Wallet Required: The Agent SDK (@veridex/agentic-payments) is built on top of @veridex/sdk, which requires a passkey wallet created via a frontend. Passkey operations (register, authenticate) use WebAuthn browser APIs and cannot run in Node.js or server-side code. Your app must have a browser-based frontend that creates the passkey, then passes the credential to the server-side agent.
Try It — Working Examples
🟢 Basic Example
Minimal Next.js app — passkey wallet + agent provisioning + simple payments. Best for beginners.
🔵 Advanced Example
Production-grade — Gemini AI chat, MCP tools, ERC-8004 identity, trust gates, multi-chain.
Overview
The Agent SDK enables AI agents to:
- Pay for APIs automatically via multiple protocols (x402, UCP, ACP, AP2) with auto-detection
- Expose MCP tools for integration with AI models (Gemini, Claude, GPT)
- Manage spending limits with daily and per-transaction caps
- Use session keys so the master passkey isn't needed for every payment
- Register on-chain identity via ERC-8004 and enforce trust gates
- Monitor spending with real-time alerts and audit logs
- Operate across chains including EVM, Solana, Stacks, Monad, and more
Prerequisites
bun add @veridex/agentic-payments @veridex/sdkYou'll also need:
- A browser-based frontend to create the passkey wallet (WebAuthn)
- Testnet tokens on your target chain (e.g., USDC on Base Sepolia via Circle Faucet (opens in a new tab))
Next.js Webpack Configuration
If you're using Next.js, add this next.config.mjs to handle transitive dependency resolution from the SDK's multi-chain support:
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
transpilePackages: ['@veridex/sdk', '@veridex/agentic-payments'],
webpack: (config, { isServer }) => {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
};
// Ignore problematic transitive deps from @aptos-labs/ts-sdk
// that reference unexported paths in @noble/curves
config.resolve.alias = {
...config.resolve.alias,
'@aptos-labs/ts-sdk': false,
};
return config;
},
};
export default nextConfig;Without this config, Next.js builds will fail with a Module not found: Package path ./nist.js is not exported from package @noble/curves error. This is caused by @aptos-labs/ts-sdk (a transitive dependency of @veridex/sdk) referencing unexported module paths.
Architecture
Every agent app has the same two-layer architecture:
┌─────────────────────────────────────────┐
│ Browser (React / Next.js client) │
│ • @veridex/sdk │
│ • Passkey registration (WebAuthn) │
│ • Sends credential to backend │
└──────────┬──────────────────────────────┘
│ POST /api/agent
┌──────────▼──────────────────────────────┐
│ Server (Next.js API Route / Express) │
│ • @veridex/agentic-payments │
│ • createAgentWallet(credential) │
│ • agent.pay() / getBalance() / fetch() │
│ • MCP tools for AI models │
└─────────────────────────────────────────┘Basic Example: Step by Step
This walkthrough matches the agent-basic (opens in a new tab) example.
Step 1: Create Passkey Wallet (Browser)
The passkey must be created in the browser. Use @veridex/sdk:
// This runs in the browser (React component, 'use client')
import { createSDK } from '@veridex/sdk';
const sdk = createSDK('base');
// Register a new passkey — triggers WebAuthn biometric prompt
const credential = await sdk.passkey.register('alice', 'alice');
// Persist to localStorage for page reloads
sdk.passkey.saveToLocalStorage();
// These values are sent to the server to create the agent
const { credentialId, publicKeyX, publicKeyY, keyHash } = credential;The credentialId, publicKeyX, publicKeyY, and keyHash are the four values the server needs to create an AgentWallet. The passkey itself stays on the user's device — only the public key data is sent to the server.
Step 2: Create Agent Wallet (Server)
On the server, use createAgentWallet with the credential from the frontend:
// Next.js API Route: app/api/agent/route.ts
import { createAgentWallet, AgentWallet } from '@veridex/agentic-payments';
let agent: AgentWallet | null = null;
// Called when the frontend sends the passkey credential
async function provision(credential: any, session: any) {
agent = await createAgentWallet({
masterCredential: {
credentialId: credential.credentialId,
publicKeyX: BigInt(credential.publicKeyX),
publicKeyY: BigInt(credential.publicKeyY),
keyHash: credential.keyHash,
},
session: {
dailyLimitUSD: session.dailyLimitUSD ?? 50,
perTransactionLimitUSD: session.perTransactionLimitUSD ?? 10,
expiryHours: session.expiryHours ?? 24,
allowedChains: [10004], // Base Sepolia
},
});
return agent;
}Step 3: Check Balance
const tokens = await agent.getBalance(10004); // Base Sepolia
console.log('Tokens:', tokens);Step 4: Make a Payment
const receipt = await agent.pay({
chain: 10004, // Base Sepolia (Wormhole chain ID)
token: 'USDC',
amount: '5000000', // 5 USDC (6 decimals)
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
});
console.log('Tx hash:', receipt.txHash);
console.log('Status:', receipt.status); // 'confirmed'Step 5: Monitor Session
const status = agent.getSessionStatus();
console.log('Session valid:', status.isValid);
console.log('Wallet address:', status.address);
console.log('Daily limit:', `$${status.limits!.dailyLimitUSD}`);
console.log('Spent today:', `$${status.totalSpentUSD.toFixed(2)}`);
console.log('Remaining:', `$${status.remainingDailyLimitUSD.toFixed(2)}`);Step 6: Revoke Session
await agent.revokeSession();Run the full example: Clone the examples repo (opens in a new tab) and run cd agent-basic && bun install && bun run dev. Open http://localhost:3000 to try it.
Advanced Example: AI Agent with Gemini
The agent-advanced (opens in a new tab) example adds:
- Gemini AI chat with function calling
- MCP tools mapped to Gemini function declarations
- ERC-8004 identity (optional) for on-chain agent registration
- Trust-gated payments via reputation scoring
- Multi-chain support (Base + Ethereum Sepolia)
MCP Tools → AI Function Calling
The Agent SDK exposes MCP tools that map directly to any AI model's function calling interface:
import { AgentWallet } from '@veridex/agentic-payments';
// Get MCP tools from the agent
const mcpTools = agent.getMCPTools();| Tool Name | Description |
|---|---|
veridex_pay | Execute a token payment (chain, token, amount, recipient) |
veridex_check_balance | Check wallet balance on a specific chain |
veridex_create_session_key | Create a new bounded session |
veridex_revoke_session | Revoke agent wallet access |
veridex_get_payment_history | Retrieve transaction history |
Mapping to Gemini
import { SchemaType } from '@google/generative-ai';
const tools = mcpTools.map(tool => ({
declaration: {
name: tool.name,
description: tool.description,
parameters: {
type: SchemaType.OBJECT,
properties: tool.inputSchema.properties,
required: tool.inputSchema.required || [],
},
},
execute: async (args: any) => {
const result = await tool.handler(args);
// Serialize BigInts for JSON compatibility
return JSON.parse(JSON.stringify(result, (_, v) =>
typeof v === 'bigint' ? v.toString() : v
));
},
}));BigInt serialization: The Agent SDK returns bigint values for token amounts. Always serialize them to strings before passing to AI model APIs (Gemini, OpenAI, etc.) which don't support BigInt in JSON.
Automatic x402 Payments
When the agent uses agent.fetch(), payment protocols are handled transparently:
// Auto-detects x402, UCP, ACP, or AP2 and handles payment
const response = await agent.fetch('https://paid-api.example.com/data', {
onBeforePayment: async (estimate) => {
console.log(`About to pay $${estimate.amountUSD}`);
return estimate.amountUSD < 10; // auto-approve under $10
},
maxAutoApproveUSD: 5,
});
if (response.ok) {
const data = await response.json();
console.log('Got paid data:', data);
}ERC-8004 Identity (Optional)
Enable on-chain agent identity for trust-gated payments:
const agent = await createAgentWallet({
masterCredential: { /* ... */ },
session: { /* ... */ },
erc8004: {
enabled: true,
testnet: true,
minReputationScore: 20, // Reject merchants below 20/100
},
});
// Check merchant trust before paying
const trust = await agent.checkMerchantTrust('https://data-provider.com');
if (trust.trusted) {
console.log(`Trusted — score: ${trust.score}/100`);
}See the Agent Identity guide for full ERC-8004 documentation.
Run the advanced example: Clone the examples repo (opens in a new tab), add your GOOGLE_API_KEY to .env.local, and run cd agent-advanced && bun install && bun run dev. Open http://localhost:3001.
Error Handling
import { AgentPaymentError, AgentPaymentErrorCode } from '@veridex/agentic-payments';
try {
await agent.pay({ chain: 10004, token: 'USDC', amount: '100000000', recipient: '0x...' });
} catch (error) {
if (error instanceof AgentPaymentError) {
switch (error.code) {
case AgentPaymentErrorCode.LIMIT_EXCEEDED:
console.log('Over budget! Wait for daily reset.');
break;
case AgentPaymentErrorCode.INSUFFICIENT_BALANCE:
console.log('Need more tokens:', error.suggestion);
break;
case AgentPaymentErrorCode.SESSION_EXPIRED:
// Re-provision from frontend
break;
default:
console.error('Agent error:', error.message);
}
}
}Spending Alerts
agent.onSpendingAlert((alert) => {
console.warn(`[ALERT] ${alert.type}: ${alert.message}`);
});