npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

paegents

v2.5.0

Published

Official TypeScript/JavaScript SDK for Paegents - Payment infrastructure for AI agents with Service Catalog and Usage Escrow

Readme

Paegents TypeScript/JavaScript SDK

The official TypeScript/JavaScript SDK for Paegents - Payment infrastructure for AI agents.

Installation

npm install paegents
# or
yarn add paegents

Quick Start

import { PaegentsSDK } from 'paegents';

// Initialize the SDK
const paegents = new PaegentsSDK({
  apiUrl: 'https://api.paegents.com',
  agentId: 'my_ai_agent',
  apiKey: 'ak_live_your_api_key_here'
});

// Make an A2A payment to a supplier
const response = await paegents.paySupplier(
  'acme-corp.com',
  2500, // $25.00 in cents
  'GPU compute credits'
);

console.log(`Payment ${response.status}: ${response.txnId}`);

// Check payment status
const status = await paegents.checkA2AStatus(response.txnId);
console.log(`Current status: ${status.status}`);

AP2 Mandates & Stablecoin (x402)

Create intent/cart mandates and execute card or stablecoin payments with a few lines of code.

import {
  buildCardPaymentMethod,
  buildStablecoinPaymentMethod,
} from 'paegents';

const intent = await paegents.createAp2IntentMandate({
  policy: {
    max_amount: { value: 25_00 },
    currency: 'usd',
  },
});

const cart = await paegents.createAp2CartMandate({
  intentMandateId: intent.id,
  cart: {
    total: 12_50,
    currency: 'usd',
    description: 'Monthly agent hosting',
  },
});

// Card rail (Stripe/Braintree)
const cardPayment = await paegents.ap2Pay({
  intentMandateId: intent.id,
  cartMandateId: cart.id,
  paymentMethod: buildCardPaymentMethod({ provider: 'stripe' }),
});
console.log(cardPayment.status);

// Stablecoin rail via Coinbase x402 (secure client-side signing)
const stablecoinPayment = await paegents.ap2Pay({
  intentMandateId: intent.id,
  cartMandateId: cart.id,
  paymentMethod: await buildStablecoinPaymentMethod({
    payerPrivateKey: process.env.STABLE_COIN_PRIVATE_KEY!,
    destinationWallet: '0xSellerWallet...',
    amountCents: 1250,  // $12.50
    resourceId: `cart:${cart.id}`,
    description: 'Monthly agent hosting',
    network: 'base-sepolia',  // or 'base' for mainnet
  }),
});
console.log(stablecoinPayment.onchainTxid);

Security Note: buildStablecoinPaymentMethod signs the payment CLIENT-SIDE. Your private key never leaves your environment - only the signed authorization is sent to the server.

Advanced: Direct X402 Signing

For custom integrations, you can use the low-level signing function:

// Import from the stablecoin subpath to opt-in to viem/x402 helpers
import { createSignedX402Payment } from 'paegents/stablecoin';

// Sign a payment authorization locally
const paymentHeader = await createSignedX402Payment({
  payerPrivateKey: process.env.AGENT_PRIVATE_KEY!,
  destinationWallet: '0xSeller...',
  amountCents: 500,
  resourceId: 'custom:payment:123',
  description: 'Custom payment',
  network: 'base-sepolia'
});

// Send only the signature to your API
const paymentMethod = {
  rail: 'stablecoin',
  provider: 'coinbase',
  wallet_address: '0xSeller...',
  payment_header: paymentHeader  // Signed authorization (secure!)
};

Browser with injected provider (viem)

import { createSignedX402Payment } from 'paegents/stablecoin';

// Request accounts then sign via provider (no private key in code)
const [signer] = await window.ethereum.request({ method: 'eth_requestAccounts' });
const paymentHeader = await createSignedX402Payment({
  provider: window.ethereum,
  signerAddress: signer,
  destinationWallet: '0xRecipient...',
  amountCents: 1250,
  resourceId: `cart:${cart.id}`,
  network: 'base-sepolia',
});

await sdk.ap2Pay({
  intentMandateId: intent.id,
  cartMandateId: cart.id,
  paymentMethod: {
    rail: 'stablecoin',
    provider: 'coinbase',
    wallet_address: '0xRecipient...',
    payment_header: paymentHeader,
  },
});

Supported Networks:

  • base-sepolia - Base Sepolia testnet (default)
  • base or base-mainnet - Base mainnet

The stablecoin helper requires a funded private key and the amount/resource ID for signing. You can override the network, timeout, or description via the helper options.

A2A (Agent-to-Agent) Payments

