@krewe/x402-client
v0.1.0
Published
x402 payment client for the krewe decentralized inference network on Base. Pay per inference call in USDC via EIP-3009 — no API keys, no signup.
Maintainers
Readme
@krewe/x402-client
Pay-per-call client for the krewe decentralized inference network on Base. Settles each call in USDC via EIP-3009 transferWithAuthorization — no API keys, no signup, no rate-limit dashboards. If your wallet has USDC on Base, you can call the network.
The network runs 3-of-3 fan-out with 2-of-3 byte-equal consensus on every job — your inference call is independently verified before you get a response. See krewe-AI/krewe for the full protocol.
Install
pnpm add @krewe/x402-client viem
# or: npm i @krewe/x402-client viemQuickstart
import { createX402Client } from "@krewe/x402-client";
import { privateKeyToAccount } from "viem/accounts";
const client = createX402Client({
signer: privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`),
});
const result = await client.predict({
kind: "text.structure",
payload: {
text: "Email [email protected] about the meeting on 2026-06-12.",
},
});
console.log(result.output);
// → { emails: ["[email protected]"], urls: [], dates: ["2026-06-12"], numbers: [] }
console.log(`Paid: ${result.paymentTxHash} (replicas=${result.replicas})`);Supported job kinds
| kind | Price (USDC) | Description |
|-------------------|--------------|------------------------------------------------------|
| text.structure | $0.005 | Extract emails, URLs, dates, numbers, phones |
| text.embed | $0.010 | Sentence embeddings (Xenova/all-MiniLM-L6-v2) |
| web.scrape | $0.020 | Fetch + clean a small URL payload |
| text.complete | $0.050 | Quantized SLM completion (Xenova/Qwen2.5-0.5B) |
How it works
client.predict(req)POSTs/v2/predictwithout payment → orchestrator returnsHTTP 402with an x402 challenge (recipient, USDC amount, nonce, 5-minute deadline).- SDK signs the challenge as an EIP-3009
TransferWithAuthorizationtyped-data message using your wallet. - SDK re-POSTs with
X-PAYMENT: base64(json({challenge, from, v, r, s})). - Orchestrator verifies the signature off-chain, submits
transferWithAuthorizationon-chain, runs the inference job across 3 miners, returns the consensus result with the on-chainpaymentTxHash.
The orchestrator pays the gas (~$0.001 on Base) and recovers it from the payment itself.
Advanced: two-step flow
If you want to show a user the price before signing:
const challenge = await client.getChallenge({ kind: "text.complete", payload: { prompt: "…" } });
console.log(challenge.description); // "$0.050000 for text.complete"
// (display to user, get confirmation, …)
const payment = await client.signChallenge(challenge);
const result = await client.submitWithPayment({ kind: "text.complete", payload: {...} }, payment);Spending cap
By default the SDK rejects any quoted price > $0.10 per call. Override with maxPricePerCallUsdc:
const client = createX402Client({
signer,
maxPricePerCallUsdc: 1_000_000n, // $1.00 per call
});Browser usage
The SDK uses fetch and Buffer only — works in Node ≥ 18, Bun, Deno, Cloudflare Workers, Vercel Edge, and browsers (with a wallet-injected signer like wagmi's useWalletClient).
import { createWalletClient, custom } from "viem";
import { base } from "viem/chains";
const wallet = createWalletClient({ chain: base, transport: custom(window.ethereum) });
const [address] = await wallet.getAddresses();
const client = createX402Client({
signer: {
address,
signTypedData: (params) => wallet.signTypedData({ account: address, ...params }),
},
});License
MIT. See LICENSE.
