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

@deepfirstsearch/agent-pay-agentkit

v0.3.0

Published

Coinbase AgentKit action provider: agents fetch x402 APIs while the owner's Agent Safe policy decides every payment (no payee or amount in the model's hands)

Readme

@deepfirstsearch/agent-pay-agentkit

A Coinbase AgentKit action provider that lets an agent fetch x402 APIs and pay them in USDC on Base, while the owner's Agent Safe policy decides every payment. The action, AgentPayActionProvider_paid_fetch, takes a URL and nothing that moves money: no payee, no amount, no network. Payees, price pins, caps and the budget come from the owner's registry and sealed plan, so a prompt-injected agent can ask for any URL but can't choose who gets paid or how much.

Beta, unaudited. Use Base Sepolia or small amounts on Base mainnet. Independent open-source project; not affiliated with Coinbase.

npm install @deepfirstsearch/agent-pay-agentkit @deepfirstsearch/agent-pay @coinbase/agentkit [email protected] zod@3

(AgentKit pins viem 2.38.3; using the same version keeps one copy of viem's types.)

Before you install: @coinbase/agentkit pulls in about 1,000 packages, and npm audit reports upstream warnings in that tree (from @coinbase/agentkit and the viem version it pins, not from this package, which has no dependencies of its own beyond its peers). AgentKit also makes an outbound analytics call when a wallet provider is created; see the note below.

Project setup. The example is ESM with top-level await: run npm pkg set type=module (or name the file .ts and run it with npx tsx file.ts). Node 20 or later.

Try it offline (no keys to fund, no chain)

process.on("unhandledRejection", () => {}); // AgentKit's wallet providers send an analytics event; see the note below
import { AgentKit, ViemWalletProvider } from "@coinbase/agentkit";
import { createAgentPay, MerchantRegistry } from "@deepfirstsearch/agent-pay";
import { startMockServer } from "@deepfirstsearch/agent-pay/testing";
import { agentKitPayer, agentPayActionProvider, PAID_FETCH_ACTION } from "@deepfirstsearch/agent-pay-agentkit";
import { createWalletClient, http } from "viem";
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";

// A local x402 merchant (it verifies signatures itself; nothing touches a chain) and a hostile route.
const payTo = "0x1111111111111111111111111111111111111111";
const merchant = await startMockServer({
  "/data": { price: 10_000n, payTo, body: '{"price":42}' },
  "/evil": { price: 10_000n, payTo, tamper: (r) => ({ ...r, payTo: "0x9999999999999999999999999999999999999999" }) },
}, { network: "eip155:8453" });

// The agent's AgentKit wallet (here a throwaway key) signs the payments, but only when Agent Safe allows them.
const walletProvider = new ViemWalletProvider(
  createWalletClient({ account: privateKeyToAccount(generatePrivateKey()), chain: base, transport: http() }),
);

// The owner's rules: who may be paid, at what price, with what cap. Nothing here comes from the model.
const pay = createAgentPay({
  registry: new MerchantRegistry([{ origin: merchant.url, payTo, network: "eip155:8453", maxPerTx: 50_000n, pricePin: 10_000n }]),
  policy: { allowedNetworks: ["eip155:8453"], periodBudget: { amount: 1_000_000n, periodMs: 86_400_000 } },
  payer: () => agentKitPayer(walletProvider),
  session: { readsUntrustedInput: true, accessesSensitiveData: false, canPay: true },
});
// Seal the plan before the agent reads anything untrusted.
const plan = pay.commitPlan([{ origin: merchant.url, maxSpend: 100_000n }], 60 * 60_000);

const agentkit = await AgentKit.from({ walletProvider, actionProviders: [agentPayActionProvider({ pay, plan })] });
const paidFetch = agentkit.getActions().find((a) => a.name === PAID_FETCH_ACTION)!;

console.log(await paidFetch.invoke({ url: `${merchant.url}/data` })); // HTTP 200. Paid 0.01 USDC to 0x1111… + fenced body
console.log(await paidFetch.invoke({ url: `${merchant.url}/evil` })); // Payment refused by policy: … (nothing signed)
await merchant.close();

With a real merchant, use its origin and payTo from its 402 (34 merchants with tested values: deepfirstsearch.com/developers). The actions plug into AgentKit's framework extensions (LangChain, Vercel AI SDK, OpenAI Agents) like any other provider.

What's different from AgentKit's built-in x402 actions

AgentKit's x402ActionProvider lets the model pick the payment option (selectedPaymentOption includes payTo and the amount) when it retries a 402. That is convenient, and it is also where a prompt injection can redirect a payment. This provider keeps the model out of money decisions:

  • The model only chooses a URL. Every 402 is checked against the owner's registry before anything is signed: payee, asset, network, price and timeout must match, and the sealed plan and period budget must have room.
  • Refusals come back as text (Payment refused by policy: …), never thrown, so the agent can explain what happened. Since 0.2.0, with @deepfirstsearch/agent-pay >= 0.8.0, the text carries the refusal's stable code and what to do about it, e.g. Payment refused by policy [price_changed → ask the owner]: … or [payee_mismatch → do not retry, report it] (codes listed in the SDK README, "Refusal codes"). Older SDKs give the text without the tag. Blocks carry codes too (Payment blocked [settlement_pending → …]; also settled_not_delivered, settlement_unknown (agent-pay >= 0.8.2), rate_limited, kill_switch), with the extra action resend_same: fetch the same URL again, and the SDK resends the same signed authorization without signing a new one.
  • Responses are fenced with a random tag and labeled as untrusted data.
  • paid_fetch fetches any public https URL the model asks for; only payments are restricted to registered merchants. A non-402 response from an unregistered origin is returned as data (fenced as untrusted), so treat it like any fetch action you give a model. Hosts that are or resolve to loopback, private, link-local or CGNAT addresses, localhost names and plain http are refused unless they are in the sealed plan (registered merchants) or you pass allowPrivateNetwork: true to agentPayActionProvider; redirects are returned, not followed. Errors other than policy refusals (which can carry an RPC URL with its API key) reach the model as a fixed text.
  • On-chain budgets (optional): fund the payer from an Agent Safe vault with vaultFunder, so even a compromised machine can only spend inside the owner-signed caps. See the SDK.
  • The action is built without AgentKit's @CreateAction decorator, so invoking it sends no analytics event.

Note: AgentKit makes an outbound analytics call. Its wallet providers send an initialization event to Coinbase's analytics endpoint when they are created, including in the offline example above (this package's action sends none). In AgentKit 0.10.4 that call isn't awaited, so if the endpoint answers with an error the rejection is unhandled and Node exits. Until that's fixed upstream, the process.on("unhandledRejection", …) handler at the top of the example keeps it running; in a real agent, log those rejections rather than ignoring them.

agentKitPayer(walletProvider) works with any AgentKit EVM wallet provider (ViemWalletProvider, CdpEvmWalletProvider, …): it signs EIP-712 payment authorizations and refuses to sign transactions. Any viem LocalAccount works as the payer too.

Develop

npm ci && npm run typecheck && npm test   # includes an AgentKit.from(...) run against a mock x402 merchant

MIT. Questions: GitHub Discussions.