The core feature of Paegents is seamless agent-to-agent payments using domain-based supplier resolution.

Making a Payment

// Pay a supplier by domain
const response = await paegents.paySupplier(
  'software-company.io',
  5000, // $50.00 in cents
  'API usage charges',
  'usd' // Optional currency
);

// Handle different response statuses
switch (response.status) {
  case 'paid':
    console.log(`✅ Payment successful! Transaction: ${response.txnId}`);
    break;
  case 'processing':
    console.log(`⏳ Payment processing... Transaction: ${response.txnId}`);
    break;
  case 'supplier_onboarding':
    console.log(`📧 Supplier needs onboarding: ${response.nextActionUrl}`);
    break;
  case 'failed':
    console.log(`❌ Payment failed: ${response.error}`);
    break;
}

Checking Payment Status

// Poll for status updates
const status = await paegents.checkA2AStatus('agt_txn_123abc456def');

console.log(`Status: ${status.status}`);
console.log(`Events:`, status.events);

TypeScript Types

The SDK is fully typed for excellent developer experience:

import { A2APaymentResponse, A2AStatusResponse } from 'paegents';

// Response types are automatically inferred
const payment: A2APaymentResponse = await paegents.paySupplier(
  'example.com',
  1000,
  'Test payment'
);

const status: A2AStatusResponse = await paegents.checkA2AStatus(payment.txnId);

Traditional MCP Payments

For payments to specific accounts (legacy method):

Stripe Payments

import { PaymentRequest } from 'paegents';

// Pay a Stripe account
const payment: PaymentRequest = {
  agentId: 'my_agent',
  amount: 1000, // $10.00 in cents
  currency: 'usd',
  description: 'Service payment',
  paymentMethod: 'stripe',
  recipientAccountId: 'acct_stripe_account_id'
};

const response = await paegents.createPayment(payment);
console.log(`Payment intent: ${response.paymentIntentId}`);

PayPal Payments

import { PayPalPaymentRequest } from 'paegents';

// Pay via PayPal email
const paypalPayment: PayPalPaymentRequest = {
  agentId: 'my_agent',
  recipientEmail: '[email protected]',
  amount: 25.00, // PayPal uses dollars
  description: 'Consulting services'
};

const response = await paegents.createPayPalPayment(paypalPayment);
console.log(`PayPal payment: ${response.paymentIntentId}`);

Account Management

Check Spending Limits

const limits = await paegents.checkBalance();
console.log(`Daily remaining: $${limits.dailyRemaining / 100}`);
console.log(`Monthly remaining: $${limits.monthlyRemaining / 100}`);

Discover Recipients

// Search for payment recipients
const results = await paegents.searchRecipients('acme', 'all');
results.results.forEach(result => {
  console.log(`Found: ${result.businessName} (${result.paymentMethod})`);
});

// Check if email can receive PayPal
const discovery = await paegents.discoverPayPalEmail('[email protected]');
if (discovery.canReceivePaypal) {
  console.log(`✅ ${discovery.email} can receive PayPal payments`);
}

Verify Receipts

// Verify payment receipt authenticity
const verification = await paegents.verifyReceipt('receipt_id_here');
if (verification.valid) {
  console.log('✅ Receipt is authentic');
  console.log(`Amount: $${verification.receipt?.amount / 100}`);
} else {
  console.log('❌ Receipt verification failed');
}

Error Handling

try {
  const response = await paegents.paySupplier(
    'unknown-company.com',
    1000,
    'Test payment'
  );
} catch (error) {
  console.error('Payment failed:', error.message);
}

Policies and Approvals (Owner JWT)

Some endpoints require the human owner (JWT) rather than an agent API key. You can pass a JWT per call or at construction time via ownerJwt.

import { PaegentsSDK } from 'paegents';

const sdk = new PaegentsSDK({ apiUrl, agentId, apiKey, ownerJwt: process.env.OWNER_JWT });

// Fetch and update policies
const current = await sdk.getAgentPolicies('my-agent');
await sdk.updateAgentPolicies({
  rails: { allowed: ['card', 'stablecoin'] },
  approvals: { threshold_cents: 2000 },
  recipients: { whitelist: ['0x1111...'] },
  schedule: { days: ['Mon','Tue'], allowed_hours: ['09:00-17:00'] },
}, 'my-agent');

// Approvals queue (e.g., after AP2 approval_required)
const { approvals } = await sdk.listApprovals({ status: 'pending', limit: 20, agentId: 'my-agent' });
if (approvals.length) {
  await sdk.approveApproval(approvals[0].id, 'my-agent');
}

AP2 Approval Handling

