ribaunt 0.2.2 → 0.2.4
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/README.md +113 -10
- package/demo/lib/ribaunt-solver.wasm +0 -0
- package/demo/lib/solver-worker.js +174 -0
- package/demo/lib/solver-worker.js.map +1 -0
- package/demo/lib/solver.js +135 -0
- package/demo/lib/solver.js.map +1 -0
- package/demo/lib/wasm-solver.js +296 -0
- package/demo/lib/wasm-solver.js.map +1 -0
- package/demo/lib/widget-browser.js +9 -0
- package/demo/lib/widget-browser.js.map +1 -0
- package/demo/lib/widget.js +942 -0
- package/demo/lib/widget.js.map +1 -0
- package/demo/lib/worker-client.js +128 -0
- package/demo/lib/worker-client.js.map +1 -0
- package/dist/cjs/index.d.ts +48 -3
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +196 -17
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/risk.d.ts +124 -0
- package/dist/cjs/risk.d.ts.map +1 -0
- package/dist/cjs/risk.js +213 -0
- package/dist/cjs/risk.js.map +1 -0
- package/dist/index.d.ts +48 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +193 -16
- package/dist/index.js.map +1 -1
- package/dist/ribaunt-solver.wasm +0 -0
- package/dist/risk.d.ts +124 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +202 -0
- package/dist/risk.js.map +1 -0
- package/dist/solver-worker.d.ts.map +1 -1
- package/dist/solver-worker.js +166 -7
- package/dist/solver-worker.js.map +1 -1
- package/dist/solver.d.ts +1 -0
- package/dist/solver.d.ts.map +1 -1
- package/dist/solver.js +38 -3
- package/dist/solver.js.map +1 -1
- package/dist/wasm-solver.d.ts +29 -0
- package/dist/wasm-solver.d.ts.map +1 -0
- package/dist/wasm-solver.js +296 -0
- package/dist/wasm-solver.js.map +1 -0
- package/dist/widget-browser.d.ts +3 -2
- package/dist/widget-browser.d.ts.map +1 -1
- package/dist/widget-browser.js +1 -1
- package/dist/widget-browser.js.map +1 -1
- package/dist/widget-react.d.ts +4 -1
- package/dist/widget-react.d.ts.map +1 -1
- package/dist/widget-react.js +102 -14
- package/dist/widget-react.js.map +1 -1
- package/dist/widget.d.ts +42 -14
- package/dist/widget.d.ts.map +1 -1
- package/dist/widget.js +254 -12
- package/dist/widget.js.map +1 -1
- package/dist/worker-client.d.ts +7 -1
- package/dist/worker-client.d.ts.map +1 -1
- package/dist/worker-client.js +69 -19
- package/dist/worker-client.js.map +1 -1
- package/package.json +22 -9
- package/context7.json +0 -4
package/dist/risk.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ribaunt Risk Engine — programmable risk-assessment subsystem.
|
|
3
|
+
*
|
|
4
|
+
* This module is intentionally small, stateless, and caller-driven.
|
|
5
|
+
* All incoming signals are caller-supplied and treated as untrusted
|
|
6
|
+
* inputs. The default scorer is a transparent, deterministic heuristic
|
|
7
|
+
* (not an ML/fraud probability model) that can be inspected and replaced.
|
|
8
|
+
*
|
|
9
|
+
* Scoring is CPU-only, O(1) over the small set of known signals, and
|
|
10
|
+
* performs no I/O.
|
|
11
|
+
*/
|
|
12
|
+
// ── Default policy values ──────────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Sensible v1 defaults. These numbers are policy defaults, not claims
|
|
15
|
+
* about a statistically calibrated fraud model. Consumers should tune
|
|
16
|
+
* them to their application.
|
|
17
|
+
*
|
|
18
|
+
* Semantics:
|
|
19
|
+
* risk < challenge -> allow
|
|
20
|
+
* challenge <= risk < block -> challenge
|
|
21
|
+
* risk >= block -> block
|
|
22
|
+
*/
|
|
23
|
+
const _DEFAULT_RISK_THRESHOLDS = Object.freeze({
|
|
24
|
+
challenge: 40,
|
|
25
|
+
block: 80,
|
|
26
|
+
});
|
|
27
|
+
export const DEFAULT_RISK_THRESHOLDS = _DEFAULT_RISK_THRESHOLDS;
|
|
28
|
+
// ── Validation helpers ─────────────────────────────────────────────────────
|
|
29
|
+
/**
|
|
30
|
+
* Validate thresholds. Throws if invalid rather than silently repairing.
|
|
31
|
+
* Requires 0 <= challenge < block <= 100
|
|
32
|
+
*/
|
|
33
|
+
export function validateRiskThresholds(thresholds) {
|
|
34
|
+
if (!thresholds || typeof thresholds !== 'object' || Array.isArray(thresholds)) {
|
|
35
|
+
throw new Error('Risk thresholds must be an object');
|
|
36
|
+
}
|
|
37
|
+
const c = thresholds.challenge;
|
|
38
|
+
const b = thresholds.block;
|
|
39
|
+
if (typeof c !== 'number' || !Number.isFinite(c)) {
|
|
40
|
+
throw new Error('Challenge threshold must be a finite number');
|
|
41
|
+
}
|
|
42
|
+
if (typeof b !== 'number' || !Number.isFinite(b)) {
|
|
43
|
+
throw new Error('Block threshold must be a finite number');
|
|
44
|
+
}
|
|
45
|
+
if (c < 0 || c > 100) {
|
|
46
|
+
throw new Error('Challenge threshold must be between 0 and 100');
|
|
47
|
+
}
|
|
48
|
+
if (b < 0 || b > 100) {
|
|
49
|
+
throw new Error('Block threshold must be between 0 and 100');
|
|
50
|
+
}
|
|
51
|
+
if (c >= b) {
|
|
52
|
+
throw new Error('Challenge threshold must be less than block threshold');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Validate scorer output. Custom scorers must return a finite number
|
|
57
|
+
* between 0 and 100 inclusive. Do not silently clamp — reject as a
|
|
58
|
+
* configuration/programming error so broken policies are visible.
|
|
59
|
+
*/
|
|
60
|
+
export function validateScorerOutput(value) {
|
|
61
|
+
if (typeof value !== 'number') {
|
|
62
|
+
throw new Error('Scorer must return a finite number between 0 and 100');
|
|
63
|
+
}
|
|
64
|
+
if (!Number.isFinite(value)) {
|
|
65
|
+
throw new Error('Scorer must return a finite number between 0 and 100');
|
|
66
|
+
}
|
|
67
|
+
if (value < 0 || value > 100) {
|
|
68
|
+
throw new Error('Scorer must return a number between 0 and 100');
|
|
69
|
+
}
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
export function clampRisk(value) {
|
|
73
|
+
if (!Number.isFinite(value))
|
|
74
|
+
return 0;
|
|
75
|
+
return Math.max(0, Math.min(100, Math.round(value)));
|
|
76
|
+
}
|
|
77
|
+
// ── Normalizer / rule helpers (default scorer pipeline) ───────────────────
|
|
78
|
+
/**
|
|
79
|
+
* Normalize account age to a bounded risk contribution (0..30).
|
|
80
|
+
*
|
|
81
|
+
* Younger accounts contribute more risk than older accounts.
|
|
82
|
+
* - Negative ages are invalid/ignored (0)
|
|
83
|
+
* - NaN / Infinity are ignored (0)
|
|
84
|
+
* - Very large values saturate to 0 rather than overflow (no dominance)
|
|
85
|
+
*
|
|
86
|
+
* Buckets are documented and deterministic:
|
|
87
|
+
* < 60s -> 30
|
|
88
|
+
* < 1h -> 25
|
|
89
|
+
* < 1d -> 20
|
|
90
|
+
* < 7d -> 15
|
|
91
|
+
* < 30d -> 10
|
|
92
|
+
* < 90d -> 5
|
|
93
|
+
* >= 90d -> 0
|
|
94
|
+
*/
|
|
95
|
+
export function normalizeAccountAge(value) {
|
|
96
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
if (value < 60)
|
|
100
|
+
return 30;
|
|
101
|
+
if (value < 3600)
|
|
102
|
+
return 25;
|
|
103
|
+
if (value < 86400)
|
|
104
|
+
return 20;
|
|
105
|
+
if (value < 604800)
|
|
106
|
+
return 15;
|
|
107
|
+
if (value < 2592000)
|
|
108
|
+
return 10;
|
|
109
|
+
if (value < 7776000)
|
|
110
|
+
return 5;
|
|
111
|
+
return 0;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalize caller-derived request velocity to a bounded contribution (0..40).
|
|
115
|
+
*
|
|
116
|
+
* Higher velocity contributes more risk.
|
|
117
|
+
* - Negative values are invalid/ignored
|
|
118
|
+
* - Non-finite values are ignored
|
|
119
|
+
* - Saturates rather than growing without bound
|
|
120
|
+
*
|
|
121
|
+
* Buckets:
|
|
122
|
+
* < 1 -> 0
|
|
123
|
+
* < 5 -> 10
|
|
124
|
+
* < 20 -> 20
|
|
125
|
+
* < 60 -> 30
|
|
126
|
+
* < 200 -> 35
|
|
127
|
+
* >= 200 -> 40
|
|
128
|
+
*
|
|
129
|
+
* The caller-derived velocity is not assumed to be authoritative; it is
|
|
130
|
+
* a weak heuristic contributed to the total score.
|
|
131
|
+
*/
|
|
132
|
+
export function normalizeRequestVelocity(value) {
|
|
133
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) {
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
if (value < 1)
|
|
137
|
+
return 0;
|
|
138
|
+
if (value < 5)
|
|
139
|
+
return 10;
|
|
140
|
+
if (value < 20)
|
|
141
|
+
return 20;
|
|
142
|
+
if (value < 60)
|
|
143
|
+
return 30;
|
|
144
|
+
if (value < 200)
|
|
145
|
+
return 35;
|
|
146
|
+
return 40;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Inspect user-agent signal as a weak signal only.
|
|
150
|
+
*
|
|
151
|
+
* - Missing or non-string UA -> 0 (not treated as strong signal)
|
|
152
|
+
* - Empty / whitespace-only UA -> 5
|
|
153
|
+
* - Very short UA (<10 chars) -> 10
|
|
154
|
+
* - Otherwise -> 0
|
|
155
|
+
*
|
|
156
|
+
* No fragile substring bans (e.g. `ua.includes('bot')`) are used.
|
|
157
|
+
* UA classification is not treated as trustworthy.
|
|
158
|
+
*/
|
|
159
|
+
export function scoreUserAgent(value) {
|
|
160
|
+
if (typeof value !== 'string')
|
|
161
|
+
return 0;
|
|
162
|
+
const trimmed = value.trim();
|
|
163
|
+
if (trimmed.length === 0)
|
|
164
|
+
return 5;
|
|
165
|
+
if (trimmed.length < 10)
|
|
166
|
+
return 10;
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* IP is accepted for custom scorers but the default scorer does not
|
|
171
|
+
* pretend to know whether an IP is malicious. The safest v1 choice is
|
|
172
|
+
* to return 0 and let custom scorers handle IP reputation if needed.
|
|
173
|
+
*/
|
|
174
|
+
export function scoreIp(_value) {
|
|
175
|
+
return 0;
|
|
176
|
+
}
|
|
177
|
+
// ── Default scorer ─────────────────────────────────────────────────────────
|
|
178
|
+
/**
|
|
179
|
+
* Deterministic default scorer. Transparent heuristic:
|
|
180
|
+
* signals -> normalizeAccountAge + normalizeRequestVelocity + scoreUserAgent + scoreIp -> clamp 0..100
|
|
181
|
+
*
|
|
182
|
+
* Unknown properties on RiskSignals are ignored by the default scorer;
|
|
183
|
+
* custom scorers may use them.
|
|
184
|
+
*
|
|
185
|
+
* This scorer is synchronous internally but exposed as async via the
|
|
186
|
+
* RiskScorer interface so callers can supply remote/model-based scorers
|
|
187
|
+
* without changing the API.
|
|
188
|
+
*/
|
|
189
|
+
export function defaultScore(signals) {
|
|
190
|
+
const age = normalizeAccountAge(signals.accountAgeSeconds);
|
|
191
|
+
const velocity = normalizeRequestVelocity(signals.requestVelocity);
|
|
192
|
+
const ua = scoreUserAgent(signals.userAgent);
|
|
193
|
+
const ip = scoreIp(signals.ip);
|
|
194
|
+
const raw = age + velocity + ua + ip;
|
|
195
|
+
return clampRisk(raw);
|
|
196
|
+
}
|
|
197
|
+
export const defaultScorer = {
|
|
198
|
+
async score(signals) {
|
|
199
|
+
return defaultScore(signals);
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=risk.js.map
|
package/dist/risk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"risk.js","sourceRoot":"","sources":["../src/risk.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver-worker.d.ts","sourceRoot":"","sources":["../src/solver-worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"solver-worker.d.ts","sourceRoot":"","sources":["../src/solver-worker.ts"],"names":[],"mappings":"AAiNA,OAAO,EAAE,CAAC"}
|
package/dist/solver-worker.js
CHANGED
|
@@ -1,15 +1,174 @@
|
|
|
1
1
|
/// <reference lib="webworker" />
|
|
2
|
-
import { solveChallenge } from './solver.js';
|
|
2
|
+
import { solveChallenge, decodeChallengeToken } from './solver.js';
|
|
3
|
+
import { ensureWasm, solveBatch, resetWasmHeap } from './wasm-solver.js';
|
|
3
4
|
const workerScope = self;
|
|
5
|
+
const activeControllers = new Map();
|
|
6
|
+
// Cache WASM initialization per worker lifetime (wasm-solver already caches, but keep explicit)
|
|
7
|
+
let wasmBackendState = 'uninitialized';
|
|
8
|
+
const WASM_BATCH_SIZE = 1024;
|
|
9
|
+
const yieldToEventLoop = (() => {
|
|
10
|
+
if (typeof MessageChannel !== 'function') {
|
|
11
|
+
return () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
12
|
+
}
|
|
13
|
+
let channel = null;
|
|
14
|
+
const waiting = new Set();
|
|
15
|
+
return () => {
|
|
16
|
+
if (!channel) {
|
|
17
|
+
channel = new MessageChannel();
|
|
18
|
+
channel.port1.onmessage = () => {
|
|
19
|
+
for (const resolve of waiting)
|
|
20
|
+
resolve();
|
|
21
|
+
waiting.clear();
|
|
22
|
+
};
|
|
23
|
+
channel.port1.unref?.();
|
|
24
|
+
}
|
|
25
|
+
return new Promise((resolve) => {
|
|
26
|
+
waiting.add(resolve);
|
|
27
|
+
channel.port2.postMessage(null);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
})();
|
|
31
|
+
async function solveSingleChallengeWasm(token, signal) {
|
|
32
|
+
const payload = decodeChallengeToken(token);
|
|
33
|
+
if (!payload)
|
|
34
|
+
return undefined;
|
|
35
|
+
const { challenge, difficulty } = payload;
|
|
36
|
+
let startNonce = 0;
|
|
37
|
+
try {
|
|
38
|
+
while (true) {
|
|
39
|
+
if (signal?.aborted) {
|
|
40
|
+
throw new DOMException('Challenge solving aborted', 'AbortError');
|
|
41
|
+
}
|
|
42
|
+
const result = solveBatch(challenge, startNonce, WASM_BATCH_SIZE, difficulty);
|
|
43
|
+
if (result.found && result.nonce && result.hash) {
|
|
44
|
+
// Validate before returning (wasm-solver already validated, but double-check)
|
|
45
|
+
if (typeof result.nonce !== 'string' || typeof result.hash !== 'string') {
|
|
46
|
+
throw new Error('Invalid WASM result shape');
|
|
47
|
+
}
|
|
48
|
+
return { nonce: result.nonce, hash: result.hash };
|
|
49
|
+
}
|
|
50
|
+
startNonce += WASM_BATCH_SIZE;
|
|
51
|
+
// Overflow guard - do not wrap; allow final batch where last nonce is 0x7fffffff
|
|
52
|
+
if (startNonce > 0x7fffffff - WASM_BATCH_SIZE + 1) {
|
|
53
|
+
throw new Error('WASM solver nonce overflow');
|
|
54
|
+
}
|
|
55
|
+
// Yield every 2048 nonces to keep worker responsive (matches JS solver's 2048)
|
|
56
|
+
if (startNonce % 2048 === 0) {
|
|
57
|
+
await yieldToEventLoop();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
// Reset heap to avoid leak between tokens/requests
|
|
63
|
+
try {
|
|
64
|
+
resetWasmHeap();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// ignore
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function solveChallengeWasm(tokens, onProgress, signal) {
|
|
72
|
+
const solutions = [];
|
|
73
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
74
|
+
const token = tokens[i];
|
|
75
|
+
if (!token)
|
|
76
|
+
throw new Error(`Invalid token at index ${i}`);
|
|
77
|
+
if (signal?.aborted)
|
|
78
|
+
throw new DOMException('Challenge solving aborted', 'AbortError');
|
|
79
|
+
const solution = await solveSingleChallengeWasm(token, signal);
|
|
80
|
+
if (!solution)
|
|
81
|
+
throw new Error(`Failed to solve challenge ${i + 1}`);
|
|
82
|
+
solutions.push(solution);
|
|
83
|
+
if (onProgress) {
|
|
84
|
+
const progress = Math.round(((i + 1) / tokens.length) * 100);
|
|
85
|
+
onProgress(progress);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return solutions;
|
|
89
|
+
}
|
|
90
|
+
async function selectBackend(wasmMode) {
|
|
91
|
+
if (wasmMode === 'disabled')
|
|
92
|
+
return 'js';
|
|
93
|
+
// preferred (default)
|
|
94
|
+
if (wasmBackendState === 'wasm-unavailable')
|
|
95
|
+
return 'js';
|
|
96
|
+
if (wasmBackendState === 'wasm-ready')
|
|
97
|
+
return 'wasm';
|
|
98
|
+
// uninitialized -> try to init
|
|
99
|
+
try {
|
|
100
|
+
const ok = await ensureWasm();
|
|
101
|
+
wasmBackendState = ok ? 'wasm-ready' : 'wasm-unavailable';
|
|
102
|
+
return ok ? 'wasm' : 'js';
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
wasmBackendState = 'wasm-unavailable';
|
|
106
|
+
return 'js';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
4
109
|
workerScope.addEventListener('message', (event) => {
|
|
5
110
|
const request = event.data;
|
|
6
|
-
if (request
|
|
111
|
+
if (!request)
|
|
7
112
|
return;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
113
|
+
if (request.type === 'cancel') {
|
|
114
|
+
const controller = activeControllers.get(request.id);
|
|
115
|
+
if (controller) {
|
|
116
|
+
controller.abort();
|
|
117
|
+
activeControllers.delete(request.id);
|
|
118
|
+
workerScope.postMessage({ type: 'cancelled', id: request.id });
|
|
119
|
+
workerScope.close();
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (request.type !== 'solve')
|
|
124
|
+
return;
|
|
125
|
+
const controller = new AbortController();
|
|
126
|
+
activeControllers.set(request.id, controller);
|
|
127
|
+
const wasmMode = request.wasmMode === 'disabled' ? 'disabled' : 'preferred';
|
|
128
|
+
(async () => {
|
|
129
|
+
const backend = await selectBackend(wasmMode);
|
|
130
|
+
// Telemetry: report backend selection once per request
|
|
131
|
+
if (!controller.signal.aborted) {
|
|
132
|
+
try {
|
|
133
|
+
workerScope.postMessage({ type: 'backend', id: request.id, backend });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// telemetry must never break solving
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const solver = backend === 'wasm' ? solveChallengeWasm : solveChallenge;
|
|
140
|
+
// For wasm-unavailable fallback, re-select if wasm fails during solve? We already selected js
|
|
141
|
+
// But if backend is wasm and solve fails with internal error, we surface not fallback
|
|
142
|
+
return solver(request.tokens, (progress) => {
|
|
143
|
+
if (!controller.signal.aborted) {
|
|
144
|
+
workerScope.postMessage({
|
|
145
|
+
type: 'progress',
|
|
146
|
+
id: request.id,
|
|
147
|
+
progress,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}, controller.signal);
|
|
151
|
+
})().then((solutions) => {
|
|
152
|
+
activeControllers.delete(request.id);
|
|
153
|
+
if (controller.signal.aborted)
|
|
154
|
+
return;
|
|
155
|
+
workerScope.postMessage({
|
|
156
|
+
type: 'result',
|
|
157
|
+
id: request.id,
|
|
158
|
+
solutions,
|
|
159
|
+
});
|
|
160
|
+
}, (error) => {
|
|
161
|
+
activeControllers.delete(request.id);
|
|
162
|
+
if (controller.signal.aborted)
|
|
163
|
+
return;
|
|
164
|
+
// If WASM was selected and failed due to unexpected runtime error, surface as error
|
|
165
|
+
// For expected initialization failures we already fell back to JS, so this error is genuine
|
|
166
|
+
workerScope.postMessage({
|
|
167
|
+
type: 'error',
|
|
168
|
+
id: request.id,
|
|
169
|
+
error: error instanceof Error ? error.message : String(error),
|
|
170
|
+
});
|
|
171
|
+
});
|
|
13
172
|
});
|
|
14
173
|
export {};
|
|
15
174
|
//# sourceMappingURL=solver-worker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver-worker.js","sourceRoot":"","sources":["../src/solver-worker.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"solver-worker.js","sourceRoot":"","sources":["../src/solver-worker.ts"],"names":[],"mappings":"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"}
|
package/dist/solver.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface ChallengePayload {
|
|
|
16
16
|
}
|
|
17
17
|
export declare function calibrateBrowser(iterations?: number): Promise<BrowserCalibration>;
|
|
18
18
|
export declare const calibrateClient: typeof calibrateBrowser;
|
|
19
|
+
export declare function decodeChallengeToken(token: string): ChallengePayload | null;
|
|
19
20
|
/**
|
|
20
21
|
* Solve a single challenge token (browser-compatible)
|
|
21
22
|
*/
|
package/dist/solver.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"solver.d.ts","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AA4ED,wBAAsB,gBAAgB,CAAC,UAAU,SAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAepF;AAED,eAAO,MAAM,eAAe,yBAAmB,CAAC;AAEhD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAE3E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CA0BxC;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EACvC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAwB9B"}
|
package/dist/solver.js
CHANGED
|
@@ -34,6 +34,38 @@ async function sha256(message) {
|
|
|
34
34
|
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
35
35
|
return hashHex;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Yield to the event loop without the ~4ms clamping browsers apply to
|
|
39
|
+
* nested setTimeout calls. MessageChannel tasks run as macrotasks with
|
|
40
|
+
* microsecond-level latency, keeping the UI responsive at a fraction of
|
|
41
|
+
* the timer overhead.
|
|
42
|
+
*
|
|
43
|
+
* The channel is created lazily on first yield, and the receiving port is
|
|
44
|
+
* unref'd where supported (Node.js): a port with an active message listener
|
|
45
|
+
* otherwise keeps the host event loop alive and prevents clean exit.
|
|
46
|
+
*/
|
|
47
|
+
const yieldToEventLoop = (() => {
|
|
48
|
+
if (typeof MessageChannel !== 'function') {
|
|
49
|
+
return () => new Promise((resolve) => setTimeout(resolve, 0));
|
|
50
|
+
}
|
|
51
|
+
let channel = null;
|
|
52
|
+
const waiting = new Set();
|
|
53
|
+
return () => {
|
|
54
|
+
if (!channel) {
|
|
55
|
+
channel = new MessageChannel();
|
|
56
|
+
channel.port1.onmessage = () => {
|
|
57
|
+
for (const resolve of waiting)
|
|
58
|
+
resolve();
|
|
59
|
+
waiting.clear();
|
|
60
|
+
};
|
|
61
|
+
channel.port1.unref?.();
|
|
62
|
+
}
|
|
63
|
+
return new Promise((resolve) => {
|
|
64
|
+
waiting.add(resolve);
|
|
65
|
+
channel.port2.postMessage(null);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
})();
|
|
37
69
|
export async function calibrateBrowser(iterations = 128) {
|
|
38
70
|
if (!Number.isFinite(iterations) || iterations < 1) {
|
|
39
71
|
throw new Error('Calibration iterations must be at least 1');
|
|
@@ -49,6 +81,9 @@ export async function calibrateBrowser(iterations = 128) {
|
|
|
49
81
|
};
|
|
50
82
|
}
|
|
51
83
|
export const calibrateClient = calibrateBrowser;
|
|
84
|
+
export function decodeChallengeToken(token) {
|
|
85
|
+
return decodeJWT(token);
|
|
86
|
+
}
|
|
52
87
|
/**
|
|
53
88
|
* Solve a single challenge token (browser-compatible)
|
|
54
89
|
*/
|
|
@@ -68,9 +103,9 @@ export async function solveSingleChallenge(token, signal) {
|
|
|
68
103
|
return { nonce: String(nonce), hash };
|
|
69
104
|
}
|
|
70
105
|
nonce++;
|
|
71
|
-
// Yield to
|
|
72
|
-
if (nonce %
|
|
73
|
-
await
|
|
106
|
+
// Yield to keep the UI responsive; each batch amortizes the yield cost.
|
|
107
|
+
if (nonce % 2048 === 0) {
|
|
108
|
+
await yieldToEventLoop();
|
|
74
109
|
}
|
|
75
110
|
}
|
|
76
111
|
}
|
package/dist/solver.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH;;GAEG;AACH,SAAS,SAAS,CAAC,KAAa;IAC9B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAEjD,MAAM,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzE,MAAM,aAAa,GAAG,iBAAiB,CAAC,MAAM,CAC5C,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EACrE,GAAG,CACJ,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QAChD,OAAO,OAA2B,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,MAAM,CAAC,OAAe;IACnC,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAU,GAAG,GAAG;IACrD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACpC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,oBAAoB,EAAE,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,MAAM,CAAC,uBAAuB,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO;QACL,UAAU,EAAE,oBAAoB;QAChC,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,KAAa,EACb,MAAoB;IAEpB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAE/B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAC1C,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACpB,MAAM,IAAI,YAAY,CAAC,2BAA2B,EAAE,YAAY,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,GAAG,SAAS,GAAG,KAAK,EAAE,CAAC,CAAC;QAElD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;QAED,KAAK,EAAE,CAAC;QAER,
|
|
1
|
+
{"version":3,"file":"solver.js","sourceRoot":"","sources":["../src/solver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript adapter for the WASM SHA-256 solver.
|
|
3
|
+
* Contains all WASM-specific implementation details and validates boundary values.
|
|
4
|
+
*/
|
|
5
|
+
export type WasmMode = 'preferred' | 'disabled';
|
|
6
|
+
export interface WasmBatchResult {
|
|
7
|
+
found: boolean;
|
|
8
|
+
nonce?: string;
|
|
9
|
+
hash?: string;
|
|
10
|
+
}
|
|
11
|
+
declare let wasmState: 'uninitialized' | 'wasm-ready' | 'wasm-unavailable';
|
|
12
|
+
export interface WasmSolver {
|
|
13
|
+
solveBatch(challenge: string, startNonce: number, batchSize: number, difficulty: number): WasmBatchResult;
|
|
14
|
+
}
|
|
15
|
+
export declare function ensureWasm(): Promise<boolean>;
|
|
16
|
+
export declare function getWasmState(): typeof wasmState;
|
|
17
|
+
export declare function resetWasmForTesting(): void;
|
|
18
|
+
export declare function setWasmUnavailableForTesting(): void;
|
|
19
|
+
export declare function isWasmAvailable(): boolean;
|
|
20
|
+
export declare function resetWasmHeap(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Synchronous batch solver - must be called after ensureWasm() succeeds.
|
|
23
|
+
* Encodes challenge as UTF-8, allocates in WASM memory, calls solve_batch,
|
|
24
|
+
* validates and returns result.
|
|
25
|
+
*/
|
|
26
|
+
export declare function solveBatch(challenge: string, startNonce: number, batchSize: number, difficulty: number): WasmBatchResult;
|
|
27
|
+
export declare function isTextEncoderAvailable(): boolean;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=wasm-solver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm-solver.d.ts","sourceRoot":"","sources":["../src/wasm-solver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAaD,QAAA,IAAI,SAAS,EAAE,eAAe,GAAG,YAAY,GAAG,kBAAoC,CAAC;AAOrF,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CAAC;CAC3G;AAwHD,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAYnD;AAED,wBAAgB,YAAY,IAAI,OAAO,SAAS,CAE/C;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C;AAGD,wBAAgB,4BAA4B,IAAI,IAAI,CAInD;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAYpC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,eAAe,CAsGjB;AAGD,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD"}
|