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

payagent

v2.10.0

Published

Let AI agents pay for APIs. The ArisPay SDK + CLI for x402 payments with delegated-custody wallets — no private keys in your process.

Downloads

2,537

Readme

payagent

Let AI agents pay for APIs. The ArisPay SDK + CLI for x402 USDC payments — no private keys ever live in your process.

payagent provisions a delegated-custody agent wallet through ArisPay: Coinbase CDP holds the signing key, ArisPay enforces per-transaction, daily, monthly, and allowed-domain limits server-side, and signs on your agent's behalf when it hits an HTTP 402.

Install

npm install payagent

Requires Node.js >= 18.

Quick start (CLI)

One command. No dashboard trip, no separate init, no separate agent create, no manual funding step.

npx payagent pay https://api.example.com/premium

On a cold machine, pay self-bootstraps in order:

  1. Auth — prints a verification URL + code (OAuth device-code flow). Open it, approve, the CLI picks up your API key.
  2. Agent — auto-creates a local agent named default with conservative defaults ($5/tx, $20/day, $100/month, Base mainnet, URL hostname allowlisted). Persisted to ~/.payagent/config.json, so subsequent runs skip this step.
  3. Funding — if the agent has 0 USDC, prints a Coinbase Onramp link (or the raw wallet address if onramp isn't configured on the deployment) and polls until funds land.
  4. Pay — retries the URL with a signed X-PAYMENT header.

Progress goes to stderr; the HTTP response body is written to stdout, so you can pipe it:

npx payagent pay https://api.example.com/premium | jq .

Overrides (all optional) let you tune the first-run defaults:

npx payagent pay <url> \
  --agent hermes \                        # name the agent (defaults to `default`)
  --per-tx 0.50 --daily 10 --monthly 100 \# dollars; cents stored server-side
  --network base \                        # base | base-sepolia | ethereum | polygon
  --domains api.example.com,api.example.net \
  --method POST --body '{"foo":"bar"}' \
  --amount 25                             # preset Coinbase Onramp amount (USD)

For advanced setups you can still run the gates manually:

npx payagent init                                     # OAuth device-code sign-in
npx payagent agent create --name hermes \
  --per-tx 0.50 --daily 10 --monthly 100              # amounts in dollars
npx payagent agent fund hermes --hosted 25            # Coinbase Onramp link for $25

The CLI and the @arispay/payagent-mcp server share the same ~/.payagent/config.json, so an agent created on the command line is immediately available to Claude Desktop or any other MCP host.

Quick start (programmatic)

import { launchAgent } from 'payagent';

const hermes = await launchAgent({
  name: 'hermes',
  limits: { perTx: 50, daily: 1000, monthly: 10000 }, // cents
  allowedDomains: ['api.example.com'],
});

console.log(`Fund this wallet with USDC on Base: ${hermes.walletAddress}`);
await hermes.waitUntilFunded();

const res = await hermes.fetch('https://api.example.com/premium');
const data = await res.json();

For finer-grained control, the low-level DelegationClient + payFetchDelegated primitives are still exported and used by launchAgent under the hood:

import { DelegationClient, payFetchDelegated } from 'payagent';

const client = new DelegationClient('https://api.arispay.app', process.env.ARISPAY_API_KEY);
const agent = await client.createX402Agent({
  name: 'my-agent',
  maxPerTx: 100,
  maxDaily: 1000,
  maxMonthly: 10000,
  allowedDomains: ['api.example.com'],
});
await client.pollUntilFunded(agent.agentId);

const fetch402 = payFetchDelegated({
  arispayUrl: 'https://api.arispay.app',
  apiKey: agent.apiKey,
});
const res = await fetch402('https://api.example.com/premium');

CLI reference

| Command | Purpose | |---|---| | payagent init | Browser-based OAuth device-code flow. Saves the developer API key to ~/.payagent/config.json (mode 0600). | | payagent status / payagent doctor | Show local readiness: API target, key validity, cached agents, balances, and next command. | | payagent whoami | Show the current developer key prefix, base URL, and config path. | | payagent logout | Clear the developer key. Local agent records are kept. | | payagent agent create --name N --per-tx N --daily N --monthly N [--domains a,b] [--network base|base-sepolia|ethereum|polygon] | Create an x402 agent, cache its credentials locally, and print a hosted funding link when available. | | payagent agent fund NAME | Print the funding address, render a QR, and poll until the wallet first receives USDC. | | payagent agent balance NAME | Show current balance + fundedAt. | | payagent agent list | List locally-cached agents. | | payagent agent remove NAME | Drop an agent from the local cache (the server-side agent remains). | | payagent pay URL [--agent N] [--method GET/POST/…] [--body STR] | Make a single paid request through payFetchDelegated. |

Amounts on the CLI are in dollars (5, 5.00, or "$5.00" all mean 500 cents). Internally everything is integer cents, matching the ArisPay API.

Env overrides respected everywhere: ARISPAY_API_KEY, ARISPAY_URL, PAYAGENT_CONFIG_DIR.

Hosted top-up (Coinbase Onramp)

For end-user-friendly funding — no crypto wallet required — ArisPay can return a hosted Coinbase Onramp URL instead of a raw wallet address. The user opens the URL, pays with card or Apple Pay, and Coinbase deposits USDC straight into the agent's CDP wallet.

import { launchAgent, HostedTopupNotConfiguredError } from 'payagent';

const hermes = await launchAgent({
  name: 'hermes',
  limits: { perTx: 50, daily: 1000, monthly: 10000 },
});

try {
  const link = await hermes.getFundingLink({ amount: 50 });
  console.log(`Pay here: ${link.fundingUrl}`);
  // Expires at link.expiresAt, valid for ~2 hours.
  await hermes.waitUntilFunded();
} catch (err) {
  if (err instanceof HostedTopupNotConfiguredError) {
    // Deployment hasn't set ARISPAY_ONRAMP_PROVIDER — fall back to
    // the plain wallet address.
    console.log(`Send USDC on base to ${hermes.walletAddress}`);
    await hermes.waitUntilFunded();
  } else {
    throw err;
  }
}

Or via the CLI:

npx payagent agent fund hermes --hosted 50

Requires ARISPAY_ONRAMP_PROVIDER=coinbase + COINBASE_ONRAMP_APP_ID on the API deployment. Without them, the --hosted flag falls back to the manual path with a clear message.

How x402 works

The x402 protocol uses HTTP status code 402 for machine-to-machine API payments:

  1. Server returns 402 Payment Required with payment requirements (chain, amount, recipient).
  2. payagent asks ArisPay to sign an EIP-3009 transferWithAuthorization — a gasless USDC transfer authorization.
  3. ArisPay validates the request against your delegation limits (maxPerTx, maxDaily, maxMonthly, allowedDomains), then signs via the CDP-managed wallet.
  4. payagent retries the request with the signed payment in the X-PAYMENT header.
  5. Server's facilitator submits the authorization on-chain and returns the API response.

Key properties:

  • No private keys in your agent — the signing key lives in Coinbase CDP, never in your process.
  • Server-enforced limits — ArisPay rejects requests that breach your delegation before signing.
  • No gas fees for agents — the seller's facilitator sponsors gas.
  • USDC stablecoins — amounts are in dollars, no price volatility.

API

DelegationClient — provision and monitor agents

const client = new DelegationClient('https://api.arispay.app', process.env.ARISPAY_KEY);

const agent = await client.createX402Agent({
  name: 'hermes-prod',
  agentType: 'hermes',
  maxPerTx: 100,       // cents
  maxDaily: 1000,
  maxMonthly: 10000,
  allowedDomains: ['api.example.com'],
  network: 'base',     // default
});
// agent.agentId, agent.walletAddress, agent.apiKey (returned ONCE)

// Wait for the wallet to be funded with USDC.
await client.pollUntilFunded(agent.agentId);

// Or check manually:
const balance = await client.getBalance(agent.agentId);
// { walletAddress, usdcBalance, network, fundedAt }

Supported network values: base (default, mainnet), base-sepolia, ethereum, polygon.

The apiKey returned by createX402Agent is the credential for this agent only — ArisPay stores only its SHA-256 hash and cannot recover it. Store it securely.

payFetchDelegated(config) — drop-in fetch

const fetch402 = payFetchDelegated({
  arispayUrl: 'https://api.arispay.app',
  apiKey: agent.apiKey,
});
const res = await fetch402('https://api.example.com/data');

Works like native fetch. On 402, payagent asks ArisPay to sign via CDP, then retries. If ArisPay rejects (limit breach, disallowed domain, etc.), throws PaymentRejectedError.

getUSDCBalance(address, chain?, rpcUrl?) — direct on-chain read

import { getUSDCBalance, formatUSDC } from 'payagent';

const raw = await getUSDCBalance(agent.walletAddress);           // default chain: 'base'
const raw2 = await getUSDCBalance(agent.walletAddress, 'base');
console.log(formatUSDC(raw), 'USDC');

Utility that reads USDC balance directly from any EVM RPC — handy for sanity-checking wallet state independent of ArisPay's balance endpoint.

Supported chains

| Chain | Network ID | Notes | |-------|-----------|-------| | Base | eip155:8453 | Default — mainnet, lowest fees | | Base Sepolia | eip155:84532 | Testnet | | Ethereum | eip155:1 | Mainnet | | Polygon | eip155:137 | Mainnet |

Errors

import {
  PaymentRejectedError,     // ArisPay denied signing, or server returned 402 after payment
  InvalidRequirementsError, // Could not parse the 402 response
  PayAgentError,            // Base class
} from 'payagent';

Framework integrations

Vercel AI SDK

import { createPayAgentTool } from 'payagent/vercel';
import { generateText } from 'ai';

const payTool = createPayAgentTool({
  arispayUrl: 'https://api.arispay.app',
  apiKey: process.env.ARISPAY_AGENT_KEY,
});

const { text } = await generateText({
  model: yourModel,
  tools: { pay_api: payTool },
  prompt: 'Get the premium forecast from https://weather-api.example.com/forecast',
});

Requires peer dependencies: ai, zod.

LangChain

import { createPayAgentTool } from 'payagent/langchain';

const payTool = createPayAgentTool({
  arispayUrl: 'https://api.arispay.app',
  apiKey: process.env.ARISPAY_AGENT_KEY,
});

Requires peer dependency: @langchain/core.

MCP server

Use @arispay/payagent-mcp to add payment capabilities to Claude Desktop, Cursor, or any MCP client.

Migrating from 1.x

v2 removes the self-custody path (payFetch, PayAgent, raw private-key signing). ArisPay's product is delegated-custody only — keys live in Coinbase CDP with server-enforced limits.

Migration:

  • Replace payFetch({ privateKey }) with payFetchDelegated({ arispayUrl, apiKey }).
  • Replace new PayAgent({ privateKey, budget, maxPerRequest }) with DelegationClient.createX402Agent({ maxPerTx, maxDaily, maxMonthly, ... }) to provision, then payFetchDelegated to transact.
  • BudgetExceededError, UnsupportedChainError, and DomainNotAllowedError are gone — their equivalents are now server-side rejections surfaced as PaymentRejectedError.

License

MIT