nano-pow 3.2.1 → 4.0.0
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/dist/bin/cli.js +2 -19
- package/dist/bin/server.js +175 -0
- package/dist/main.min.js +35 -61
- package/dist/types.d.ts +3 -3
- package/docs/index.js +38 -0
- package/package.json +4 -2
package/dist/bin/cli.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import * as fs from "node:fs/promises";
|
|
5
5
|
import * as readline from "node:readline/promises";
|
|
6
6
|
import * as puppeteer from "puppeteer";
|
|
7
|
+
import { cliHelp } from "../../docs/index.js";
|
|
7
8
|
const hashes = [];
|
|
8
9
|
const stdinErrors = [];
|
|
9
10
|
if (!process.stdin.isTTY) {
|
|
@@ -20,25 +21,7 @@ if (!process.stdin.isTTY) {
|
|
|
20
21
|
}
|
|
21
22
|
const args = process.argv.slice(2);
|
|
22
23
|
if (hashes.length === 0 && args.length === 0 || args.some((v) => v === "--help" || v === "-h")) {
|
|
23
|
-
console.log(
|
|
24
|
-
Generate work for BLOCKHASH, or multiple work values for BLOCKHASH(es)
|
|
25
|
-
BLOCKHASH is a 64-character hexadecimal string. Multiple blockhashes must be separated by whitespace or line breaks.
|
|
26
|
-
Prints a 16-character hexadecimal work value to standard output. If using --validate, prints 'true' or 'false' to standard output instead.
|
|
27
|
-
|
|
28
|
-
-h, --help show this dialog
|
|
29
|
-
-d, --debug enable additional logging output
|
|
30
|
-
-j, --json format output as JSON
|
|
31
|
-
-e, --effort=<value> increase demand on GPU processing
|
|
32
|
-
-t, --threshold=<value> override the minimum threshold value
|
|
33
|
-
-v, --validate=<value> check an existing work value instead of searching for one
|
|
34
|
-
|
|
35
|
-
If validating a nonce, it must be a 16-character hexadecimal value.
|
|
36
|
-
Effort must be a decimal number between 1-32.
|
|
37
|
-
Threshold must be a hexadecimal string between 0-FFFFFFFF.
|
|
38
|
-
|
|
39
|
-
Report bugs: <bug-nano-pow@zoso.dev>
|
|
40
|
-
Full documentation: <https://www.npmjs.com/package/nano-pow>
|
|
41
|
-
`);
|
|
24
|
+
console.log(cliHelp);
|
|
42
25
|
process.exit();
|
|
43
26
|
}
|
|
44
27
|
const inArgs = [];
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
3
|
+
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
import * as http from "node:http";
|
|
5
|
+
import * as fs from "node:fs/promises";
|
|
6
|
+
import * as puppeteer from "puppeteer";
|
|
7
|
+
import { serverHelp } from "../../docs/index.js";
|
|
8
|
+
const PORT = process.env.PORT || 3e3;
|
|
9
|
+
function log(...args) {
|
|
10
|
+
console.log(new Date(Date.now()).toLocaleString(), "NanoPow", args);
|
|
11
|
+
}
|
|
12
|
+
log("Starting server");
|
|
13
|
+
const NanoPow = await fs.readFile(new URL("../main.min.js", import.meta.url), "utf-8");
|
|
14
|
+
let browser;
|
|
15
|
+
let page;
|
|
16
|
+
async function work_generate(res, json) {
|
|
17
|
+
if (!/^[0-9A-Fa-f]{64}$/.test(json.hash ?? "")) {
|
|
18
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
19
|
+
res.end(JSON.stringify({ error: "Invalid hash. Must be a 64-character hex string." }));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (json.difficulty && !/^[1-9A-Fa-f][0-9A-Fa-f]{0,15}$/.test(json.difficulty)) {
|
|
23
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
24
|
+
res.end(JSON.stringify({ error: "Invalid difficulty. Must be a hexadecimal string between 1-FFFFFFFFFFFFFFFF." }));
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const result = await page.evaluate(async (args) => {
|
|
29
|
+
const options = {
|
|
30
|
+
debug: true
|
|
31
|
+
};
|
|
32
|
+
if (args.difficulty) options.threshold = BigInt(`0x${args.difficulty}`);
|
|
33
|
+
return await window.NanoPow.work_generate(args.hash, options);
|
|
34
|
+
}, json);
|
|
35
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
36
|
+
res.end(JSON.stringify(result));
|
|
37
|
+
} catch (err) {
|
|
38
|
+
log("work_generate error:", err);
|
|
39
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
40
|
+
res.end(JSON.stringify({ error: "work_generate failed" }));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function work_validate(res, json) {
|
|
44
|
+
if (!/^[0-9A-Fa-f]{64}$/.test(json.hash ?? "")) {
|
|
45
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
46
|
+
res.end(JSON.stringify({ error: "Invalid hash. Must be a 64-character hex string." }));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (json.difficulty && !/^[1-9A-Fa-f][0-9A-Fa-f]{0,15}$/.test(json.difficulty)) {
|
|
50
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
51
|
+
res.end(JSON.stringify({ error: "Invalid difficulty. Must be a hexadecimal string between 1-FFFFFFFFFFFFFFFF." }));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (!/^[0-9A-Fa-f]{16}$/.test(json.work ?? "")) {
|
|
55
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
56
|
+
res.end(JSON.stringify({ error: "Invalid work. Must be a 16-character hex string." }));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const result = await page.evaluate(async (args) => {
|
|
61
|
+
const options = {
|
|
62
|
+
debug: true
|
|
63
|
+
};
|
|
64
|
+
if (args.difficulty) options.threshold = BigInt(`0x${args.difficulty}`);
|
|
65
|
+
return await window.NanoPow.work_validate(args.work, args.hash, options);
|
|
66
|
+
}, json);
|
|
67
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
68
|
+
res.end(JSON.stringify(result));
|
|
69
|
+
} catch (err) {
|
|
70
|
+
log("work_validate error:", err);
|
|
71
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
72
|
+
res.end(JSON.stringify({ error: "work_validate failed" }));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
(async () => {
|
|
76
|
+
browser = await puppeteer.launch({
|
|
77
|
+
headless: true,
|
|
78
|
+
args: [
|
|
79
|
+
"--headless=new",
|
|
80
|
+
"--use-angle=vulkan",
|
|
81
|
+
"--enable-features=Vulkan",
|
|
82
|
+
"--disable-vulkan-surface",
|
|
83
|
+
"--enable-unsafe-webgpu"
|
|
84
|
+
]
|
|
85
|
+
});
|
|
86
|
+
page = await browser.newPage();
|
|
87
|
+
page.on("console", (msg) => {
|
|
88
|
+
log(msg.text());
|
|
89
|
+
});
|
|
90
|
+
await fs.writeFile(`${import.meta.dirname}/server.html`, "");
|
|
91
|
+
await page.goto(import.meta.resolve("./server.html"));
|
|
92
|
+
await page.waitForFunction(async () => {
|
|
93
|
+
return await navigator.gpu.requestAdapter();
|
|
94
|
+
});
|
|
95
|
+
const inject = `${NanoPow};window.NanoPow=NanoPow;`;
|
|
96
|
+
const hash = await crypto.subtle.digest("SHA-256", Buffer.from(inject, "utf-8"));
|
|
97
|
+
const src = `sha256-${Buffer.from(hash).toString("base64")}`;
|
|
98
|
+
await page.setContent(`
|
|
99
|
+
<!DOCTYPE html>
|
|
100
|
+
<head>
|
|
101
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'none'; form-action 'none'; script-src '${src}';">
|
|
102
|
+
<script type="module">${inject}</script>
|
|
103
|
+
</head>
|
|
104
|
+
</html>
|
|
105
|
+
`);
|
|
106
|
+
await fs.unlink(`${import.meta.dirname}/server.html`);
|
|
107
|
+
log("Puppeteer initialized");
|
|
108
|
+
const server = http.createServer(async (req, res) => {
|
|
109
|
+
let data = [];
|
|
110
|
+
if (req.method === "POST") {
|
|
111
|
+
req.on("data", (chunk) => {
|
|
112
|
+
data.push(chunk);
|
|
113
|
+
});
|
|
114
|
+
req.on("end", async () => {
|
|
115
|
+
let json;
|
|
116
|
+
try {
|
|
117
|
+
json = JSON.parse(Buffer.concat(data).toString());
|
|
118
|
+
} catch (err) {
|
|
119
|
+
log("JSON.parse error:", err);
|
|
120
|
+
log("Failed JSON:", json);
|
|
121
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
122
|
+
res.end(JSON.stringify({ error: "Invalid data." }));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
switch (json.action) {
|
|
126
|
+
case "work_generate": {
|
|
127
|
+
await work_generate(res, json);
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case "work_validate": {
|
|
131
|
+
await work_validate(res, json);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
default: {
|
|
135
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
136
|
+
res.end(JSON.stringify({ error: `Invalid data.` }));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
143
|
+
res.end(serverHelp);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
server.on("error", (e) => {
|
|
147
|
+
log("Server error", e);
|
|
148
|
+
try {
|
|
149
|
+
shutdown();
|
|
150
|
+
} catch (err) {
|
|
151
|
+
log("Failed to shut down", err);
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
server.listen(PORT, () => {
|
|
156
|
+
process.title = "NanoPow Server";
|
|
157
|
+
log(`Server process ${process.pid} running at http://localhost:${PORT}/`);
|
|
158
|
+
});
|
|
159
|
+
function shutdown() {
|
|
160
|
+
log("Shutdown signal received");
|
|
161
|
+
const kill = setTimeout(() => {
|
|
162
|
+
log("Server unresponsive, forcefully stopped");
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}, 1e4);
|
|
165
|
+
server.close(async () => {
|
|
166
|
+
await page?.close();
|
|
167
|
+
await browser?.close();
|
|
168
|
+
clearTimeout(kill);
|
|
169
|
+
log("Server stopped");
|
|
170
|
+
process.exit(0);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
process.on("SIGINT", shutdown);
|
|
174
|
+
process.on("SIGTERM", shutdown);
|
|
175
|
+
})();
|
package/dist/main.min.js
CHANGED
|
@@ -345,22 +345,10 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
345
345
|
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
346
346
|
*
|
|
347
347
|
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
348
|
-
* @param {NanoPowOptions} options - Used to configure search execution
|
|
349
|
-
*/
|
|
350
|
-
static async search(hash, options) {
|
|
351
|
-
if (options?.threshold != null) {
|
|
352
|
-
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
353
|
-
}
|
|
354
|
-
const result = await this.work_generate(hash, options);
|
|
355
|
-
return result.work;
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
359
|
-
*
|
|
360
|
-
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
361
348
|
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
362
349
|
*/
|
|
363
350
|
static async work_generate(hash, options) {
|
|
351
|
+
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
|
|
364
352
|
if (this.#busy) {
|
|
365
353
|
console.log("NanoPowGl is busy. Retrying search...");
|
|
366
354
|
return new Promise((resolve) => {
|
|
@@ -371,11 +359,17 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
371
359
|
});
|
|
372
360
|
}
|
|
373
361
|
this.#busy = true;
|
|
374
|
-
if (
|
|
362
|
+
if (typeof options?.threshold === "string") {
|
|
363
|
+
try {
|
|
364
|
+
options.threshold = BigInt(`0x${options.threshold}`);
|
|
365
|
+
} catch (err) {
|
|
366
|
+
throw new TypeError(`Invalid threshold ${options.threshold}`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
375
369
|
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
376
370
|
const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 32 ? this.#cores : options.effort;
|
|
377
371
|
this.#debug = !!options?.debug;
|
|
378
|
-
if (this.#debug) console.log("NanoPowGl.
|
|
372
|
+
if (this.#debug) console.log("NanoPowGl.work_generate()");
|
|
379
373
|
if (this.#debug) console.log("blockhash", hash);
|
|
380
374
|
if (this.#debug) console.log("search options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
381
375
|
if (this.#WORKLOAD !== 256 * effort) {
|
|
@@ -436,21 +430,9 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
436
430
|
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
437
431
|
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
438
432
|
*/
|
|
439
|
-
static async validate(work, hash, options) {
|
|
440
|
-
if (options?.threshold != null) {
|
|
441
|
-
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
442
|
-
}
|
|
443
|
-
const result = await this.work_validate(work, hash, options);
|
|
444
|
-
return options?.threshold != null ? result.valid === "1" : result.valid_all === "1";
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
448
|
-
*
|
|
449
|
-
* @param {string} work - Hexadecimal proof-of-work value to validate
|
|
450
|
-
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
451
|
-
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
452
|
-
*/
|
|
453
433
|
static async work_validate(work, hash, options) {
|
|
434
|
+
if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new Error(`Invalid work ${work}`);
|
|
435
|
+
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new Error(`Invalid hash ${hash}`);
|
|
454
436
|
if (this.#busy) {
|
|
455
437
|
console.log("NanoPowGl is busy. Retrying validate...");
|
|
456
438
|
return new Promise((resolve) => {
|
|
@@ -461,11 +443,16 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
461
443
|
});
|
|
462
444
|
}
|
|
463
445
|
this.#busy = true;
|
|
464
|
-
if (
|
|
465
|
-
|
|
446
|
+
if (typeof options?.threshold === "string") {
|
|
447
|
+
try {
|
|
448
|
+
options.threshold = BigInt(`0x${options.threshold}`);
|
|
449
|
+
} catch (err) {
|
|
450
|
+
throw new TypeError(`Invalid threshold ${options.threshold}`);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
466
453
|
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
467
454
|
this.#debug = !!options?.debug;
|
|
468
|
-
if (this.#debug) console.log("NanoPowGl.
|
|
455
|
+
if (this.#debug) console.log("NanoPowGl.work_validate()");
|
|
469
456
|
if (this.#debug) console.log("blockhash", hash);
|
|
470
457
|
if (this.#debug) console.log("validate options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
471
458
|
if (_NanoPowGl.#gl == null) throw new Error("WebGL 2 is required");
|
|
@@ -706,19 +693,6 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
706
693
|
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
707
694
|
* @param {NanoPowOptions} options - Used to configure search execution
|
|
708
695
|
*/
|
|
709
|
-
static async search(hash, options) {
|
|
710
|
-
if (options?.threshold != null) {
|
|
711
|
-
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
712
|
-
}
|
|
713
|
-
const result = await this.work_generate(hash, options);
|
|
714
|
-
return result.work;
|
|
715
|
-
}
|
|
716
|
-
/**
|
|
717
|
-
* Finds a nonce that satisfies the Nano proof-of-work requirements.
|
|
718
|
-
*
|
|
719
|
-
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
720
|
-
* @param {NanoPowOptions} options - Used to configure search execution
|
|
721
|
-
*/
|
|
722
696
|
static async work_generate(hash, options) {
|
|
723
697
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
|
|
724
698
|
if (this.#busy) {
|
|
@@ -731,10 +705,17 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
731
705
|
});
|
|
732
706
|
}
|
|
733
707
|
this.#busy = true;
|
|
708
|
+
if (typeof options?.threshold === "string") {
|
|
709
|
+
try {
|
|
710
|
+
options.threshold = BigInt(`0x${options.threshold}`);
|
|
711
|
+
} catch (err) {
|
|
712
|
+
throw new TypeError(`Invalid threshold ${options.threshold}`);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
734
715
|
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
735
716
|
const effort = typeof options?.effort !== "number" || options.effort < 1 || options.effort > 32 ? 2048 : options.effort * 256;
|
|
736
717
|
this.#debug = !!options?.debug;
|
|
737
|
-
if (this.#debug) console.log("NanoPowGpu.
|
|
718
|
+
if (this.#debug) console.log("NanoPowGpu.work_generate()");
|
|
738
719
|
if (this.#debug) console.log("blockhash", hash);
|
|
739
720
|
if (this.#debug) console.log("search options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
740
721
|
let loads = 0;
|
|
@@ -780,20 +761,6 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
780
761
|
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
781
762
|
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
782
763
|
*/
|
|
783
|
-
static async validate(work, hash, options) {
|
|
784
|
-
if (options?.threshold != null) {
|
|
785
|
-
options.threshold = BigInt(`0x${options.threshold.toString(16) ?? "0"}00000000`);
|
|
786
|
-
}
|
|
787
|
-
const result = await this.work_validate(work, hash, options);
|
|
788
|
-
return options?.threshold != null ? result.valid === "1" : result.valid_all === "1";
|
|
789
|
-
}
|
|
790
|
-
/**
|
|
791
|
-
* Validates that a nonce satisfies Nano proof-of-work requirements.
|
|
792
|
-
*
|
|
793
|
-
* @param {string} work - Hexadecimal proof-of-work value to validate
|
|
794
|
-
* @param {string} hash - Hexadecimal hash of previous block, or public key for new accounts
|
|
795
|
-
* @param {NanoPowOptions} options - Options used to configure search execution
|
|
796
|
-
*/
|
|
797
764
|
static async work_validate(work, hash, options) {
|
|
798
765
|
if (!/^[A-Fa-f0-9]{16}$/.test(work)) throw new TypeError(`Invalid work ${work}`);
|
|
799
766
|
if (!/^[A-Fa-f0-9]{64}$/.test(hash)) throw new TypeError(`Invalid hash ${hash}`);
|
|
@@ -807,9 +774,16 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
807
774
|
});
|
|
808
775
|
}
|
|
809
776
|
this.#busy = true;
|
|
777
|
+
if (typeof options?.threshold === "string") {
|
|
778
|
+
try {
|
|
779
|
+
options.threshold = BigInt(`0x${options.threshold}`);
|
|
780
|
+
} catch (err) {
|
|
781
|
+
throw new TypeError(`Invalid threshold ${options.threshold}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
810
784
|
const threshold = typeof options?.threshold !== "bigint" || options.threshold < 1n || options.threshold > 0xffffffffffffffffn ? 0xfffffff800000000n : options.threshold;
|
|
811
785
|
this.#debug = !!options?.debug;
|
|
812
|
-
if (this.#debug) console.log("NanoPowGpu.
|
|
786
|
+
if (this.#debug) console.log("NanoPowGpu.work_validate()");
|
|
813
787
|
if (this.#debug) console.log("blockhash", hash);
|
|
814
788
|
if (this.#debug) console.log("validate options", JSON.stringify(options, (k, v) => typeof v === "bigint" ? v.toString(16) : v));
|
|
815
789
|
let loads = 0;
|
package/dist/types.d.ts
CHANGED
|
@@ -91,12 +91,12 @@ export type FBO = {
|
|
|
91
91
|
*
|
|
92
92
|
* @param {boolean} [debug=false] - Enables additional debug logging to the console. Default: false
|
|
93
93
|
* @param {number} [effort=0x8] - Multiplier for dispatching work search. Larger values are not necessarily better since they can quickly overwhelm the GPU. Ignored when validating. Default: 0x8
|
|
94
|
-
* @param {
|
|
94
|
+
* @param {bigint|string} [threshold=0xfffffff800000000] - Minimum value result of `BLAKE2b(nonce||blockhash)`. Default: 0xFFFFFFF800000000
|
|
95
95
|
*/
|
|
96
96
|
export type NanoPowOptions = {
|
|
97
97
|
debug?: boolean
|
|
98
98
|
effort?: number
|
|
99
|
-
threshold?: bigint |
|
|
99
|
+
threshold?: bigint | string
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/**
|
|
@@ -105,7 +105,7 @@ export type NanoPowOptions = {
|
|
|
105
105
|
export declare class NanoPowGl {
|
|
106
106
|
#private
|
|
107
107
|
/** Drawing buffer width in pixels. */
|
|
108
|
-
static get size (): number
|
|
108
|
+
static get size (): number
|
|
109
109
|
/**
|
|
110
110
|
* Constructs canvas, gets WebGL context, initializes buffers, and compiles
|
|
111
111
|
* shaders.
|
package/docs/index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
//! SPDX-FileCopyrightText: 2025 Chris Duncan <chris@zoso.dev>
|
|
2
|
+
//! SPDX-License-Identifier: GPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
export const cliHelp = `Usage: nano-pow [OPTION]... BLOCKHASH...
|
|
5
|
+
Generate work for BLOCKHASH, or multiple work values for BLOCKHASH(es)
|
|
6
|
+
BLOCKHASH is a 64-character hexadecimal string. Multiple blockhashes must be separated by whitespace or line breaks.
|
|
7
|
+
Prints a 16-character hexadecimal work value to standard output. If using --validate, prints 'true' or 'false' to standard output instead.
|
|
8
|
+
|
|
9
|
+
-h, --help show this dialog
|
|
10
|
+
-d, --debug enable additional logging output
|
|
11
|
+
-j, --json format output as JSON
|
|
12
|
+
-e, --effort=<value> increase demand on GPU processing
|
|
13
|
+
-t, --threshold=<value> override the minimum threshold value
|
|
14
|
+
-v, --validate=<value> check an existing work value instead of searching for one
|
|
15
|
+
|
|
16
|
+
If validating a nonce, it must be a 16-character hexadecimal value.
|
|
17
|
+
Effort must be a decimal number between 1-32.
|
|
18
|
+
Threshold must be a hexadecimal string between 0-FFFFFFFF.
|
|
19
|
+
|
|
20
|
+
Report bugs: <bug-nano-pow@zoso.dev>
|
|
21
|
+
Full documentation: <https://www.npmjs.com/package/nano-pow>
|
|
22
|
+
`
|
|
23
|
+
|
|
24
|
+
export const serverHelp = `Usage: Send POST request to server URL to generate or validate Nano proof-of-work
|
|
25
|
+
|
|
26
|
+
Generate work for a BLOCKHASH with an optional DIFFICULTY:
|
|
27
|
+
curl -d '{ action: "work_generate", hash: BLOCKHASH, difficulty?: DIFFICULTY }'
|
|
28
|
+
|
|
29
|
+
Validate WORK previously calculated for a BLOCKHASH with an optional DIFFICULTY:
|
|
30
|
+
curl -d '{ action: "work_validate", work: WORK, hash: BLOCKHASH, difficulty?: DIFFICULTY }'
|
|
31
|
+
|
|
32
|
+
BLOCKHASH is a 64-character hexadecimal string.
|
|
33
|
+
WORK is 16-character hexadecimal string.
|
|
34
|
+
DIFFICULTY is a 16-character hexadecimal string (default: FFFFFFF800000000)
|
|
35
|
+
|
|
36
|
+
Report bugs: <bug-nano-pow@zoso.dev>
|
|
37
|
+
Full documentation: <https://www.npmjs.com/package/nano-pow>
|
|
38
|
+
`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nano-pow",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "Proof-of-work generation and validation with WebGPU/WebGL for Nano cryptocurrency.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nemo",
|
|
@@ -45,7 +45,9 @@
|
|
|
45
45
|
"url": "git+https://zoso.dev/nano-pow.git"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
|
-
"build": "rm -rf {dist,types} && tsc && node esbuild.mjs"
|
|
48
|
+
"build": "rm -rf {dist,types} && tsc && node esbuild.mjs",
|
|
49
|
+
"start": "mkdir -p logs; node ./dist/bin/server.js > ./logs/nano-pow-server-$(date +%s).log 2>&1 & echo $! > server.pid",
|
|
50
|
+
"test": "./test/script.sh"
|
|
49
51
|
},
|
|
50
52
|
"devDependencies": {
|
|
51
53
|
"@types/node": "^22.13.11",
|