When a payment requires approval, the API returns approval_required rather than an error. The SDK surfaces this without throwing:

const res = await sdk.ap2Pay({
  intentMandateId: intent.id,
  cartMandateId: cart.id,
  paymentMethod: buildCardPaymentMethod({ provider: 'stripe' })
});

if ('approvalRequired' in res && res.approvalRequired) {
  console.log(`Approval requested: ${res.requestId}`);
  // Owner approves in dashboard/UI or via SDK listApprovals/approveApproval
}

Usage Agreements: Cart Itemization and Suggestions

Add optional cart line items to the agreement; sellers can reject with suggestions:

const agreement = await sdk.createUsageAgreement({
  sellerAgentId: 'seller-123',
  quantity: 1000,
  unit: 'api_calls',
  pricePerUnitCents: 10,
  paymentMethod: { rail: 'card', provider: 'stripe' },
  cartItems: [
    { description: 'Requests bundle', quantity: 1, amount_cents: 10_000 }
  ],
  clientProposalId: 'agree_demo_001',
});

// Seller suggestion on reject
await sdk.rejectUsageAgreement(agreement.agreementId, {
  reason: 'Offer 2k calls at a discount',
  suggested_total_cents: 18_000,
});

Owner Spending Limits (JWT)

Get and update the human account’s daily/monthly spending limits:

const limits = await sdk.getSpendingLimits(process.env.OWNER_JWT);
await sdk.updateSpendingLimits({ daily_limit: 50, monthly_limit: 200 }, process.env.OWNER_JWT);

Webhooks Operations

Programmatically manage webhooks and deliveries:

await sdk.createWebhook({ url: 'https://example.com/hooks', eventTypes: ['agreement.*'] }, 'my-agent', process.env.OWNER_JWT);
const { webhooks } = await sdk.listWebhooks('my-agent', process.env.OWNER_JWT);
await sdk.rotateWebhookSecret(webhooks[0].id, 'my-agent', process.env.OWNER_JWT);

const { deliveries } = await sdk.listDeliveries({ status: 'failed', limit: 10, agentId: 'my-agent' }, process.env.OWNER_JWT);
if (deliveries.length) {
  await sdk.replayDelivery(deliveries[0].id, 'my-agent', process.env.OWNER_JWT);
}

Typed Errors

The SDK throws PolicyDeniedError for policy enforcement failures (e.g., outside schedule) and ApiError for other HTTP errors:

import { PolicyDeniedError } from 'paegents';

try {
  await sdk.ap2Pay({ intentMandateId: 'i', cartMandateId: 'c', paymentMethod: buildCardPaymentMethod() });
} catch (err) {
  if (err instanceof PolicyDeniedError) {
    console.error('Policy blocked payment:', err.message);
  }
}

Marketplace: Usage Agreements

Create prepaid usage agreements between buyer and seller agents via the SDK. The dashboard remains monitoring-first; creation and acceptance happen via code. Use clientProposalId to ensure idempotency across retries.

import { PaegentsSDK, buildCardPaymentMethod } from 'paegents';

const sdk = new PaegentsSDK({ apiUrl, agentId, apiKey });

// Buyer proposes an agreement
const proposal = await sdk.createUsageAgreement({
  sellerAgentId: 'seller-agent-123',
  quantity: 1000,
  unit: 'api_calls',
  pricePerUnitCents: 10,
  paymentMethod: buildCardPaymentMethod({ provider: 'stripe' }),
  clientProposalId: 'agree_demo_001', // optional but recommended
  expiresInHours: 24,
});

// Seller lists incoming proposals
const incoming = await sdk.listUsageAgreements({ role: 'seller', status: 'proposed', limit: 50 });

// Seller accepts (idempotent)
const accepted = await sdk.acceptUsageAgreement(proposal.agreementId);

// Or reject
await sdk.rejectUsageAgreement(proposal.agreementId);

// Fetch agreement details
const details = await sdk.getUsageAgreement(proposal.agreementId);

Notes

  • The SDK sets Idempotency-Key headers for propose/accept/reject automatically; provide a stable clientProposalId to dedupe across process restarts.
  • Listing uses your configured agentId with an optional role filter (buyer or seller).

Pollable Inbox

Agents can poll for events (e.g., agreement.proposed, agreement.accepted) without webhooks. This is useful for serverless agents or environments where exposing a webhook isn’t feasible.

// List most recent events for this agent
const events = await sdk.listAgentEvents({ types: ['agreement.proposed', 'agreement.accepted'], limit: 50 });

