@voidly/pay
Voidly Pay SDK for TypeScript / JavaScript. Agent-to-agent payments that AI agents actually want to use.
npm install @voidly/pay
30-second tour
import { VoidlyPay } from "@voidly/pay";
const pay = await VoidlyPay.create();
console.log("My DID:", pay.did);
await pay.transfer({ to: "did:voidly:provider", amount: 0.5 });
That's it. The SDK signs the envelope, hits https://api.voidly.ai, and settles.
What you can do
| Transfer | One-shot payment | pay.transfer({ to, amount }) |
| Batch | Pay many at once, atomically | pay.batchTransfer([...]) |
| Escrow | Conditional hold | pay.openEscrow({ to, amount, deadlineHours }) |
| Stream | Per-token / per-second metering | pay.openStream({ provider, budget }) |
| Subscription | Recurring charge | pay.subscribe({ provider, amountPerPeriod, periodSeconds }) |
| x402 quote | Server-side paywall | pay.createQuote({ resource, amount }) |
| x402 verify | Server-side verify | pay.verifyPayment({ payment_header }) |
| x402 client | Pay-on-402 wrapper | pay.fetchWithPay(url) |
| Webhooks | Push notifications | pay.subscribeWebhook({ url, events }) |
Server-side x402 paywall (10 lines)
import { VoidlyPay } from "@voidly/pay";
const pay = await VoidlyPay.create();
async function handleRequest(req, res) {
const paymentHeader = req.headers["x-payment"];
if (!paymentHeader) {
const quote = await pay.createQuote({ resource: req.path, amount: 0.01 });
res.status(402).json(quote.payment_required_response);
return;
}
const v = await pay.verifyPayment({ payment_header: paymentHeader });
if (!v.ok) { res.status(402).json({ error: v.reason }); return; }
res.json({ data: "the goods" });
}
Client-side fetch-with-pay
const response = await pay.fetchWithPay("https://api.example.com/expensive-resource", {
method: "POST",
body: JSON.stringify({ query: "hello" }),
}, { maxAmount: 0.05 });
Webhook signature verification
import { verifyWebhookSignature } from "@voidly/pay";
app.post("/voidly-webhook", async (req, res) => {
const ok = await verifyWebhookSignature({
body: req.rawBody,
signatureHeader: req.headers["x-voidly-signature"],
secret: process.env.VOIDLY_WEBHOOK_SECRET!,
});
if (!ok) return res.status(401).end();
});
Configuration
const pay = await VoidlyPay.create({
apiUrl: "https://api.voidly.ai",
secretKey: existingKey,
defaultExpiryMinutes: 30,
});
Storage
Keys auto-persist to:
- Browser:
localStorage["voidly-pay-keypair-v1"]
- Node:
~/.voidly-pay/keypair.json (mode 0600)
- Or pass a custom
KeyStorage implementation
License
MIT