@cap.js/widget 0.1.57 → 0.1.59
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/cap-floating.min.js +1 -1
- package/cap.d.ts +11 -0
- package/cap.min.js +1 -1
- package/package.json +1 -1
- package/src/cap-floating.js +1 -3
- package/src/cap.js +630 -193
- package/src/i18n/translations.mjs +869 -0
- package/src/worker.js +300 -16
- package/cap.compat.min.js +0 -408
- package/src/i18n/translations.js +0 -87
package/src/worker.js
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
if (!self.CAP_SILENT) console[method]("[cap worker]", ...args);
|
|
4
4
|
};
|
|
5
5
|
|
|
6
|
+
const HASHWX_CLOCK_EVERY = 256;
|
|
7
|
+
const HASHWX_YIELD_MS = 16;
|
|
8
|
+
const HASHWX_PROGRESS_MS = 150;
|
|
9
|
+
let stopRequested = false;
|
|
10
|
+
const yieldChannel =
|
|
11
|
+
typeof MessageChannel === "function" ? new MessageChannel() : null;
|
|
12
|
+
const macrotask = () =>
|
|
13
|
+
new Promise((resolve) => {
|
|
14
|
+
if (!yieldChannel) return setTimeout(resolve, 0);
|
|
15
|
+
yieldChannel.port1.onmessage = () => resolve();
|
|
16
|
+
yieldChannel.port2.postMessage(0);
|
|
17
|
+
});
|
|
18
|
+
|
|
6
19
|
const solveFallback = async ({ salt, target }) => {
|
|
7
20
|
let nonce = 0;
|
|
8
21
|
const batchSize = 50000;
|
|
@@ -19,7 +32,8 @@
|
|
|
19
32
|
targetBytes[k] = parseInt(paddedTarget.substring(k * 2, k * 2 + 2), 16);
|
|
20
33
|
}
|
|
21
34
|
|
|
22
|
-
const partialMask =
|
|
35
|
+
const partialMask =
|
|
36
|
+
remainingBits > 0 ? (0xff << (8 - remainingBits)) & 0xff : 0;
|
|
23
37
|
|
|
24
38
|
while (true) {
|
|
25
39
|
try {
|
|
@@ -41,7 +55,10 @@
|
|
|
41
55
|
}
|
|
42
56
|
|
|
43
57
|
if (matches && remainingBits > 0) {
|
|
44
|
-
if (
|
|
58
|
+
if (
|
|
59
|
+
(hashBytes[fullBytes] & partialMask) !==
|
|
60
|
+
(targetBytes[fullBytes] & partialMask)
|
|
61
|
+
) {
|
|
45
62
|
matches = false;
|
|
46
63
|
}
|
|
47
64
|
}
|
|
@@ -54,7 +71,7 @@
|
|
|
54
71
|
nonce++;
|
|
55
72
|
}
|
|
56
73
|
} catch (error) {
|
|
57
|
-
wlog("error","fallback solver crashed:", error.message || error);
|
|
74
|
+
wlog("error", "fallback solver crashed:", error.message || error);
|
|
58
75
|
self.postMessage({
|
|
59
76
|
found: false,
|
|
60
77
|
error: error.message,
|
|
@@ -65,8 +82,8 @@
|
|
|
65
82
|
};
|
|
66
83
|
|
|
67
84
|
const solveRsw = (data) => {
|
|
68
|
-
const N = BigInt(
|
|
69
|
-
let y = BigInt(
|
|
85
|
+
const N = BigInt(`0x${data.N}`);
|
|
86
|
+
let y = BigInt(`0x${data.x}`);
|
|
70
87
|
const t = data.t | 0;
|
|
71
88
|
const chunk = Math.max(64, Math.floor(t / 50));
|
|
72
89
|
const t0 = performance.now();
|
|
@@ -82,11 +99,246 @@
|
|
|
82
99
|
});
|
|
83
100
|
};
|
|
84
101
|
|
|
85
|
-
|
|
86
|
-
|
|
102
|
+
const SHA_K = new Uint32Array([
|
|
103
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
|
104
|
+
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
105
|
+
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
106
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
107
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
|
108
|
+
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
109
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
|
110
|
+
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
111
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
112
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
|
113
|
+
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
const sha256Into = (bytes, out) => {
|
|
117
|
+
const len = bytes.length;
|
|
118
|
+
const blocks = ((len + 8) >> 6) + 1;
|
|
119
|
+
const padded = new Uint8Array(blocks << 6);
|
|
120
|
+
padded.set(bytes);
|
|
121
|
+
padded[len] = 0x80;
|
|
122
|
+
const bitLen = len * 8;
|
|
123
|
+
const dv = new DataView(padded.buffer);
|
|
124
|
+
dv.setUint32(padded.length - 4, bitLen >>> 0, false);
|
|
125
|
+
dv.setUint32(padded.length - 8, Math.floor(bitLen / 0x100000000), false);
|
|
126
|
+
|
|
127
|
+
let h0 = 0x6a09e667,
|
|
128
|
+
h1 = 0xbb67ae85,
|
|
129
|
+
h2 = 0x3c6ef372,
|
|
130
|
+
h3 = 0xa54ff53a;
|
|
131
|
+
let h4 = 0x510e527f,
|
|
132
|
+
h5 = 0x9b05688c,
|
|
133
|
+
h6 = 0x1f83d9ab,
|
|
134
|
+
h7 = 0x5be0cd19;
|
|
135
|
+
const w = new Uint32Array(64);
|
|
136
|
+
|
|
137
|
+
for (let b = 0; b < blocks; b++) {
|
|
138
|
+
const off = b << 6;
|
|
139
|
+
for (let i = 0; i < 16; i++) w[i] = dv.getUint32(off + (i << 2), false);
|
|
140
|
+
for (let i = 16; i < 64; i++) {
|
|
141
|
+
const x = w[i - 15],
|
|
142
|
+
y = w[i - 2];
|
|
143
|
+
const s0 =
|
|
144
|
+
((x >>> 7) | (x << 25)) ^ ((x >>> 18) | (x << 14)) ^ (x >>> 3);
|
|
145
|
+
const s1 =
|
|
146
|
+
((y >>> 17) | (y << 15)) ^ ((y >>> 19) | (y << 13)) ^ (y >>> 10);
|
|
147
|
+
w[i] = (w[i - 16] + s0 + w[i - 7] + s1) >>> 0;
|
|
148
|
+
}
|
|
149
|
+
let a = h0,
|
|
150
|
+
bb = h1,
|
|
151
|
+
c = h2,
|
|
152
|
+
d = h3,
|
|
153
|
+
e = h4,
|
|
154
|
+
f = h5,
|
|
155
|
+
g = h6,
|
|
156
|
+
h = h7;
|
|
157
|
+
for (let i = 0; i < 64; i++) {
|
|
158
|
+
const S1 =
|
|
159
|
+
((e >>> 6) | (e << 26)) ^
|
|
160
|
+
((e >>> 11) | (e << 21)) ^
|
|
161
|
+
((e >>> 25) | (e << 7));
|
|
162
|
+
const ch = (e & f) ^ (~e & g);
|
|
163
|
+
const t1 = (h + S1 + ch + SHA_K[i] + w[i]) >>> 0;
|
|
164
|
+
const S0 =
|
|
165
|
+
((a >>> 2) | (a << 30)) ^
|
|
166
|
+
((a >>> 13) | (a << 19)) ^
|
|
167
|
+
((a >>> 22) | (a << 10));
|
|
168
|
+
const maj = (a & bb) ^ (a & c) ^ (bb & c);
|
|
169
|
+
const t2 = (S0 + maj) >>> 0;
|
|
170
|
+
h = g;
|
|
171
|
+
g = f;
|
|
172
|
+
f = e;
|
|
173
|
+
e = (d + t1) >>> 0;
|
|
174
|
+
d = c;
|
|
175
|
+
c = bb;
|
|
176
|
+
bb = a;
|
|
177
|
+
a = (t1 + t2) >>> 0;
|
|
178
|
+
}
|
|
179
|
+
h0 = (h0 + a) >>> 0;
|
|
180
|
+
h1 = (h1 + bb) >>> 0;
|
|
181
|
+
h2 = (h2 + c) >>> 0;
|
|
182
|
+
h3 = (h3 + d) >>> 0;
|
|
183
|
+
h4 = (h4 + e) >>> 0;
|
|
184
|
+
h5 = (h5 + f) >>> 0;
|
|
185
|
+
h6 = (h6 + g) >>> 0;
|
|
186
|
+
h7 = (h7 + h) >>> 0;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const odv = new DataView(out.buffer, out.byteOffset, 32);
|
|
190
|
+
odv.setUint32(0, h0, false);
|
|
191
|
+
odv.setUint32(4, h1, false);
|
|
192
|
+
odv.setUint32(8, h2, false);
|
|
193
|
+
odv.setUint32(12, h3, false);
|
|
194
|
+
odv.setUint32(16, h4, false);
|
|
195
|
+
odv.setUint32(20, h5, false);
|
|
196
|
+
odv.setUint32(24, h6, false);
|
|
197
|
+
odv.setUint32(28, h7, false);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
let hashwxRuntime = null;
|
|
201
|
+
|
|
202
|
+
const getHashwxRuntime = (hashwxModule) => {
|
|
203
|
+
if (hashwxRuntime) return hashwxRuntime;
|
|
204
|
+
|
|
205
|
+
const instance = new WebAssembly.Instance(hashwxModule, {});
|
|
206
|
+
const w = instance.exports;
|
|
207
|
+
if (w._initialize) w._initialize();
|
|
208
|
+
|
|
209
|
+
let compiled = true;
|
|
210
|
+
let ctx = w.hashwx_alloc(1);
|
|
211
|
+
if (ctx === -1 || ctx === 0) {
|
|
212
|
+
compiled = false;
|
|
213
|
+
ctx = w.hashwx_alloc(0);
|
|
214
|
+
}
|
|
215
|
+
if (ctx <= 0) throw new Error("hashwx_alloc failed");
|
|
216
|
+
|
|
217
|
+
hashwxRuntime = {
|
|
218
|
+
w,
|
|
219
|
+
ctx,
|
|
220
|
+
compiled,
|
|
221
|
+
seedPtr: w.hashwx_seed(ctx),
|
|
222
|
+
regPtr: compiled ? w.hashwx_registers(ctx) : 0,
|
|
223
|
+
memPtr: compiled ? w.hashwx_memory(ctx) : 0,
|
|
224
|
+
};
|
|
225
|
+
return hashwxRuntime;
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const solveHashwx = async (data) => {
|
|
229
|
+
const { c, d, n, workerIndex, workerCount, hashwxModule } = data;
|
|
230
|
+
if (!Number.isInteger(n) || n < 1 || !Number.isInteger(d) || d < 1) {
|
|
231
|
+
throw new Error("malformed hashwx challenge payload");
|
|
232
|
+
}
|
|
233
|
+
const noncesPerHash = n >>> 0;
|
|
234
|
+
const target = ((1n << 64n) - 1n) / BigInt(d);
|
|
235
|
+
stopRequested = false;
|
|
236
|
+
|
|
237
|
+
const { w, ctx, compiled, seedPtr, regPtr, memPtr } =
|
|
238
|
+
getHashwxRuntime(hashwxModule);
|
|
239
|
+
|
|
240
|
+
const challenge = new Uint8Array(32);
|
|
241
|
+
for (let i = 0; i < 32; i++)
|
|
242
|
+
challenge[i] = parseInt(c.slice(i * 2, i * 2 + 2), 16);
|
|
243
|
+
const seedInput = new Uint8Array(40);
|
|
244
|
+
seedInput.set(challenge, 0);
|
|
245
|
+
const seedOut = new Uint8Array(32);
|
|
246
|
+
|
|
247
|
+
const t0 = performance.now();
|
|
248
|
+
let hashes = 0;
|
|
249
|
+
let lastYield = t0;
|
|
250
|
+
let lastReport = t0;
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
for (let block = workerIndex; ; block += workerCount) {
|
|
254
|
+
let rest = block;
|
|
255
|
+
for (let i = 0; i < 8; i++) {
|
|
256
|
+
seedInput[32 + i] = rest & 0xff;
|
|
257
|
+
rest = Math.floor(rest / 256);
|
|
258
|
+
}
|
|
259
|
+
sha256Into(seedInput, seedOut);
|
|
260
|
+
new Uint8Array(w.memory.buffer, seedPtr, 32).set(seedOut);
|
|
261
|
+
w.hashwx_make(ctx, seedPtr);
|
|
262
|
+
|
|
263
|
+
let side = null;
|
|
264
|
+
if (compiled) {
|
|
265
|
+
const codePtr = w.hashwx_module(ctx);
|
|
266
|
+
const codeSize = w.hashwx_module_size(ctx);
|
|
267
|
+
const bytes = new Uint8Array(
|
|
268
|
+
w.memory.buffer,
|
|
269
|
+
codePtr,
|
|
270
|
+
codeSize,
|
|
271
|
+
).slice();
|
|
272
|
+
side = new WebAssembly.Instance(new WebAssembly.Module(bytes), {
|
|
273
|
+
env: { memory: w.memory },
|
|
274
|
+
}).exports.exec;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const base = BigInt(block) * BigInt(noncesPerHash);
|
|
278
|
+
for (let k = 0; k < noncesPerHash; k++) {
|
|
279
|
+
const nonce = base + BigInt(k);
|
|
280
|
+
let hash;
|
|
281
|
+
if (compiled) {
|
|
282
|
+
w.hashwx_exec_begin(ctx, nonce);
|
|
283
|
+
side(regPtr, memPtr);
|
|
284
|
+
hash = BigInt.asUintN(64, w.hashwx_exec_final(ctx));
|
|
285
|
+
} else {
|
|
286
|
+
hash = BigInt.asUintN(64, w.hashwx_exec(ctx, nonce));
|
|
287
|
+
}
|
|
288
|
+
hashes++;
|
|
289
|
+
if (hash <= target) {
|
|
290
|
+
self.postMessage({
|
|
291
|
+
found: true,
|
|
292
|
+
nonce: nonce.toString(),
|
|
293
|
+
hashes,
|
|
294
|
+
compiled,
|
|
295
|
+
durationMs: (performance.now() - t0).toFixed(2),
|
|
296
|
+
});
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if ((hashes & (HASHWX_CLOCK_EVERY - 1)) === 0) {
|
|
300
|
+
const now = performance.now();
|
|
301
|
+
if (now - lastYield >= HASHWX_YIELD_MS) {
|
|
302
|
+
if (now - lastReport >= HASHWX_PROGRESS_MS) {
|
|
303
|
+
lastReport = now;
|
|
304
|
+
self.postMessage({ progress: hashes });
|
|
305
|
+
}
|
|
306
|
+
await macrotask();
|
|
307
|
+
lastYield = performance.now();
|
|
308
|
+
if (stopRequested) {
|
|
309
|
+
return self.postMessage({ found: false, error: "stopped" });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
} catch (error) {
|
|
316
|
+
hashwxRuntime = null;
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
if (
|
|
322
|
+
typeof WebAssembly !== "object" ||
|
|
323
|
+
typeof WebAssembly?.instantiate !== "function"
|
|
324
|
+
) {
|
|
325
|
+
wlog(
|
|
326
|
+
"warn",
|
|
327
|
+
"WebAssembly unavailable, using JS fallback solver (significantly slower)",
|
|
328
|
+
);
|
|
87
329
|
|
|
88
330
|
self.onmessage = async ({ data }) => {
|
|
331
|
+
if (data?.kind === "stop") {
|
|
332
|
+
stopRequested = true;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
89
335
|
if (data?.kind === "rsw") return solveRsw(data);
|
|
336
|
+
if (data?.kind === "hashwx") {
|
|
337
|
+
return self.postMessage({
|
|
338
|
+
found: false,
|
|
339
|
+
error: "hashwx requires WebAssembly",
|
|
340
|
+
});
|
|
341
|
+
}
|
|
90
342
|
return solveFallback({ salt: data.salt, target: data.target });
|
|
91
343
|
};
|
|
92
344
|
|
|
@@ -102,7 +354,10 @@
|
|
|
102
354
|
let cachedUint8ArrayMemory = null;
|
|
103
355
|
|
|
104
356
|
const getMemory = () => {
|
|
105
|
-
if (
|
|
357
|
+
if (
|
|
358
|
+
cachedUint8ArrayMemory === null ||
|
|
359
|
+
cachedUint8ArrayMemory.byteLength === 0
|
|
360
|
+
) {
|
|
106
361
|
cachedUint8ArrayMemory = new Uint8Array(wasm.memory.buffer);
|
|
107
362
|
}
|
|
108
363
|
return cachedUint8ArrayMemory;
|
|
@@ -164,33 +419,62 @@
|
|
|
164
419
|
if (wasm.__wbindgen_start) wasm.__wbindgen_start();
|
|
165
420
|
|
|
166
421
|
solve_pow_function = (salt, target) => {
|
|
167
|
-
const saltPtr = passStringToWasm(
|
|
422
|
+
const saltPtr = passStringToWasm(
|
|
423
|
+
salt,
|
|
424
|
+
wasm.__wbindgen_malloc,
|
|
425
|
+
wasm.__wbindgen_realloc,
|
|
426
|
+
);
|
|
168
427
|
const saltLen = WASM_VECTOR_LEN;
|
|
169
|
-
const targetPtr = passStringToWasm(
|
|
428
|
+
const targetPtr = passStringToWasm(
|
|
429
|
+
target,
|
|
430
|
+
wasm.__wbindgen_malloc,
|
|
431
|
+
wasm.__wbindgen_realloc,
|
|
432
|
+
);
|
|
170
433
|
const targetLen = WASM_VECTOR_LEN;
|
|
171
|
-
return BigInt.asUintN(
|
|
434
|
+
return BigInt.asUintN(
|
|
435
|
+
64,
|
|
436
|
+
wasm.solve_pow(saltPtr, saltLen, targetPtr, targetLen),
|
|
437
|
+
);
|
|
172
438
|
};
|
|
173
439
|
|
|
174
440
|
return true;
|
|
175
441
|
} catch (e) {
|
|
176
|
-
wlog("error","wasm init failed:", e.message || e);
|
|
442
|
+
wlog("error", "wasm init failed:", e.message || e);
|
|
177
443
|
return false;
|
|
178
444
|
}
|
|
179
445
|
};
|
|
180
446
|
|
|
181
447
|
self.onmessage = async ({ data }) => {
|
|
448
|
+
if (data?.kind === "stop") {
|
|
449
|
+
stopRequested = true;
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
182
452
|
if (data?.kind === "rsw") return solveRsw(data);
|
|
453
|
+
if (data?.kind === "hashwx") {
|
|
454
|
+
try {
|
|
455
|
+
return await solveHashwx(data);
|
|
456
|
+
} catch (error) {
|
|
457
|
+
wlog("error", "hashwx solver threw:", error.message || error);
|
|
458
|
+
return self.postMessage({
|
|
459
|
+
found: false,
|
|
460
|
+
error: error.message || String(error),
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
}
|
|
183
464
|
const { salt, target, wasmModule } = data;
|
|
184
|
-
if (
|
|
465
|
+
if (
|
|
466
|
+
wasmModule instanceof WebAssembly.Module &&
|
|
467
|
+
solve_pow_function === null
|
|
468
|
+
) {
|
|
185
469
|
const ok = initFromModule(wasmModule);
|
|
186
470
|
if (!ok) {
|
|
187
|
-
wlog("warn","wasm init failed, falling back to JS solver");
|
|
471
|
+
wlog("warn", "wasm init failed, falling back to JS solver");
|
|
188
472
|
return solveFallback({ salt, target });
|
|
189
473
|
}
|
|
190
474
|
}
|
|
191
475
|
|
|
192
476
|
if (solve_pow_function === null) {
|
|
193
|
-
wlog("warn","no wasm module provided, falling back to JS solver");
|
|
477
|
+
wlog("warn", "no wasm module provided, falling back to JS solver");
|
|
194
478
|
return solveFallback({ salt, target });
|
|
195
479
|
}
|
|
196
480
|
|
|
@@ -205,7 +489,7 @@
|
|
|
205
489
|
durationMs: (endTime - startTime).toFixed(2),
|
|
206
490
|
});
|
|
207
491
|
} catch (error) {
|
|
208
|
-
wlog("error","solve_pow threw:", error.message || error);
|
|
492
|
+
wlog("error", "solve_pow threw:", error.message || error);
|
|
209
493
|
|
|
210
494
|
self.postMessage({
|
|
211
495
|
found: false,
|