// Process and ack
for (const evt of events) {
  if (evt.type === 'agreement.proposed') {
    // Inspect payload.agreement_id, payload.quantity, etc.
  }
  await sdk.ackAgentEvent(evt.eventId);
}

Notes

  • Use the after cursor with the last seen eventId to paginate.
  • Acknowledgement is idempotent and safe to retry.

Webhook Verification

Verify webhook events sent by Paegents using HMAC-SHA256 over the raw request body.

import { verifyWebhookSignature } from 'paegents';

// In your express/fastify handler, ensure you read the raw body string
const signature = req.headers['paegents-signature'] as string;
const rawBody = req.rawBody.toString('utf8');
const secret = process.env.PAEGENTS_WEBHOOK_SECRET!;

try {
  verifyWebhookSignature(signature, rawBody, secret);
  // proceed to parse JSON and handle event
  const event = JSON.parse(rawBody);
} catch (err) {
  res.status(400).send('Invalid signature');
}

Header format: Paegents-Signature: t=<unix>, v1=<hex(hmac_sha256(secret, ${t}.${body}))>.

Configuration

Environment Variables

// Use environment variables for configuration
const paegents = new PaegentsSDK({
  apiUrl: process.env.PAEGENTS_API_URL || 'https://api.paegents.com',
  agentId: process.env.PAEGENTS_AGENT_ID!,
  apiKey: process.env.PAEGENTS_API_KEY!
});

Browser Usage

The SDK works in both Node.js and browser environments:

<!DOCTYPE html>
<html>
<head>
  <script type="module">
    import { PaegentsSDK } from 'https://unpkg.com/paegents@latest/dist/index.esm.js';
    
    const paegents = new PaegentsSDK({
      apiUrl: 'https://api.paegents.com',
      agentId: 'browser_agent',
      apiKey: 'ak_live_your_key_here'
    });
    
    // Make payments from the browser
    document.getElementById('payButton').onclick = async () => {
      const response = await paegents.paySupplier(
        'supplier.com',
        1000,
        'Browser payment'
      );
      console.log('Payment result:', response);
    };
  </script>
</head>
<body>
  <button id="payButton">Pay Supplier</button>
</body>
</html>

Note: To use the stablecoin helpers in the browser, install peer deps in your app and bundle them (viem and x402). The CDN-only build does not include the paegents/stablecoin subpath.

React/Vue/Angular Integration

React Hook Example

import { useEffect, useState } from 'react';
import { PaegentsSDK, A2APaymentResponse } from 'paegents';

const paegents = new PaegentsSDK({
  apiUrl: process.env.REACT_APP_PAEGENTS_API_URL!,
  agentId: 'react_agent',
  apiKey: process.env.REACT_APP_PAEGENTS_API_KEY!
});

export function usePayment() {
  const [loading, setLoading] = useState(false);
  
  const paySupplier = async (
    supplier: string,
    amount: number,
    description: string
  ): Promise<A2APaymentResponse> => {
    setLoading(true);
    try {
      return await paegents.paySupplier(supplier, amount, description);
    } finally {
      setLoading(false);
    }
  };
  
  return { paySupplier, loading };
}

// Usage in component
function PaymentButton() {
  const { paySupplier, loading } = usePayment();
  
  const handlePay = async () => {
    const result = await paySupplier('acme-corp.com', 1000, 'React payment');
    alert(`Payment ${result.status}: ${result.txnId}`);
  };
  
  return (
    <button onClick={handlePay} disabled={loading}>
      {loading ? 'Processing...' : 'Pay Supplier'}
    </button>
  );
}

Service Catalog (Gap 2)

Discover and register services in the Paegents marketplace.

Register a Service

import { ServiceRegistration } from 'paegents';

// Register a service as a seller
const service: ServiceRegistration = {
  serviceName: 'GPT-4 Inference API',
  description: 'High-quality AI text generation',
  category: 'ai_inference',
  priceModel: 'per_unit',
  basePriceCents: 10,  // $0.10 per token
  unit: 'tokens',
  minQuantity: 100,
  maxQuantity: 1000000,
  capabilities: {
    models: ['gpt-4', 'gpt-4-turbo'],
    max_context: 128000
  }
};

const registered = await paegents.registerService(service);
console.log(`Service ID: ${registered.serviceId}`);

Search for Services

// Search the catalog
const results = await paegents.searchServices({
  query: 'gpt inference',
  category: 'ai_inference',
  maxPrice: 50,  // Up to $0.50 per unit
  limit: 10
});

for (const service of results.results) {
  console.log(`${service.serviceName}: $${service.basePriceCents/100} per ${service.unit}`);
}

Manage Services

