Payment-gate any Vercel AI SDK model call or tool using x402, MPP, or AP2 — paid in USDC on Algorand, VOI, Hedera, or Stellar.
v1.0.0 — TypeScript-native, provider-agnostic. Works with OpenAI, Anthropic, Google, Groq, Ollama, and any @ai-sdk/* provider. Designed for Next.js App Router, Express, and Vercel Edge Functions.
https://github.com/chopmob-cloud/AlgoVoi-Platform-Adapters
Client sends request
|
v
AlgoVoiVercelAI.check() — no payment proof
|
v
HTTP 402 + protocol challenge header
x402: X-PAYMENT-REQUIRED (spec v1, base64 JSON)
MPP: WWW-Authenticate: Payment (IETF draft)
AP2: X-AP2-Cart-Mandate (crypto-algo extension)
|
v
Client pays on-chain (Algorand / VOI / Hedera / Stellar)
Client re-sends with proof in header
|
v
AlgoVoiVercelAI.check() — proof verified directly via public
blockchain indexers (no central API dependency)
|
v
gate.generateText(messages) → model reply string
gate.streamText(messages) → StreamTextResult (pipe to client)
|
v
HTTP 200 — response returned
LLM selects AlgoVoiPaymentTool via function calling
|
v
tool.execute({ query: "...", paymentProof: "<base64>" })
→ challenge JSON if proof absent/invalid
→ resourceFn(query) result if payment verified
| File | Description |
|---|---|
vercel_ai_algovoi.ts |
Adapter — AlgoVoiVercelAI, VercelAIResult |
test_vercel_ai_algovoi.test.ts |
Unit tests (all mocked, no live calls) — 79/79 |
smoke_test_vercel_ai.ts |
Two-phase smoke test (challenge render + real on-chain verification) |
example.ts |
Next.js App Router, streaming, Express, tool, multi-provider examples |
package.json |
Dev dependencies (vitest, tsx, typescript) |
tsconfig.json |
TypeScript compiler config |
README.md |
This file |
| Network key | Asset | Asset ID |
|---|---|---|
algorand-mainnet |
USDC | ASA 31566704 |
voi-mainnet |
aUSDC | ARC200 302190 |
hedera-mainnet |
USDC | HTS 0.0.456858 |
stellar-mainnet |
USDC | Circle |
| Key | Spec |
|---|---|
x402 |
x402 spec v1 — X-PAYMENT-REQUIRED / X-PAYMENT |
mpp |
IETF draft-ryan-httpauth-payment — WWW-Authenticate: Payment |
ap2 |
AP2 v0.1 + AlgoVoi crypto-algo extension |
npm install ai zod @ai-sdk/openaiimport { openai } from "@ai-sdk/openai";
import { AlgoVoiVercelAI } from "./vercel_ai_algovoi";
const gate = new AlgoVoiVercelAI({
algovoiKey: "algv_...",
tenantId: "your-tenant-uuid",
payoutAddress: "YOUR_ALGORAND_ADDRESS",
protocol: "mpp", // "mpp" | "x402" | "ap2"
network: "algorand-mainnet",
amountMicrounits: 10_000, // 0.01 USDC per call
model: openai("gpt-4o"),
});// app/api/chat/route.ts
export async function POST(req: Request) {
return gate.nextHandler(req); // check() → generateText() → 200 or 402
}// app/api/chat/stream/route.ts
export async function POST(req: Request) {
const body = await req.json();
const result = await gate.check(req.headers, body);
if (result.requiresPayment) return result.as402Response();
const stream = gate.streamText(body.messages);
return stream.toDataStreamResponse(); // Vercel AI SDK streaming
}const result = await gate.check(dict(request.headers), body);
if (result.requiresPayment) {
return result.as402Response(); // 402 + challenge header
}
const content = await gate.generateText(body.messages);const premiumTool = gate.asTool(
async (query) => myPremiumHandler(query),
{ toolName: "premium_kb", toolDescription: "Access premium knowledge base." }
);
// Use with any Vercel AI SDK generateText call
const { generateText } = await import("ai");
await generateText({
model: openai("gpt-4o"),
tools: { premium_kb: premiumTool },
messages: [{ role: "user", content: "..." }],
});| Parameter | Type | Default | Description |
|---|---|---|---|
algovoiKey |
string |
required | algv_... API key |
tenantId |
string |
required | AlgoVoi tenant UUID |
payoutAddress |
string |
required | On-chain payout address |
protocol |
string |
"mpp" |
Payment protocol |
network |
string |
"algorand-mainnet" |
Blockchain network |
amountMicrounits |
number |
10000 |
Amount in micro-USDC (10000 = $0.01) |
model |
LanguageModel |
undefined |
Vercel AI SDK model (required for generateText/streamText) |
resourceId |
string |
"ai-function" |
AlgoVoi resource identifier |
realm |
string |
"API Access" |
MPP realm string |
challengeTtl |
number |
300 |
MPP challenge TTL in seconds |
ap2ExpiresSec |
number |
600 |
AP2 CartMandate TTL in seconds |
Verify payment proof from request headers.
const result = await gate.check(req.headers, body);
result.requiresPayment // true → return 402; false → proceed
result.error // human-readable rejection reason
result.challengeHeaders // Record<string, string> with 402 headers
result.as402Response() // Web API Response (status 402)Accepts Headers (Web API) or Record<string, string>. Header names are case-normalised internally.
Run an OpenAI-format message list through the configured model via ai.generateText.
const reply = await gate.generateText([
{ role: "system", content: "Be concise." },
{ role: "user", content: "What is AlgoVoi?" },
]);Throws if no model was set in the constructor.
Stream through the configured model via ai.streamText. Returns the raw result — call .toDataStreamResponse() for Next.js streaming.
const stream = gate.streamText(messages);
return stream.toDataStreamResponse();Throws if no model was set in the constructor.
Return a Vercel AI SDK tool() compatible object. The tool accepts query and paymentProof parameters.
const t = gate.asTool(
(query) => myHandler(query),
{ toolName: "premium_kb", toolDescription: "..." }
);
// Use in generateText({ tools: { premium_kb: t } })One-call Next.js App Router handler: check() → generateText().
export const POST = (req: Request) => gate.nextHandler(req);For streaming, use check() + streamText() manually.
Pass any provider model to the model constructor parameter.
| Provider | Install | Model example |
|---|---|---|
| OpenAI | npm i @ai-sdk/openai |
openai("gpt-4o") |
| Anthropic | npm i @ai-sdk/anthropic |
anthropic("claude-opus-4-5") |
npm i @ai-sdk/google |
google("gemini-2.0-flash") |
|
| Groq | npm i @ai-sdk/groq |
groq("llama-3.1-70b-versatile") |
| Mistral | npm i @ai-sdk/mistral |
mistral("mistral-large-latest") |
| Cohere | npm i @ai-sdk/cohere |
cohere("command-r-plus") |
| Ollama | npm i ollama-ai-provider |
ollama("llama3") |
| Azure OpenAI | npm i @ai-sdk/azure |
azure("gpt-4o") |
| Any OpenAI-compatible | npm i @ai-sdk/openai |
createOpenAI({ baseURL: "..." })("model") |
vercel_ai_algovoi.ts uses node:crypto for MPP HMAC challenge generation. This requires the Node.js runtime in Vercel. For Edge Functions, use x402 or ap2 protocol, or configure runtime = "nodejs" in your route:
export const runtime = "nodejs"; // in Next.js App Router routeAll network verification calls use the standard fetch() API and work on both runtimes.
# Phase 1 — no live API needed:
npx tsx smoke_test_vercel_ai.ts --phase 1
# Phase 2 — live on-chain verification:
ALGOVOI_KEY=algv_... TENANT_ID=... PAYOUT_ADDRESS=... OPENAI_KEY=sk-... \
npx tsx smoke_test_vercel_ai.ts --phase 2- Node.js ≥ 18 (for native
fetchandBuffer) ai≥ 4.0.0 (peer dependency)zod≥ 3.0.0 (peer dependency)- A
@ai-sdk/*provider package forgenerateText/streamText
Licensed under the Business Source License 1.1.