@btx-tools/challenges-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 visitor-code
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # @btx/challenges-sdk
2
+
3
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+
5
+ TypeScript SDK for **BTX service challenges** — chain-anchored proof-of-work admission control for APIs, agent gateways, and form submissions.
6
+
7
+ > ⚠️ **Status**: 0.0.1 pre-release. Day 2.5 shipped: RPC + pure-JS solver, cross-validated byte-equal against btxd's own pinned test vectors. See [CHANGELOG](https://github.com/btx-tools/btx-challenges-sdk/blob/main/CHANGELOG.md).
8
+
9
+ ## What is this?
10
+
11
+ [BTX](https://btx.dev) is a post-quantum settlement chain that exposes a unique admission-control primitive: domain-bound MatMul work proofs that you can use to gate any HTTP endpoint, MCP tool call, or anonymous form submission.
12
+
13
+ Issue a challenge → client solves a ~1–4 second matrix-multiplication puzzle → server redeems the proof atomically (no replays). The work is anchored to the BTX chain — tamper-proof, no centralized issuer needed.
14
+
15
+ **Use cases**:
16
+
17
+ - 🤖 Gate AI inference APIs without a CAPTCHA
18
+ - 🛡️ Per-tool-call proof-of-work for MCP / agent gateways
19
+ - 📝 Anonymous form submission rate-limiting
20
+ - 🚦 Replace hCaptcha / reCAPTCHA with chain-anchored proof
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install @btx/challenges-sdk
26
+ # or
27
+ pnpm add @btx/challenges-sdk
28
+ ```
29
+
30
+ ## Quickstart
31
+
32
+ ```typescript
33
+ import { BtxChallengeClient } from '@btx/challenges-sdk';
34
+
35
+ const client = new BtxChallengeClient({
36
+ rpcUrl: 'http://127.0.0.1:19332',
37
+ rpcAuth: { user: 'rpcuser', pass: 'rpcpass' },
38
+ });
39
+
40
+ // Server: issue a challenge bound to the requested resource
41
+ const challenge = await client.issue({
42
+ purpose: 'ai_inference_gate',
43
+ resource: 'model:gpt-x|route:/v1/generate',
44
+ subject: 'tenant:abc123',
45
+ target_solve_time_s: 2,
46
+ expires_in_s: 60,
47
+ });
48
+
49
+ // ... ship challenge to client; client solves locally and returns (nonce, digest) ...
50
+
51
+ // Server: verify-and-consume atomically (anti-replay admission)
52
+ const result = await client.redeem(challenge, nonce64_hex, digest_hex);
53
+
54
+ if (result.valid && result.reason === 'ok') {
55
+ // Run the expensive action
56
+ }
57
+ ```
58
+
59
+ ## Security
60
+
61
+ ### HTTPS / TLS
62
+
63
+ Basic-auth credentials are sent on every RPC call. **Use HTTPS** (or a localhost-only deployment) when btxd's RPC port is exposed beyond `127.0.0.1`.
64
+
65
+ Recommended terminations:
66
+
67
+ - **stunnel**, **nginx**, or **Caddy** in front of btxd
68
+ - **Cloudflare Tunnel** for remote operator access
69
+ - Never expose btxd's RPC port (default `19332`) directly to the public internet
70
+
71
+ The SDK does NOT enforce HTTPS — that's a deployment concern. If you set `rpcUrl: 'http://example.com:19332'` from a production service, the SDK will happily transmit your credentials in plaintext.
72
+
73
+ ### Error handling
74
+
75
+ ```typescript
76
+ import {
77
+ BtxError, // base class — all SDK errors extend this
78
+ BtxRpcError, // btxd returned a JSON-RPC error envelope
79
+ BtxHttpError, // non-2xx HTTP status
80
+ BtxParseError, // 2xx but body wasn't valid JSON
81
+ BtxTimeoutError, // request exceeded timeoutMs
82
+ BtxNetworkError, // DNS/TCP/TLS-level failure
83
+ } from '@btx/challenges-sdk';
84
+
85
+ try {
86
+ await client.redeem(challenge, nonce, digest);
87
+ } catch (err) {
88
+ if (err instanceof BtxRpcError && err.code === -8) {
89
+ // btxd rejected the request shape
90
+ } else if (err instanceof BtxTimeoutError) {
91
+ // user took too long to solve
92
+ } else if (err instanceof BtxError) {
93
+ // any other SDK-originated error
94
+ }
95
+ }
96
+ ```
97
+
98
+ Error response bodies are scanned and `Authorization: Basic <token>` patterns are redacted before storage — safe to log.
99
+
100
+ ## API
101
+
102
+ ### `BtxChallengeClient`
103
+
104
+ | Method | RPC | Description |
105
+ |---|---|---|
106
+ | `issue(params)` | `getmatmulservicechallenge` | Issue a fresh challenge bound to (purpose, resource, subject). |
107
+ | `verify(...)` | `verifymatmulserviceproof` | Stateless verify. Does NOT consume the challenge. |
108
+ | `redeem(...)` | `redeemmatmulserviceproof` | **Atomic verify + consume**. Use for admission control. |
109
+ | `verifyBatch(entries)` | `verifymatmulserviceproofs` | Batch (1–256) verify. No consumption. |
110
+ | `redeemBatch(entries)` | `redeemmatmulserviceproofs` | Batch verify + consume, sequential. |
111
+ | `solve(challenge)` | `solvematmulservicechallenge` | Server-side solver (fixtures + tests). |
112
+ | `call(method, params)` | (any) | Low-level escape hatch. |
113
+
114
+ ### `Solver`
115
+
116
+ Three modes:
117
+
118
+ - **`'rpc'`** — delegates to btxd's `solvematmulservicechallenge` RPC. Server-side / Node only. Fast (sub-second to a few seconds) on a dedicated non-mining node — see the deployment note below.
119
+ - **`'pure-js'`** — solves locally in pure TypeScript with `@noble/hashes` SHA-256. Browser-compatible. Slow at production difficulty (see the performance section); calibrate via `target_solve_time_s` for browser use.
120
+ - **`'auto'`** (default) — picks `'rpc'` if `opts.rpcClient` is provided, else `'pure-js'`.
121
+
122
+ ```typescript
123
+ import { BtxChallengeClient, Solver } from '@btx/challenges-sdk';
124
+
125
+ // Server-side (RPC mode): delegates the solve to btxd
126
+ const client = new BtxChallengeClient({ rpcUrl: '...', rpcAuth: { ... } });
127
+ const proof = await Solver.solve(challenge, { mode: 'rpc', rpcClient: client });
128
+
129
+ // Browser / no-RPC (pure-JS mode): solves locally, no node required
130
+ const proof = await Solver.solve(challenge, {
131
+ mode: 'pure-js',
132
+ pureJs: { maxTries: 5_000 }, // cap on attempts before giving up
133
+ });
134
+
135
+ // 'auto' (default) — picks rpc if a client is passed, else pure-js
136
+ const proof = await Solver.solve(challenge, { rpcClient: client });
137
+ ```
138
+
139
+ #### Algorithm correctness
140
+
141
+ The pure-JS solver is a direct port of the canonical CPU path from `btxd v0.29.7 src/matmul/`. We cross-validate against 5 pinned golden vectors lifted from btxd's own test suite — see `tests/unit/matmul/btxd-vectors.test.ts`. Match is byte-equal for:
142
+
143
+ - `fromSeedRect(zero, 8)` — `matrix_from_seed_deterministic`
144
+ - `deriveNoiseSeed(TAG_EL, zero_sigma)` — `noise_derived_seed_pinned_EL`
145
+ - `noise.generate(zero_sigma, 4, 2)` E_L + E_R — `noise_EL_pinned_elements` / `noise_ER_pinned_elements`
146
+ - `canonicalMatMul(n=8, b=4)` transcript_hash — `canonical_matmul_n8_b4_pinned_transcript`
147
+ - Live `deriveSigma` (2 nonces) — `verifymatmulserviceproof.proof.sigma` from a real btxd
148
+
149
+ Plus 125 internal unit tests covering field arithmetic, matrix ops, header serialization, and solver dispatch.
150
+
151
+ #### ⚠️ Deployment note — RPC mode against a mining btxd
152
+
153
+ btxd's service-challenge solver shares the matmul backend with block-template mining. On a node that's actively mining, `solvematmulservicechallenge` queues behind block work and can take **15+ minutes** per call — measured 2026-05-20 on a production mining rental, where the solve RPC didn't return even after `btx-cli`'s own 15-minute transient-error timeout fired.
154
+
155
+ For RPC mode at advertised latency (~1–4 seconds), point it at a **dedicated btxd** that is NOT mining (e.g., a $5/mo DO droplet with `gen=0` in `btx.conf`). The SDK itself works fine — the bottleneck is the upstream solver service-sharing.
156
+
157
+ ## Performance
158
+
159
+ Pure-JS solver bench at production matmul shape (n=512, b=16, r=8) on M-series Mac / Node 22 (2026-05-21):
160
+
161
+ | Statistic | Wall-clock per attempt |
162
+ |---|---|
163
+ | mean | **4.6 s** |
164
+ | median | 4.6 s |
165
+ | min / max | 4.6 / 4.7 s |
166
+
167
+ `mul` and the `dot` accumulator use `bigint` because the worst-case M31 product (`(2^31-1)^2 ≈ 2^62`) exceeds `Number`'s 2^53 precision. The `bigint`-bounded inner loop is the dominant cost.
168
+
169
+ Expected end-to-end solve time depends on challenge difficulty. At btxd's lowest service-challenge difficulty (`target_solve_time_s = min_solve_time_s = 0.001`), per-attempt success ≈ 1.3·10⁻³, so expected ≈ 770 attempts ≈ **1 hour** wall-clock. **Default difficulty is too slow for online browser use.** Workable today for:
170
+
171
+ - Server-side gating where you control difficulty (calibrate via `target_solve_time_s` for your target user wait)
172
+ - Backend cron / batch jobs
173
+ - Examples + demos with manually-issued low-difficulty challenges
174
+
175
+ Day 2.6 will add a WASM port of the matmul kernel + the `field.mul`/`field.dot` hot loops, targeting a 10× speed-up.
176
+
177
+ Reproduce the bench:
178
+
179
+ ```bash
180
+ npx tsx packages/core/tests/perf/solver-bench.ts 10 # 10 attempts
181
+ ```
182
+
183
+ > **Cross-engine note**: bench captured on **Node 22 / V8 / M-series Mac arm64** (2026-05-21). `bigint` performance varies significantly by JS engine — Bun, Deno, Firefox SpiderMonkey, Safari JavaScriptCore are untested. If you run the SDK in those environments, please file an issue with your `solver-bench.ts` output so we can track real-world numbers across engines.
184
+
185
+ ## Roadmap
186
+
187
+ | Status | Item |
188
+ |---|---|
189
+ | ✅ | Day 1: RPC client + types + audit Wave A/B/C fixes |
190
+ | ✅ | Day 2: Solver class with mode dispatch (RPC mode ships) |
191
+ | ✅ | Day 2.5: Pure-JS MatMul solver port, cross-validated against btxd goldens |
192
+ | ⏳ | Day 2.6: WASM port of matmul kernel (perf) |
193
+ | ⏳ | Day 3: Express / Fastify / Hono middleware (separate sub-packages) |
194
+ | ⏳ | Day 4: Browser demo + Node examples |
195
+ | ⏳ | Day 5-6: `@btx/mcp-gateway` companion package |
196
+ | ⏳ | Day 7-8: Docs + npm publish |
197
+ | ⏳ | Day 9: Findings + handoff |
198
+
199
+ ## Testing
200
+
201
+ ```bash
202
+ pnpm test # all tests
203
+ pnpm test:unit # msw-mocked HTTP only (fast)
204
+ pnpm test:integration # live btxd via SSH (requires fleet access)
205
+ ```
206
+
207
+ The integration test target is `btx-iowa` by default — change `SSH_TARGET` in `tests/integration/smoke.test.ts` to retarget any healthy at-tip BTX node.
208
+
209
+ ## Links
210
+
211
+ - [BTX dev portal](https://btx.dev/develop/)
212
+ - [Service-challenges RPC reference](https://btx.dev/docs/rpc/service-challenges)
213
+ - [Service-challenges integration guide](https://btx.dev/docs/guides/service-challenges)
214
+ - [BTX node source](https://github.com/btxchain/btx)
215
+
216
+ ## License
217
+
218
+ MIT