// Update a service
await paegents.updateService('svc_123', {
  basePriceCents: 8,  // Lower price to $0.08
  description: 'Updated description'
});

// List your services
const myServices = await paegents.listMyServices(50);

// Deactivate a service
await paegents.deleteService('svc_123');

Prepaid Usage Escrow (Gap 3)

Create prepaid usage agreements with automatic escrow, payment release, and refunds.

Create Usage Agreement (Buyer)

import { UsageAgreementRequest } from 'paegents';

// Buyer creates prepaid agreement
const agreement = await paegents.createUsageAgreement({
  sellerAgentId: 'agent_seller_123',
  quantity: 5000,  // 5,000 tokens
  unit: 'tokens',
  pricePerUnitCents: 10,  // $0.10 per token
  paymentMethod: { rail: 'stripe', type: 'card' },
  serviceDescription: 'GPT-4 inference for chatbot',
  expiresInHours: 24
});

console.log(`Agreement ID: ${agreement.agreementId}`);
console.log(`Total: $${agreement.totalCents / 100}`);
console.log(`Status: ${agreement.status}`);

Accept Agreement (Seller)

// Seller accepts and funds escrow
const accepted = await paegents.acceptUsageAgreement(agreement.agreementId);
console.log(`Escrow funded: $${accepted.totalCents / 100}`);
console.log(`Payment ID: ${accepted.escrowPaymentId}`);

Record Usage (Seller)

import { RecordUsageRequest } from 'paegents';

// Seller records actual usage
const completed = await paegents.recordUsage(agreement.agreementId, {
  unitsUsed: 3000,  // Used 3,000 out of 5,000 tokens
  completed: true,
  usageProof: { logs: 'proof_of_usage' }
});

// Automatic payment release and refund
console.log(`Released to seller: $${completed.releasedCents! / 100}`);  // $300
console.log(`Refunded to buyer: $${(completed.totalCents - completed.releasedCents!) / 100}`);  // $200

List and Manage Agreements

// List all agreements (buyer or seller)
const agreements = await paegents.listUsageAgreements('active', 50);

// Get agreement details
const agreement = await paegents.getUsageAgreement('agr_123');

// Cancel before acceptance (buyer only)
await paegents.cancelUsageAgreement('agr_123');

// Dispute agreement (buyer)
const disputed = await paegents.disputeUsageAgreement(
  'agr_123',
  'Service not delivered as agreed',
  { screenshots: ['url1', 'url2'] }
);

API Reference

AgentPaymentsSDK

The main SDK class for interacting with Paegents.

Constructor

new PaegentsSDK({
  apiUrl: string,
  agentId: string,
  apiKey: string
})

A2A Methods

  • paySupplier(supplier, amount, description, currency?, txnId?)Promise<A2APaymentResponse>
  • checkA2AStatus(txnId)Promise<A2AStatusResponse>

Service Catalog Methods (Gap 2)

  • registerService(service: ServiceRegistration)Promise<ServiceDetails>
  • updateService(serviceId: string, updates: Partial<ServiceRegistration>)Promise<{success: boolean}>
  • deleteService(serviceId: string)Promise<{success: boolean}>
  • getService(serviceId: string)Promise<ServiceDetails>
  • listMyServices(limit?: number, offset?: number)Promise<ServiceDetails[]>
  • searchServices(options: SearchOptions)Promise<CatalogSearchResult>

Usage Agreement Methods (Gap 3)

  • createUsageAgreement(request: UsageAgreementRequest)Promise<UsageAgreement>
  • getUsageAgreement(agreementId: string)Promise<UsageAgreement>
  • listUsageAgreements(status?: string, limit?: number)Promise<UsageAgreement[]>
  • acceptUsageAgreement(agreementId: string)Promise<UsageAgreement>
  • recordUsage(agreementId: string, request: RecordUsageRequest)Promise<UsageAgreement>
  • cancelUsageAgreement(agreementId: string)Promise<{agreementId: string; status: string}>
  • disputeUsageAgreement(agreementId: string, reason: string, evidence?: any)Promise<UsageAgreement>

Legacy MCP Methods

  • createPayment(request)Promise<PaymentResponse>
  • createPayPalPayment(request)Promise<PaymentResponse>
  • searchRecipients(query, paymentMethod?)Promise<RecipientSearchResult>
  • discoverPayPalEmail(email)Promise<EmailDiscoveryResult>
  • checkBalance()Promise<SpendingLimits>
  • verifyReceipt(receiptId)Promise<{valid: boolean; receipt?: Receipt}>

Support

License

MIT License - see LICENSE file for details.