@botsigged/sdk 1.0.0 → 1.0.2

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.
@@ -0,0 +1,333 @@
1
+ import {
2
+ getHash
3
+ } from "./hash-gtpm69df.js";
4
+
5
+ // src/challenge-ui.ts
6
+ class ChallengeOverlay {
7
+ overlay = null;
8
+ messageEl = null;
9
+ progressEl = null;
10
+ config;
11
+ constructor(config) {
12
+ this.config = config;
13
+ }
14
+ show() {
15
+ if (!this.config.enabled || this.overlay)
16
+ return;
17
+ this.overlay = document.createElement("div");
18
+ this.overlay.id = "botsigged-challenge-overlay";
19
+ this.overlay.style.cssText = `
20
+ position: fixed;
21
+ top: 0;
22
+ left: 0;
23
+ width: 100%;
24
+ height: 100%;
25
+ background: ${this.config.backgroundColor};
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ justify-content: center;
30
+ z-index: ${this.config.zIndex};
31
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
32
+ `;
33
+ const spinner = document.createElement("div");
34
+ spinner.style.cssText = `
35
+ width: 48px;
36
+ height: 48px;
37
+ border: 4px solid ${this.config.textColor}33;
38
+ border-top-color: ${this.config.spinnerColor};
39
+ border-radius: 50%;
40
+ animation: botsigged-spin 1s linear infinite;
41
+ margin-bottom: 20px;
42
+ `;
43
+ this.messageEl = document.createElement("span");
44
+ this.messageEl.textContent = this.config.message;
45
+ this.messageEl.style.cssText = `
46
+ color: ${this.config.textColor};
47
+ font-size: 18px;
48
+ font-weight: 500;
49
+ margin-bottom: 12px;
50
+ `;
51
+ const progressContainer = document.createElement("div");
52
+ progressContainer.style.cssText = `
53
+ width: 200px;
54
+ height: 4px;
55
+ background: ${this.config.textColor}33;
56
+ border-radius: 2px;
57
+ overflow: hidden;
58
+ `;
59
+ this.progressEl = document.createElement("div");
60
+ this.progressEl.style.cssText = `
61
+ width: 0%;
62
+ height: 100%;
63
+ background: ${this.config.spinnerColor};
64
+ border-radius: 2px;
65
+ transition: width 0.1s ease-out;
66
+ `;
67
+ progressContainer.appendChild(this.progressEl);
68
+ const style = document.createElement("style");
69
+ style.textContent = `
70
+ @keyframes botsigged-spin {
71
+ to { transform: rotate(360deg); }
72
+ }
73
+ `;
74
+ document.head.appendChild(style);
75
+ this.overlay.appendChild(spinner);
76
+ this.overlay.appendChild(this.messageEl);
77
+ this.overlay.appendChild(progressContainer);
78
+ document.body.appendChild(this.overlay);
79
+ }
80
+ setProgress(progress) {
81
+ if (this.progressEl) {
82
+ const percent = Math.min(100, Math.max(0, progress * 100));
83
+ this.progressEl.style.width = `${percent}%`;
84
+ }
85
+ }
86
+ showSuccess() {
87
+ if (this.messageEl) {
88
+ this.messageEl.textContent = this.config.successMessage;
89
+ }
90
+ if (this.progressEl) {
91
+ this.progressEl.style.width = "100%";
92
+ }
93
+ }
94
+ hide() {
95
+ if (this.overlay) {
96
+ this.overlay.remove();
97
+ this.overlay = null;
98
+ this.messageEl = null;
99
+ this.progressEl = null;
100
+ }
101
+ }
102
+ isVisible() {
103
+ return this.overlay !== null;
104
+ }
105
+ }
106
+
107
+ // src/challenge.ts
108
+ function generateChallengePrefix() {
109
+ const prefix = new Uint8Array(16);
110
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
111
+ crypto.getRandomValues(prefix);
112
+ } else {
113
+ for (let i = 0;i < 16; i++) {
114
+ prefix[i] = Math.floor(Math.random() * 256);
115
+ }
116
+ }
117
+ return prefix;
118
+ }
119
+ function countLeadingZeroBits(value) {
120
+ if (value === 0)
121
+ return 32;
122
+ let count = 0;
123
+ if ((value & 4294901760) === 0) {
124
+ count += 16;
125
+ value <<= 16;
126
+ }
127
+ if ((value & 4278190080) === 0) {
128
+ count += 8;
129
+ value <<= 8;
130
+ }
131
+ if ((value & 4026531840) === 0) {
132
+ count += 4;
133
+ value <<= 4;
134
+ }
135
+ if ((value & 3221225472) === 0) {
136
+ count += 2;
137
+ value <<= 2;
138
+ }
139
+ if ((value & 2147483648) === 0) {
140
+ count += 1;
141
+ }
142
+ return count;
143
+ }
144
+ function solvePoWChunkJS(prefix, difficulty, chunkSize, startNonce) {
145
+ const hashModule = getHash();
146
+ const buffer = new Uint8Array(prefix.length + 4);
147
+ buffer.set(prefix);
148
+ let nonce = startNonce;
149
+ let iterations = 0;
150
+ while (iterations < chunkSize) {
151
+ buffer[prefix.length] = nonce & 255;
152
+ buffer[prefix.length + 1] = nonce >>> 8 & 255;
153
+ buffer[prefix.length + 2] = nonce >>> 16 & 255;
154
+ buffer[prefix.length + 3] = nonce >>> 24 & 255;
155
+ const hash = hashModule.xxHash32(buffer, 0);
156
+ iterations++;
157
+ if (countLeadingZeroBits(hash) >= difficulty) {
158
+ return { nonce, found: true, iterations };
159
+ }
160
+ nonce = nonce + 1 >>> 0;
161
+ }
162
+ return { nonce, found: false, iterations };
163
+ }
164
+
165
+ class ChallengeManager {
166
+ config;
167
+ overlay;
168
+ solving = false;
169
+ solved = false;
170
+ pendingForms = new Map;
171
+ formHandler = null;
172
+ formObserver = null;
173
+ resubmitting = false;
174
+ debug;
175
+ constructor(config, debug = false) {
176
+ this.config = config;
177
+ this.debug = debug;
178
+ this.overlay = new ChallengeOverlay(config.ui);
179
+ }
180
+ getDifficultyForLevel(level) {
181
+ const difficulty = this.config.difficulty;
182
+ switch (level) {
183
+ case "critical":
184
+ return difficulty.critical;
185
+ case "high":
186
+ return difficulty.high;
187
+ case "medium":
188
+ return difficulty.medium;
189
+ default:
190
+ return 0;
191
+ }
192
+ }
193
+ shouldChallenge(level) {
194
+ if (!this.config.enabled || this.solved)
195
+ return false;
196
+ const levelOrder = ["low", "medium", "high", "critical"];
197
+ const levelIndex = levelOrder.indexOf(level);
198
+ const minIndex = levelOrder.indexOf(this.config.minLevel);
199
+ return levelIndex >= minIndex;
200
+ }
201
+ blockFormsUntilSolved(level) {
202
+ if (this.formHandler)
203
+ return;
204
+ this.formHandler = (e) => {
205
+ if (this.solved || this.resubmitting)
206
+ return;
207
+ e.preventDefault();
208
+ e.stopPropagation();
209
+ const form = e.target;
210
+ if (!this.pendingForms.has(form)) {
211
+ this.pendingForms.set(form, e);
212
+ }
213
+ if (!this.solving) {
214
+ this.startChallenge(level);
215
+ }
216
+ };
217
+ document.querySelectorAll("form").forEach((form) => {
218
+ form.addEventListener("submit", this.formHandler, true);
219
+ });
220
+ this.formObserver = new MutationObserver((mutations) => {
221
+ mutations.forEach((mutation) => {
222
+ mutation.addedNodes.forEach((node) => {
223
+ if (node instanceof HTMLFormElement && this.formHandler) {
224
+ node.addEventListener("submit", this.formHandler, true);
225
+ }
226
+ if (node instanceof HTMLElement && this.formHandler) {
227
+ node.querySelectorAll("form").forEach((form) => {
228
+ form.addEventListener("submit", this.formHandler, true);
229
+ });
230
+ }
231
+ });
232
+ });
233
+ });
234
+ this.formObserver.observe(document.body, { childList: true, subtree: true });
235
+ this.log("Forms blocked, challenge required");
236
+ }
237
+ async startChallenge(level) {
238
+ if (this.solving || this.solved)
239
+ return;
240
+ this.solving = true;
241
+ const difficulty = this.getDifficultyForLevel(level);
242
+ const prefix = generateChallengePrefix();
243
+ const startTime = performance.now();
244
+ this.log(`Starting challenge: difficulty=${difficulty}, level=${level}`);
245
+ this.config.onChallengeStart?.(level, difficulty);
246
+ this.overlay.show();
247
+ const estimatedIterations = 1 << difficulty;
248
+ let nonce = 0;
249
+ let totalIterations = 0;
250
+ let result;
251
+ do {
252
+ await new Promise((resolve) => setTimeout(resolve, 0));
253
+ result = solvePoWChunkJS(prefix, difficulty, this.config.chunkSize, nonce);
254
+ totalIterations += result.iterations;
255
+ nonce = result.nonce + 1;
256
+ const progress = Math.min(1, totalIterations / estimatedIterations);
257
+ this.overlay.setProgress(progress);
258
+ this.config.onChallengeProgress?.(progress, totalIterations);
259
+ } while (!result.found);
260
+ const solveTime = performance.now() - startTime;
261
+ this.log(`Challenge solved: nonce=${result.nonce}, iterations=${totalIterations}, time=${solveTime.toFixed(0)}ms`);
262
+ this.overlay.showSuccess();
263
+ await new Promise((resolve) => setTimeout(resolve, 500));
264
+ this.overlay.hide();
265
+ this.solved = true;
266
+ this.solving = false;
267
+ const event = {
268
+ solveTimeMs: solveTime,
269
+ iterations: totalIterations,
270
+ difficulty,
271
+ level,
272
+ nonce: result.nonce
273
+ };
274
+ this.config.onChallengeComplete?.(event);
275
+ this.unblockForms();
276
+ }
277
+ unblockForms() {
278
+ if (this.formObserver) {
279
+ this.formObserver.disconnect();
280
+ this.formObserver = null;
281
+ }
282
+ if (this.formHandler) {
283
+ document.querySelectorAll("form").forEach((form) => {
284
+ form.removeEventListener("submit", this.formHandler, true);
285
+ });
286
+ this.formHandler = null;
287
+ }
288
+ this.log("Forms unblocked");
289
+ this.resubmitting = true;
290
+ this.pendingForms.forEach((_, form) => {
291
+ this.log("Resubmitting pending form");
292
+ if (form.requestSubmit) {
293
+ form.requestSubmit();
294
+ } else {
295
+ form.submit();
296
+ }
297
+ });
298
+ this.pendingForms.clear();
299
+ this.resubmitting = false;
300
+ }
301
+ isSolving() {
302
+ return this.solving;
303
+ }
304
+ isSolved() {
305
+ return this.solved;
306
+ }
307
+ reset() {
308
+ if (this.formObserver) {
309
+ this.formObserver.disconnect();
310
+ this.formObserver = null;
311
+ }
312
+ if (this.formHandler) {
313
+ document.querySelectorAll("form").forEach((form) => {
314
+ form.removeEventListener("submit", this.formHandler, true);
315
+ });
316
+ this.formHandler = null;
317
+ }
318
+ this.solved = false;
319
+ this.solving = false;
320
+ this.resubmitting = false;
321
+ this.pendingForms.clear();
322
+ }
323
+ log(...args) {
324
+ if (this.debug) {
325
+ console.log("[BotSigged:Challenge]", ...args);
326
+ }
327
+ }
328
+ }
329
+ export {
330
+ ChallengeManager
331
+ };
332
+
333
+ //# debugId=B0255CA1E0DDDD3364756E2164756E21
@@ -0,0 +1,300 @@
1
+ var __create = Object.create;
2
+ var __getProtoOf = Object.getPrototypeOf;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __toESM = (mod, isNodeMode, target) => {
7
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
8
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
9
+ for (let key of __getOwnPropNames(mod))
10
+ if (!__hasOwnProp.call(to, key))
11
+ __defProp(to, key, {
12
+ get: () => mod[key],
13
+ enumerable: true
14
+ });
15
+ return to;
16
+ };
17
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
18
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
19
+ }) : x)(function(x) {
20
+ if (typeof require !== "undefined")
21
+ return require.apply(this, arguments);
22
+ throw Error('Dynamic require of "' + x + '" is not supported');
23
+ });
24
+
25
+ // src/wasm/hash.wasm.base64.ts
26
+ var wasmBinaryBase64 = "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";
27
+ var hash_wasm_base64_default = wasmBinaryBase64;
28
+
29
+ // src/wasm/hash-wasm.ts
30
+ var wasmInstance = null;
31
+ var loadPromise = null;
32
+ function base64ToBytes(base64) {
33
+ const binaryString = atob(base64);
34
+ const bytes = new Uint8Array(binaryString.length);
35
+ for (let i = 0;i < binaryString.length; i++) {
36
+ bytes[i] = binaryString.charCodeAt(i);
37
+ }
38
+ return bytes;
39
+ }
40
+ async function loadHashModule() {
41
+ if (loadPromise) {
42
+ return loadPromise;
43
+ }
44
+ loadPromise = (async () => {
45
+ try {
46
+ const wasmBytes = base64ToBytes(hash_wasm_base64_default);
47
+ const wasmModule = await WebAssembly.compile(wasmBytes);
48
+ const instance = await WebAssembly.instantiate(wasmModule, {
49
+ env: {
50
+ abort: (_msg, _file, line, col) => {
51
+ console.error(`WASM abort at ${line}:${col}`);
52
+ }
53
+ }
54
+ });
55
+ wasmInstance = instance.exports;
56
+ return createHashModule(wasmInstance);
57
+ } catch (error) {
58
+ loadPromise = null;
59
+ throw error;
60
+ }
61
+ })();
62
+ return loadPromise;
63
+ }
64
+ function isHashModuleLoaded() {
65
+ return wasmInstance !== null;
66
+ }
67
+ function createHashModule(wasm) {
68
+ function writeBytes(data) {
69
+ const ptr = wasm.__new(data.length, 1);
70
+ const view = new Uint8Array(wasm.memory.buffer, ptr, data.length);
71
+ view.set(data);
72
+ return ptr;
73
+ }
74
+ function writeString(str) {
75
+ const buf = new Uint16Array(str.length);
76
+ for (let i = 0;i < str.length; i++) {
77
+ buf[i] = str.charCodeAt(i);
78
+ }
79
+ const ptr = wasm.__new(buf.length * 2, 2);
80
+ const mem = new Uint16Array(wasm.memory.buffer, ptr, buf.length);
81
+ mem.set(buf);
82
+ return ptr;
83
+ }
84
+ function readString(ptr, maxLength = 1024) {
85
+ const memory = new Uint8Array(wasm.memory.buffer);
86
+ const memoryLength = memory.length;
87
+ if (ptr < 0 || ptr >= memoryLength) {
88
+ return "";
89
+ }
90
+ let end = ptr;
91
+ const limit = Math.min(ptr + maxLength, memoryLength);
92
+ while (end < limit && memory[end] !== 0) {
93
+ end++;
94
+ }
95
+ const bytes = memory.slice(ptr, end);
96
+ return new TextDecoder().decode(bytes);
97
+ }
98
+ return {
99
+ xxHash32(data, seed = 0) {
100
+ const ptr = writeBytes(data);
101
+ try {
102
+ return wasm.xxHash32(ptr, seed);
103
+ } finally {
104
+ wasm.__unpin(ptr);
105
+ }
106
+ },
107
+ hashString(str, seed = 0) {
108
+ const ptr = writeString(str);
109
+ try {
110
+ return wasm.hashString(ptr, seed);
111
+ } finally {
112
+ wasm.__unpin(ptr);
113
+ }
114
+ },
115
+ hashStringToHex(str, seed = 0) {
116
+ const ptr = writeString(str);
117
+ try {
118
+ const resultPtr = wasm.hashStringToHex(ptr, seed);
119
+ return readString(resultPtr);
120
+ } finally {
121
+ wasm.__unpin(ptr);
122
+ }
123
+ },
124
+ verifyHash(data, expectedHash, seed = 0) {
125
+ const ptr = writeBytes(data);
126
+ try {
127
+ return wasm.verifyHash(ptr, expectedHash, seed);
128
+ } finally {
129
+ wasm.__unpin(ptr);
130
+ }
131
+ },
132
+ verifyStringHash(str, expectedHash, seed = 0) {
133
+ const ptr = writeString(str);
134
+ try {
135
+ return wasm.verifyStringHash(ptr, expectedHash, seed);
136
+ } finally {
137
+ wasm.__unpin(ptr);
138
+ }
139
+ }
140
+ };
141
+ }
142
+ function createFallbackHashModule() {
143
+ const textEncoder = new TextEncoder;
144
+ function xxHash32Impl(data, seed = 0) {
145
+ const PRIME32_1 = 2654435761;
146
+ const PRIME32_2 = 2246822519;
147
+ const PRIME32_3 = 3266489917;
148
+ const PRIME32_4 = 668265263;
149
+ const PRIME32_5 = 374761393;
150
+ const rotl32 = (x, r) => (x << r | x >>> 32 - r) >>> 0;
151
+ const readU32 = (arr, offset) => (arr[offset] | arr[offset + 1] << 8 | arr[offset + 2] << 16 | arr[offset + 3] << 24) >>> 0;
152
+ const len = data.length;
153
+ let h32;
154
+ let index = 0;
155
+ if (len >= 16) {
156
+ const limit = len - 16;
157
+ let v1 = seed + PRIME32_1 + PRIME32_2 >>> 0;
158
+ let v2 = seed + PRIME32_2 >>> 0;
159
+ let v3 = seed >>> 0;
160
+ let v4 = seed - PRIME32_1 >>> 0;
161
+ while (index <= limit) {
162
+ v1 = Math.imul(rotl32(v1 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
163
+ index += 4;
164
+ v2 = Math.imul(rotl32(v2 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
165
+ index += 4;
166
+ v3 = Math.imul(rotl32(v3 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
167
+ index += 4;
168
+ v4 = Math.imul(rotl32(v4 + Math.imul(readU32(data, index), PRIME32_2) >>> 0, 13), PRIME32_1) >>> 0;
169
+ index += 4;
170
+ }
171
+ h32 = rotl32(v1, 1) + rotl32(v2, 7) + rotl32(v3, 12) + rotl32(v4, 18) >>> 0;
172
+ } else {
173
+ h32 = seed + PRIME32_5 >>> 0;
174
+ }
175
+ h32 = h32 + len >>> 0;
176
+ while (index <= len - 4) {
177
+ h32 = Math.imul(rotl32(h32 + Math.imul(readU32(data, index), PRIME32_3) >>> 0, 17), PRIME32_4) >>> 0;
178
+ index += 4;
179
+ }
180
+ while (index < len) {
181
+ h32 = Math.imul(rotl32(h32 + Math.imul(data[index], PRIME32_5) >>> 0, 11), PRIME32_1) >>> 0;
182
+ index++;
183
+ }
184
+ h32 ^= h32 >>> 15;
185
+ h32 = Math.imul(h32, PRIME32_2) >>> 0;
186
+ h32 ^= h32 >>> 13;
187
+ h32 = Math.imul(h32, PRIME32_3) >>> 0;
188
+ h32 ^= h32 >>> 16;
189
+ return h32 >>> 0;
190
+ }
191
+ function toHex(value) {
192
+ return (value >>> 0).toString(16).padStart(8, "0");
193
+ }
194
+ return {
195
+ xxHash32: xxHash32Impl,
196
+ hashString(str, seed = 0) {
197
+ return xxHash32Impl(textEncoder.encode(str), seed);
198
+ },
199
+ hashStringToHex(str, seed = 0) {
200
+ return toHex(xxHash32Impl(textEncoder.encode(str), seed));
201
+ },
202
+ verifyHash(data, expectedHash, seed = 0) {
203
+ return xxHash32Impl(data, seed) === expectedHash;
204
+ },
205
+ verifyStringHash(str, expectedHash, seed = 0) {
206
+ return xxHash32Impl(textEncoder.encode(str), seed) === expectedHash;
207
+ }
208
+ };
209
+ }
210
+
211
+ // src/hash.ts
212
+ var hashModule = null;
213
+ var initPromise = null;
214
+ var useWasm = true;
215
+ async function initHashModule(config = {}) {
216
+ const { preferWasm = true, onWasmLoaded, onFallback } = config;
217
+ if (hashModule) {
218
+ return hashModule;
219
+ }
220
+ if (initPromise) {
221
+ return initPromise;
222
+ }
223
+ initPromise = (async () => {
224
+ if (preferWasm) {
225
+ try {
226
+ hashModule = await loadHashModule();
227
+ useWasm = true;
228
+ onWasmLoaded?.();
229
+ return hashModule;
230
+ } catch (error) {
231
+ const reason = error instanceof Error ? error.message : "Unknown error";
232
+ onFallback?.(reason);
233
+ }
234
+ } else {
235
+ onFallback?.("WASM disabled by configuration");
236
+ }
237
+ hashModule = createFallbackHashModule();
238
+ useWasm = false;
239
+ return hashModule;
240
+ })();
241
+ return initPromise;
242
+ }
243
+ function getHash() {
244
+ if (hashModule) {
245
+ return hashModule;
246
+ }
247
+ hashModule = createFallbackHashModule();
248
+ useWasm = false;
249
+ return hashModule;
250
+ }
251
+ function isUsingWasm() {
252
+ return useWasm && isHashModuleLoaded();
253
+ }
254
+ function hash(data, seed = 0) {
255
+ const module = getHash();
256
+ if (typeof data === "string") {
257
+ return module.hashString(data, seed);
258
+ }
259
+ return module.xxHash32(data, seed);
260
+ }
261
+ function hashToHex(data, seed = 0) {
262
+ const module = getHash();
263
+ if (typeof data === "string") {
264
+ return module.hashStringToHex(data, seed);
265
+ }
266
+ return module.xxHash32(data, seed).toString(16).padStart(8, "0");
267
+ }
268
+ function verify(data, expectedHash, seed = 0) {
269
+ const module = getHash();
270
+ const expected = typeof expectedHash === "string" ? parseInt(expectedHash, 16) : expectedHash;
271
+ if (typeof data === "string") {
272
+ return module.verifyStringHash(data, expected, seed);
273
+ }
274
+ return module.verifyHash(data, expected, seed);
275
+ }
276
+ function createSignature(data, secret) {
277
+ const module = getHash();
278
+ const secretHash = module.hashString(secret, 0);
279
+ const dataHash = module.hashString(data, secretHash);
280
+ return dataHash.toString(16).padStart(8, "0");
281
+ }
282
+ function verifySignature(data, signature, secret) {
283
+ return createSignature(data, secret) === signature;
284
+ }
285
+ export {
286
+ verifySignature,
287
+ verify,
288
+ loadHashModule,
289
+ isUsingWasm,
290
+ isHashModuleLoaded,
291
+ initHashModule,
292
+ hashToHex,
293
+ hash,
294
+ getHash,
295
+ createSignature,
296
+ createFallbackHashModule
297
+ };
298
+ export { __toESM, __require, getHash, hashToHex };
299
+
300
+ //# debugId=18EFA41CA1DEC13A64756E2164756E21