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.9.1

Published

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

Readme

Paegents TypeScript SDK

Official TypeScript/JavaScript SDK for integrating Paegents agent payments.

Installation

npm install paegents
# or
yarn add paegents

Stablecoin helpers are opt-in and require compatible peers:

npm install viem x402@^0.1.2

Initialize

import { PaegentsSDK } from 'paegents'

const sdk = new PaegentsSDK({
  apiUrl: process.env.PAEGENTS_API_URL || 'https://api.paegents.com',
  agentId: process.env.PAEGENTS_AGENT_ID!,
  apiKey: process.env.PAEGENTS_API_KEY!,
  ownerJwt: process.env.OWNER_JWT, // optional: owner-only endpoints
})

Agent runtime auth is apiKey + agentId. ownerJwt is only for owner-scoped routes such as policy management, dashboard setup, or owner-managed webhooks.

Security Model

All signing happens locally — private keys never leave your environment. Escrow funds are held by an on-chain smart contract, not by Paegents. Wallet addresses are screened for sanctions compliance before activation.

Keep API keys and private keys in environment variables. Never commit them to source control.

AP2 Quick Start

import { buildCardPaymentMethod } from 'paegents'

const intent = await sdk.createAp2IntentMandate({
  policy: { max_amount: { value: 5000 }, currency: 'usd' },
  metadata: { purpose: 'compute credits' },
})

const cart = await sdk.createAp2CartMandate({
  intentMandateId: intent.id,
  cart: { total: 2500, currency: 'usd' },
})

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

if ('approvalRequired' in payment && payment.approvalRequired) {
  console.log('Approval required:', payment.requestId)
} else {
  console.log('Payment status:', payment.status)
}

Bilateral Escrow Usage Agreements

Bilateral escrow is a two-step process: create the agreement, then activate the on-chain escrow.

Activation is required. Without completing activation, the agreement stays at accepted / activationStatus: 'ready'. The metered proxy will reject requests and no funds are deposited on-chain.

import {
  signBuyerActivationIntent,
  signInfraFeePermit,
  buildPriorAllowanceFundingAuthorization,
} from 'paegents/escrow'

// Step 1: Create the agreement (auto-accepted for self-service)
const agreement = await sdk.createUsageAgreement({
  sellerAgentId: 'seller-agent-123',
  serviceId: 'svc_abc123',
  quantity: 1000,
  unit: 'api_calls',
  pricePerUnitCents: 10,
  buyerWalletAddress: process.env.AGENT_WALLET_ADDRESS!,
})

// Step 2: Fetch the activation package (terms, nonces, funding options, infra fee)
const pkg = await sdk.getActivationPackage(agreement.agreementId)

// Step 3a: Sign the buyer activation intent locally (EIP-712)
const intent = {
  agreementKey: pkg.agreementKey,
  platformAgreementIdHash: pkg.platformAgreementIdHash,
  buyer: pkg.terms.buyer,
  seller: pkg.terms.seller,
  token: pkg.terms.token,
  quantity: BigInt(pkg.terms.quantity),
  pricePerUnit: BigInt(pkg.terms.pricePerUnitAtomic),
  depositAmount: BigInt(pkg.terms.depositAmountAtomic),
  challengeWindowSeconds: BigInt(pkg.terms.challengeWindowSeconds),
  serviceHash: pkg.terms.serviceHash,
  termsHash: pkg.terms.termsHash,
  expiry: pkg.terms.expiry,
  nonce: pkg.nonces.buyerActivationNonce,
  salt: pkg.terms.salt,
}

const sigResult = await signBuyerActivationIntent({
  buyerPrivateKey: process.env.AGENT_PRIVATE_KEY!,
  escrowContractAddress: pkg.funding.spender,
  chainId: 8453, // Base mainnet
  intent,
})

// Step 3b: Build funding authorization (prior USDC allowance)
const funding = buildPriorAllowanceFundingAuthorization({
  amount: BigInt(pkg.terms.depositAmountAtomic),
})

