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

abapay-sdk

v0.5.1

Published

Pay real-world bills (airtime, data, electricity, cable) from an agent's own Celo wallet — zero-setup x402, or a linked-wallet client for the fuller MCP tool catalog.

Readme

abapay-sdk

Pay real-world bills — airtime, mobile data, electricity, cable TV — from an agent's own Celo wallet. Two ways in, matching agents.abapays.com:

  • payBillViaX402 — zero setup. No account, no API key, no PIN, no visit to abapays.com. Your agent's wallet signs one EIP-3009 authorization and the bill is paid.
  • AbaPayAgent — a linked-wallet client for the fuller MCP tool catalog (balances, history, schedules, batch payments). One on-chain signature to link, then an API key + PIN per payment.

Full protocol details: docs/AGENT_INTEGRATION.md. Celo mainnet only in this version.

Install

npm install abapay-sdk viem

viem is a peer dependency — this package signs through whatever Account/WalletClient your own viem install already gives you, rather than bundling a second copy.

Quickstart on Celo (about 5 minutes)

  1. A wallet. Any EVM key works; for a fresh one: node -e "console.log(require('viem/accounts').generatePrivateKey())"
  2. Fund it on Celo with about $1 of USDC, USD₮ or USA₮. You don't need CELO: with x402 the facilitator submits the transfer and pays the gas.
  3. Pay ₦100 of MTN airtime (well under $1, fees included):
npm install abapay-sdk viem
PRIVATE_KEY=0x... npx abapay pay --service AIRTIME --provider mtn --to 08012345678 --amount 100

The output carries the Celo transaction hash: look it up on celoscan.io to see the payment. The same thing in code is below.

For a complete agent built on this package (spending cap, approval prompt, plain-English requests), see abapay-reference-agent.

Zero setup: pay a bill via x402

import { privateKeyToAccount } from "viem/accounts";
import { payBillViaX402 } from "abapay-sdk";

const key = process.env.PRIVATE_KEY;
if (!/^0x[0-9a-fA-F]{64}$/.test(key ?? "")) throw new Error("PRIVATE_KEY must be 0x + 64 hex characters");
const account = privateKeyToAccount(key as `0x${string}`);

const result = await payBillViaX402({
  signer: account,
  bill: {
    serviceID: "mtn",
    serviceCategory: "AIRTIME",
    network: "MTN",
    billersCode: "08012345678",
    nairaAmount: 1000,
    token: "USDT", // or "USDC", "USAT" (USA₮)
  },
});

console.log(result.status, result.tx_hash);

That's the whole integration. account never touches abapays.com beyond this one HTTP call — no account creation, no API key, no PIN. This is the flow described at agents.abapays.com/#x402: the agent holds a Celo wallet, calls the endpoint, gets a 402 Payment Required, signs the exact amount named in the challenge, and retries. payBillViaX402 does the challenge/sign/retry for you; nothing about the wire format is hidden — read src/x402.ts if you want to see or reimplement it in another language.

Linked wallet: the fuller tool catalog

import { privateKeyToAccount } from "viem/accounts";
import { AbaPayAgent } from "abapay-sdk";

const key = process.env.PRIVATE_KEY;
if (!/^0x[0-9a-fA-F]{64}$/.test(key ?? "")) throw new Error("PRIVATE_KEY must be 0x + 64 hex characters");
const account = privateKeyToAccount(key as `0x${string}`);

// One-time: prove wallet ownership, mint an Agent Hub api_key. Save agent.apiKey somewhere —
// there is no recovery flow other than linking again.
const agent = await AbaPayAgent.link({ signer: account, pin: "123456" });

// Elsewhere, an on-chain approve() + setSpendingAllowance() grants AbaPay a bounded, revocable
// allowance — see examples/agent-quickstart.mjs in the main repo for the two calls. Nothing in
// this SDK can raise that allowance on your behalf; only your own wallet can.

console.log(await agent.checkBalance());

await agent.payBill({
  pin: "123456",
  service: "AIRTIME",
  provider: "mtn",
  account_number: "08012345678",
  amount_ngn: 1000,
  idempotency_key: crypto.randomUUID(), // a retry with the same key never pays twice
});

Reattach to a previously-minted key without signing again:

const agent = AbaPayAgent.fromApiKey(savedApiKey, walletAddress);

Which one do I want?

| | payBillViaX402 | AbaPayAgent | | ------------------------ | ---------------------------------- | --------------------------------------- | | Setup | None | One signed message, once | | Credential per call | None — just the signature | api_key + PIN, every payment | | Tool catalog | Pay a bill, that's it | Balance, history, schedules, batch, more | | Best for | An external agent that already has a wallet and wants to pay, now | An agent that will call AbaPay repeatedly and wants the full catalog |

Self Agent ID

If your agent is registered at app.ai.self.xyz (the SelfAgentRegistry on Celo, which ties the agent key to a verified human), pass that key and every request is signed with it:

const selfAgent = privateKeyToAccount(process.env.SELF_AGENT_KEY as `0x${string}`);

const result = await payBillViaX402({ signer: account, selfAgent, bill: { /* … */ } });
console.log(result.self_agent); // { status: "verified", agent_id: "…" }

const signedAgent = agent.withSelfAgent(selfAgent); // MCP calls, signed

The CLI reads SELF_AGENT_KEY. The agent key need not be the paying wallet. Each request is signed afresh (AbaPay refuses a repeated or stale signature with 401 SELF_AGENT_INVALID); an agent that is expired, revoked or not registered still pays, just unverified. For other languages, selfSigningDigest and selfAgentHeaders are exported. Protocol details: docs/gitbook/self-agent-id.md.

Errors

Every failure — a bad request, a rejected signature, a settlement AbaPay itself reports as unsuccessful — throws AbaPayError (message, and response carrying whatever AbaPay's API returned, when there was a response to carry). Full error code reference: agents.abapays.com/errors.

CLI

The same two paths, from a terminal — no code required:

npm install -g abapay-sdk

PRIVATE_KEY=0x... abapay pay --service AIRTIME --provider mtn --to 08012345678 --amount 1000
PRIVATE_KEY=0x... abapay link --pin 123456
abapay balance --api-key aba_mcp_xxxxx
abapay history --api-key aba_mcp_xxxxx --limit 5

abapay help prints the full command reference. PRIVATE_KEY never leaves your machine — every command signs locally via viem, the same as the library calls above.

License

MIT