Put a proof-of-work checkpoint in front of any endpoint — no CAPTCHA, no login, no API keys, no third-party service.
A TypeScript SDK for BTX service challenges: your server asks a caller to burn a few seconds of verifiable compute before you do something expensive or abusable. The work is defined and checked by the BTX chain — so there's no centralized issuer to trust, and a proof can't be replayed. Ships a typed RPC client, a solver, and one-line middleware for Express, Fastify, and Hono.
📖 API Reference · 🟢 Stable 1.0.0 (SemVer — breaking changes require 2.0.0) · MIT
You want to slow down bots, scraping, spam, or abuse on an endpoint — but the usual options each cost something:
A BTX service challenge instead makes the caller prove they spent a little real compute. It's cheap to verify, costly to spam at scale, anchored to a public chain, and entirely self-hosted.
Client ── POST /expensive ─────────────────▶ Server
│ no proof yet → issue a challenge
Client ◀── 402 Payment Required ───────────────┤ (challenge rides in the X-BTX-Challenge header)
│
│ solve the matmul work-proof
│ (locally in JS, or — recommended — via a nearby non-mining btxd RPC)
▼
Client ── POST /expensive + proof headers ──▶ Server
│ redeem: verify + consume (anti-replay)
Client ◀── 200 OK — your handler runs ─────────┘
The middleware runs this whole handshake for you. The server never stores issued challenges (the challenge echoes back in a header on retry), so it scales horizontally with no shared state.
import express from 'express';
import { BtxChallengeClient } from '@btx-tools/challenges-sdk';
import { btxAdmission } from '@btx-tools/middleware-express';
const client = new BtxChallengeClient({
rpcUrl: 'http://127.0.0.1:19334', // a dedicated, NON-mining btxd
rpcAuth: { user: 'rpcuser', pass: 'rpcpass' },
});
const app = express();
app.post(
'/v1/generate',
btxAdmission({
client,
purpose: 'ai_inference_gate',
resource: (req) => req.path,
subject: (req) => req.ip ?? 'anon',
}),
(req, res) => res.json({ ok: true }), // only runs after a valid proof is redeemed
);
@btx-tools/mcp-gateway).ℹ️ Server-side, not a browser captcha. See What this SDK is (and isn't) below — the matmul proof is GPU-fast-mining-shaped, so production solving belongs on a server (or a nearby
btxd), not a user's browser tab.
This repo is a monorepo: the core SDK plus three framework adapters (install only the ones you need).
| Package | Description | npm |
|---|---|---|
@btx-tools/challenges-sdk |
Core RPC client + Solver (RPC + WASM + pure-JS modes) + algorithm port | |
@btx-tools/middleware-express |
Express middleware adapter | |
@btx-tools/middleware-fastify |
Fastify plugin adapter | |
@btx-tools/middleware-hono |
Hono middleware adapter (Node + edge: Cloudflare Workers, Deno, Bun) |
| Package | Description | Repo |
|---|---|---|
@btx-tools/mcp-gateway |
MCP server framework that gates every tool invocation behind a BTX service-challenge proof — for agentic AI admission control. Companion to this SDK. | btx-tools/btx-mcp-gateway |
@btx-tools/matmul-wasm |
WASM matmul solver kernel — byte-exact Rust→WASM port of btxd's matmul PoW. Optional dep of the core SDK; powers Solver mode: 'wasm' (~24× pure-JS). Fast server/edge solving without a btxd. |
btx-tools/btx-challenges-wasm |
1.0.0 froze the server-side admission-middleware API. Candidate additive work for 1.x/beyond (none breaking):
@btx-tools/mcp-gateway 1.0.0 — promote the agent-admission gateway to stable alongside this family.middleware-hono.wp-btx-gate) — form/login admission for the largest CMS surface.btx-challenges-py) — server-side parity for Python stacks.A casual sub-second browser captcha remains out of scope until the BTX protocol offers a browser-friendly proof primitive (see USE-CASES.md). The shipped @btx-tools/matmul-wasm kernel speeds up no-node solving ~24× — useful for server/edge and high-friction gates — but doesn't make the live n=512 proof a 1–4 s casual captcha.
# Core only (RPC client + browser-compatible Solver)
npm install @btx-tools/challenges-sdk
# Optional: ~24× faster no-node solving via the WASM kernel (enables Solver mode:'wasm')
npm install @btx-tools/challenges-sdk @btx-tools/matmul-wasm
# With an HTTP framework adapter — pick one
npm install @btx-tools/challenges-sdk @btx-tools/middleware-express express
npm install @btx-tools/challenges-sdk @btx-tools/middleware-fastify fastify
npm install @btx-tools/challenges-sdk @btx-tools/middleware-hono hono
# For agent / MCP admission gating (separate package, see https://github.com/btx-tools/btx-mcp-gateway)
npm install @btx-tools/challenges-sdk @btx-tools/mcp-gateway @modelcontextprotocol/sdk zod
Then see the per-package README:
Read USE-CASES.md before deciding to integrate. This SDK is server-side admission middleware for chain-anchored proof-of-work gating. It is not a casual browser captcha library — even the optional
@btx-tools/matmul-wasmkernel (~24× the pure-JS solver) leaves a floor-difficulty browser solve at ~16 s on an 8-worker pool at the liven=512, not the 1–4 s a click-to-admit widget needs. Usemode: 'rpc'against a dedicated non-mining btxd for production gating, ormode: 'wasm'for fast no-node solving (server/edge, CLI, high-friction gates).
Three runnable end-to-end examples under examples/:
| Path | Stack | What it shows | Status |
|---|---|---|---|
examples/01-basic-roundtrip |
Node + tsx | Minimal issue → Solver.solve → redeem walk-through, both pure-JS and RPC modes |
✅ Adopter-ready (server-side) |
examples/02-express-gate |
Node + Express + tsx | Full Express server with btxAdmission on POST /v1/generate, plus a Node client driving the 402 → solve → 200 → 403-replay flow |
✅ Adopter-ready (server-side) |
examples/03-browser-solver |
Vite + TypeScript + Web Worker | Demonstrates the wire protocol from a browser. NOT a production captcha — see USE-CASES.md. | ⚠️ Reference only |
Each examples/<n>/README.md has install + run instructions.
Heads-up: at floor difficulty, a pure-JS solve takes ~7-60 min wall-clock on an M-series Mac (BigInt-bound). Use
mode: 'rpc'against a dedicated non-mining btxd for sub-second production solves.
pnpm install # at the workspace root
pnpm -r type-check # all packages
pnpm -r build # all packages
pnpm -r test # unit + integration tests
MIT — see LICENSE.