// Step 3c: Sign the separate infra fee permit when the package says a fee is pending
const permitDeadline = Math.floor(Date.now() / 1000) + 600
const buyerUsdcPermitNonce = Number(process.env.BUYER_USDC_PERMIT_NONCE) // read USDC.nonces(buyer)
const infraFeePermit = pkg.infraFee && !pkg.infraFee.waived && pkg.infraFee.status !== 'paid'
  ? await signInfraFeePermit({
      buyerPrivateKey: process.env.AGENT_PRIVATE_KEY!,
      spender: pkg.infraFee.spender,
      value: BigInt(pkg.infraFee.amountAtomic),
      nonce: buyerUsdcPermitNonce,
      deadline: permitDeadline,
      chainId: 8453, // Base mainnet
      usdcAddress: pkg.infraFee.tokenAddress,
    })
  : undefined

// Step 4: Submit activation to the server with both authorizations
await sdk.activateEscrow(agreement.agreementId, {
  buyerIntent: intent,
  buyerSignature: sigResult.signature,
  fundingAuthorization: funding,
  buyerInfraFeePermitSignature: infraFeePermit?.signature,
  buyerInfraFeePermitDeadline: infraFeePermit ? permitDeadline : undefined,
})

// Step 5: Poll until active (typically 10-30 seconds on Base)
let current = await sdk.getUsageAgreement(agreement.agreementId)
while (current.status !== 'active') {
  await new Promise((r) => setTimeout(r, 3000))
  current = await sdk.getUsageAgreement(agreement.agreementId)
}

Optional: Metered Client

const client = sdk.createMeteredClient(agreement.agreementId)

const result = await client.post('/generate', {
  prompt: 'hello world',
  max_tokens: 150,
})

const usage = await client.getUsageStatus()
console.log(usage.units_used, usage.units_remaining)

Policies and Approvals

Owner JWT is required for these endpoints.

const ownerJwt = process.env.OWNER_JWT!

await sdk.updateAgentPolicies(
  {
    approvals: { threshold_cents: 2000 },
    rails: { allowed: ['card', 'stablecoin'] },
    spending: { daily_limit_cents: 10000 },
  },
  'agent-123',
  ownerJwt,
)

const { approvals } = await sdk.listApprovals({ status: 'pending', agentId: 'agent-123' }, ownerJwt)
if (approvals.length > 0) {
  await sdk.approveApproval(approvals[0].id, 'agent-123', ownerJwt)
}

Webhooks

const ownerJwt = process.env.OWNER_JWT!

const webhook = await sdk.createWebhook(
  {
    url: 'https://example.com/webhooks',
    eventTypes: ['payment.*', 'agreement.*'],
  },
  'agent-123',
  ownerJwt,
)

console.log(webhook.id)

Verify Webhook Signatures

import { verifyWebhookSignature } from 'paegents'

verifyWebhookSignature(signatureHeader, rawBody, process.env.PAEGENTS_WEBHOOK_SECRET!)

Error Handling

import { ApiError, PolicyDeniedError } from 'paegents'

try {
  await sdk.ap2Pay({
    intentMandateId: 'intent_123',
    cartMandateId: 'cart_123',
    paymentMethod: buildCardPaymentMethod(),
  })
} catch (err) {
  if (err instanceof PolicyDeniedError) {
    console.error('Policy denied:', err.message)
  } else if (err instanceof ApiError) {
    console.error('API error:', err.status, err.message)
  } else {
    console.error('Unexpected error:', err)
  }
}

Notes

  • Prefer SDK methods over manual HTTP calls.
  • Keep API keys and JWTs in environment variables.
  • Use idempotency keys on critical write operations.
  • Bilateral escrow settlement auto-pays on finalization. Buyer and seller do not need a second payout signature after the agreement is already funded and metered.
  • The platform fee is upfront-only in the current live model. Settlement should not perform a second per-call fee pull.

Support

  • Docs: https://docs.paegents.com
  • API docs: https://docs.paegents.com/api
  • Support: [email protected]

License

MIT