nano-rspow-python 0.12.0__tar.gz → 0.13.0__tar.gz
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.
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/Cargo.lock +36 -5
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/Cargo.toml +1 -1
- nano_rspow_python-0.13.0/PKG-INFO +83 -0
- nano_rspow_python-0.13.0/README.md +58 -0
- nano_rspow_python-0.13.0/nano-rspow/README.md +83 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/lib.rs +3 -3
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow-python/Cargo.toml +1 -0
- nano_rspow_python-0.13.0/nano-rspow-python/README.md +58 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow-python/nano_rspow.pyi +2 -2
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow-python/src/lib.rs +4 -4
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow-python/tests/test_pow.py +1 -1
- nano_rspow_python-0.13.0/nano-rspow-python/uv.lock +227 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/pyproject.toml +19 -3
- nano_rspow_python-0.12.0/PKG-INFO +0 -13
- nano_rspow_python-0.12.0/nano-rspow/README.md +0 -80
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/Cargo.toml +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/benches/pow_benchmark.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/cpu.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/difficulty.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/opencl_backend/mod.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/opencl_backend/pow.cl +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/thresholds.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/types.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/wgpu_backend/mod.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/wgpu_backend/pow.wgsl +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow/src/wgpu_shared.rs +0 -0
- {nano_rspow_python-0.12.0 → nano_rspow_python-0.13.0}/nano-rspow-python/build.rs +0 -0
|
@@ -94,6 +94,12 @@ version = "0.7.6"
|
|
|
94
94
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
95
95
|
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
|
96
96
|
|
|
97
|
+
[[package]]
|
|
98
|
+
name = "ascii"
|
|
99
|
+
version = "1.1.0"
|
|
100
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
101
|
+
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
|
|
102
|
+
|
|
97
103
|
[[package]]
|
|
98
104
|
name = "ash"
|
|
99
105
|
version = "0.38.0+1.3.281"
|
|
@@ -200,6 +206,12 @@ version = "0.2.1"
|
|
|
200
206
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
201
207
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|
202
208
|
|
|
209
|
+
[[package]]
|
|
210
|
+
name = "chunked_transfer"
|
|
211
|
+
version = "1.5.0"
|
|
212
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
213
|
+
checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901"
|
|
214
|
+
|
|
203
215
|
[[package]]
|
|
204
216
|
name = "ciborium"
|
|
205
217
|
version = "0.2.2"
|
|
@@ -608,6 +620,12 @@ version = "0.2.1"
|
|
|
608
620
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
609
621
|
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
|
|
610
622
|
|
|
623
|
+
[[package]]
|
|
624
|
+
name = "httpdate"
|
|
625
|
+
version = "1.0.3"
|
|
626
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
627
|
+
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|
628
|
+
|
|
611
629
|
[[package]]
|
|
612
630
|
name = "indexmap"
|
|
613
631
|
version = "2.14.0"
|
|
@@ -739,7 +757,7 @@ dependencies = [
|
|
|
739
757
|
|
|
740
758
|
[[package]]
|
|
741
759
|
name = "nano-rspow"
|
|
742
|
-
version = "0.
|
|
760
|
+
version = "0.13.0"
|
|
743
761
|
dependencies = [
|
|
744
762
|
"blake2b_simd",
|
|
745
763
|
"bytemuck",
|
|
@@ -755,18 +773,19 @@ dependencies = [
|
|
|
755
773
|
|
|
756
774
|
[[package]]
|
|
757
775
|
name = "nano-rspow-cli"
|
|
758
|
-
version = "0.
|
|
776
|
+
version = "0.13.0"
|
|
759
777
|
dependencies = [
|
|
760
778
|
"clap",
|
|
761
779
|
"hex",
|
|
762
780
|
"nano-rspow",
|
|
763
781
|
"serde",
|
|
764
782
|
"serde_json",
|
|
783
|
+
"tiny_http",
|
|
765
784
|
]
|
|
766
785
|
|
|
767
786
|
[[package]]
|
|
768
787
|
name = "nano-rspow-node"
|
|
769
|
-
version = "0.
|
|
788
|
+
version = "0.13.0"
|
|
770
789
|
dependencies = [
|
|
771
790
|
"hex",
|
|
772
791
|
"nano-rspow",
|
|
@@ -778,7 +797,7 @@ dependencies = [
|
|
|
778
797
|
|
|
779
798
|
[[package]]
|
|
780
799
|
name = "nano-rspow-python"
|
|
781
|
-
version = "0.
|
|
800
|
+
version = "0.13.0"
|
|
782
801
|
dependencies = [
|
|
783
802
|
"hex",
|
|
784
803
|
"nano-rspow",
|
|
@@ -787,7 +806,7 @@ dependencies = [
|
|
|
787
806
|
|
|
788
807
|
[[package]]
|
|
789
808
|
name = "nano-rspow-web"
|
|
790
|
-
version = "0.
|
|
809
|
+
version = "0.13.0"
|
|
791
810
|
dependencies = [
|
|
792
811
|
"bytemuck",
|
|
793
812
|
"getrandom",
|
|
@@ -1513,6 +1532,18 @@ dependencies = [
|
|
|
1513
1532
|
"syn",
|
|
1514
1533
|
]
|
|
1515
1534
|
|
|
1535
|
+
[[package]]
|
|
1536
|
+
name = "tiny_http"
|
|
1537
|
+
version = "0.12.0"
|
|
1538
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1539
|
+
checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
|
|
1540
|
+
dependencies = [
|
|
1541
|
+
"ascii",
|
|
1542
|
+
"chunked_transfer",
|
|
1543
|
+
"httpdate",
|
|
1544
|
+
"log",
|
|
1545
|
+
]
|
|
1546
|
+
|
|
1516
1547
|
[[package]]
|
|
1517
1548
|
name = "tinytemplate"
|
|
1518
1549
|
version = "1.2.1"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nano-rspow-python
|
|
3
|
+
Version: 0.13.0
|
|
4
|
+
Classifier: Programming Language :: Python :: 3
|
|
5
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
6
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
12
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
13
|
+
Classifier: Programming Language :: Rust
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Summary: Hybrid CPU/GPU Nano (XNO) Proof of Work library — Python bindings.
|
|
16
|
+
Keywords: nano,xno,proof-of-work,blake2b,gpu
|
|
17
|
+
Author-email: Conny Brunnkvist <cbrunnkvist@gmail.com>
|
|
18
|
+
License-Expression: MIT
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
21
|
+
Project-URL: Homepage, https://github.com/CasualSecurityInc/nano-rspow
|
|
22
|
+
Project-URL: Issues, https://github.com/CasualSecurityInc/nano-rspow/issues
|
|
23
|
+
Project-URL: Repository, https://github.com/CasualSecurityInc/nano-rspow
|
|
24
|
+
|
|
25
|
+
# nano-rspow-python
|
|
26
|
+
|
|
27
|
+
Native Nano (XNO) proof-of-work bindings for Python. The extension selects an available GPU backend when possible and otherwise uses the CPU backend. `generate_work` releases the Python GIL while it searches.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install nano-rspow-python
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import nano_rspow
|
|
39
|
+
from nano_rspow import WorkType
|
|
40
|
+
|
|
41
|
+
root = "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
|
|
42
|
+
result = nano_rspow.generate_work(root, WorkType.Send)
|
|
43
|
+
|
|
44
|
+
print(result.nonce_hex)
|
|
45
|
+
assert result.is_valid
|
|
46
|
+
assert nano_rspow.validate_work(root, result.nonce_hex, WorkType.Send)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## API reference
|
|
50
|
+
|
|
51
|
+
### `generate_work(hash_hex, work_type) -> WorkResult`
|
|
52
|
+
|
|
53
|
+
Generates work for a 32-byte hexadecimal block root. Raises `ValueError` for invalid hexadecimal input or a root that is not 32 bytes. Raises `RuntimeError` if generation does not return a result.
|
|
54
|
+
|
|
55
|
+
### `validate_work(hash_hex, work_hex, work_type) -> bool`
|
|
56
|
+
|
|
57
|
+
Tests a hexadecimal nonce against a block root and the threshold selected by `work_type`. Raises `ValueError` for invalid input.
|
|
58
|
+
|
|
59
|
+
### `compute_difficulty(hash_hex, nonce_hex) -> str`
|
|
60
|
+
|
|
61
|
+
Returns the raw difficulty as a 16-character lowercase hexadecimal string. Raises `ValueError` for invalid input.
|
|
62
|
+
|
|
63
|
+
### `backend_name() -> str`
|
|
64
|
+
|
|
65
|
+
Returns the selected backend name, such as `cpu`, `wgpu`, or `opencl`.
|
|
66
|
+
|
|
67
|
+
### `WorkType`
|
|
68
|
+
|
|
69
|
+
| Value | Use |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| `Send` | Epoch 2 send and change blocks |
|
|
72
|
+
| `Receive` | Epoch 2 receive blocks |
|
|
73
|
+
| `LegacyEpoch1` | Historical epoch-1 validation only |
|
|
74
|
+
| `Epoch1` | Compatibility alias for `LegacyEpoch1` |
|
|
75
|
+
|
|
76
|
+
### `WorkResult`
|
|
77
|
+
|
|
78
|
+
`generate_work` returns a read-only result with `nonce_hex`, `difficulty_hex`, `is_valid`, and `multiplier` properties.
|
|
79
|
+
|
|
80
|
+
### `thresholds`
|
|
81
|
+
|
|
82
|
+
The `nano_rspow.thresholds` submodule provides `EPOCH2_SEND`, `EPOCH2_RECEIVE`, `LEGACY_EPOCH1`, `EPOCH1`, `BETA_LEGACY_EPOCH1`, `BETA_EPOCH1`, `DEV`, and `BASE`.
|
|
83
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# nano-rspow-python
|
|
2
|
+
|
|
3
|
+
Native Nano (XNO) proof-of-work bindings for Python. The extension selects an available GPU backend when possible and otherwise uses the CPU backend. `generate_work` releases the Python GIL while it searches.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install nano-rspow-python
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import nano_rspow
|
|
15
|
+
from nano_rspow import WorkType
|
|
16
|
+
|
|
17
|
+
root = "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
|
|
18
|
+
result = nano_rspow.generate_work(root, WorkType.Send)
|
|
19
|
+
|
|
20
|
+
print(result.nonce_hex)
|
|
21
|
+
assert result.is_valid
|
|
22
|
+
assert nano_rspow.validate_work(root, result.nonce_hex, WorkType.Send)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API reference
|
|
26
|
+
|
|
27
|
+
### `generate_work(hash_hex, work_type) -> WorkResult`
|
|
28
|
+
|
|
29
|
+
Generates work for a 32-byte hexadecimal block root. Raises `ValueError` for invalid hexadecimal input or a root that is not 32 bytes. Raises `RuntimeError` if generation does not return a result.
|
|
30
|
+
|
|
31
|
+
### `validate_work(hash_hex, work_hex, work_type) -> bool`
|
|
32
|
+
|
|
33
|
+
Tests a hexadecimal nonce against a block root and the threshold selected by `work_type`. Raises `ValueError` for invalid input.
|
|
34
|
+
|
|
35
|
+
### `compute_difficulty(hash_hex, nonce_hex) -> str`
|
|
36
|
+
|
|
37
|
+
Returns the raw difficulty as a 16-character lowercase hexadecimal string. Raises `ValueError` for invalid input.
|
|
38
|
+
|
|
39
|
+
### `backend_name() -> str`
|
|
40
|
+
|
|
41
|
+
Returns the selected backend name, such as `cpu`, `wgpu`, or `opencl`.
|
|
42
|
+
|
|
43
|
+
### `WorkType`
|
|
44
|
+
|
|
45
|
+
| Value | Use |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `Send` | Epoch 2 send and change blocks |
|
|
48
|
+
| `Receive` | Epoch 2 receive blocks |
|
|
49
|
+
| `LegacyEpoch1` | Historical epoch-1 validation only |
|
|
50
|
+
| `Epoch1` | Compatibility alias for `LegacyEpoch1` |
|
|
51
|
+
|
|
52
|
+
### `WorkResult`
|
|
53
|
+
|
|
54
|
+
`generate_work` returns a read-only result with `nonce_hex`, `difficulty_hex`, `is_valid`, and `multiplier` properties.
|
|
55
|
+
|
|
56
|
+
### `thresholds`
|
|
57
|
+
|
|
58
|
+
The `nano_rspow.thresholds` submodule provides `EPOCH2_SEND`, `EPOCH2_RECEIVE`, `LEGACY_EPOCH1`, `EPOCH1`, `BETA_LEGACY_EPOCH1`, `BETA_EPOCH1`, `DEV`, and `BASE`.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# nano-rspow
|
|
2
|
+
|
|
3
|
+
nano-rspow generates and validates [Nano](https://www.nano.org) proof of work on CPU and supported GPU backends. The workspace contains Rust, CLI, Node.js, Python, and browser WebAssembly packages.
|
|
4
|
+
|
|
5
|
+
The native core selects an available GPU backend when possible and otherwise uses its multi-threaded CPU backend. The browser package tries WebGPU, then falls back to single-threaded WebAssembly CPU execution.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🎯 Who is this for?
|
|
10
|
+
|
|
11
|
+
* **Exchange and wallet integrators** that need in-process work generation.
|
|
12
|
+
* **Server-side developers** using native Node.js or Python bindings.
|
|
13
|
+
* **Web developers** that need browser WebAssembly with an optional WebGPU path.
|
|
14
|
+
* **Node operators** that need a CLI to generate, validate, or benchmark work.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## ⚡ Quick Start
|
|
19
|
+
|
|
20
|
+
### 1. Standalone CLI
|
|
21
|
+
Install from crates.io (requires a Rust toolchain):
|
|
22
|
+
```bash
|
|
23
|
+
cargo install nano-rspow-cli
|
|
24
|
+
nano-rspow benchmark --count 10
|
|
25
|
+
|
|
26
|
+
# Run a loopback Nano work peer on 127.0.0.1:7076
|
|
27
|
+
nano-rspow serve
|
|
28
|
+
```
|
|
29
|
+
Alternatively, build from this repository:
|
|
30
|
+
```bash
|
|
31
|
+
cargo build -p nano-rspow-cli --release
|
|
32
|
+
./target/release/nano-rspow benchmark --count 10
|
|
33
|
+
```
|
|
34
|
+
Or use `cargo run -p nano-rspow-cli -- <args>` to build and execute in one step.
|
|
35
|
+
|
|
36
|
+
### 2. Node.js (Programmatic API)
|
|
37
|
+
Use the native bindings for in-process PoW generation:
|
|
38
|
+
```bash
|
|
39
|
+
npm install nano-rspow-node
|
|
40
|
+
```
|
|
41
|
+
See the [nano-rspow-node README](https://github.com/CasualSecurityInc/nano-rspow/blob/HEAD/nano-rspow-node/README.md) for API usage.
|
|
42
|
+
|
|
43
|
+
### 3. Interactive Web Dashboard
|
|
44
|
+
Build and open the self-contained browser dashboard. It tests WebGPU and a Web Worker CPU fallback:
|
|
45
|
+
```bash
|
|
46
|
+
cargo benchmark-web
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 📦 Documentation & Release Channels
|
|
52
|
+
|
|
53
|
+
Below is the directory mapping for each target, along with their primary release registries:
|
|
54
|
+
|
|
55
|
+
| Environment | Documentation Link | Latest Releases & Authoritative Registries |
|
|
56
|
+
| :--- | :--- | :--- |
|
|
57
|
+
| **Rust (Core)** | [crate API documentation](nano-rspow/src/lib.rs) | [GitHub Releases](https://github.com/CasualSecurityInc/nano-rspow/releases) |
|
|
58
|
+
| **Node.js & TS** | [nano-rspow-node README](https://github.com/CasualSecurityInc/nano-rspow/blob/HEAD/nano-rspow-node/README.md) | [Public NPM package](https://www.npmjs.com/package/nano-rspow-node) |
|
|
59
|
+
| **Python** | [nano-rspow-python README](nano-rspow-python/README.md) | [PyPI (pip)](https://pypi.org/project/nano-rspow-python/) |
|
|
60
|
+
| **Web (WASM / WebGPU)** | [nano-rspow-web/README.md](nano-rspow-web/README.md) | [Public NPM package](https://www.npmjs.com/package/nano-rspow-web) + [🎛️ Demo](https://csi.ninzin.net/nano-rspow/) |
|
|
61
|
+
| **CLI Tool** | [nano-rspow-cli README](nano-rspow-cli/README.md) | [crates.io](https://crates.io/crates/nano-rspow-cli) · [GitHub Releases](https://github.com/CasualSecurityInc/nano-rspow/releases) |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 🗂️ Repository Layout
|
|
66
|
+
|
|
67
|
+
This monorepo is organized into specialized workspaces to deliver native performance across all environments:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
.
|
|
71
|
+
├── .cargo/ # Target-specific build configurations and cargo aliases
|
|
72
|
+
├── nano-rspow/ # Core Rust library containing cryptographic Blake2b logic & backends
|
|
73
|
+
├── nano-rspow-cli/ # Standalone CLI binary for hardware benchmarking & generation
|
|
74
|
+
├── nano-rspow-node/ # High-performance Node.js & TypeScript native bindings (N-API)
|
|
75
|
+
├── nano-rspow-python/ # Native PyO3 bindings for Python environments
|
|
76
|
+
└── nano-rspow-web/ # Web/WASM target crate & self-contained HTML benchmarking dashboard
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 🔒 License
|
|
82
|
+
|
|
83
|
+
MIT License. See [LICENSE](LICENSE). Distributions must include the copyright and permission notices.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//! `nano-rspow` — Hybrid CPU/GPU Nano (XNO) Proof of Work library.
|
|
2
2
|
//!
|
|
3
|
-
//! Provides `work_generate`, `work_validate`, and `
|
|
4
|
-
//! multi-backend architecture: CPU (always
|
|
5
|
-
//!
|
|
3
|
+
//! Provides `work_generate`, `work_validate`, and `WorkGenerator` with a
|
|
4
|
+
//! multi-backend architecture: CPU (always available), wgpu/WGSL (the default
|
|
5
|
+
//! GPU backend on Metal, Vulkan, and DX12), and optional OpenCL.
|
|
6
6
|
//!
|
|
7
7
|
//! # Quick Start
|
|
8
8
|
//!
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# nano-rspow-python
|
|
2
|
+
|
|
3
|
+
Native Nano (XNO) proof-of-work bindings for Python. The extension selects an available GPU backend when possible and otherwise uses the CPU backend. `generate_work` releases the Python GIL while it searches.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install nano-rspow-python
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
import nano_rspow
|
|
15
|
+
from nano_rspow import WorkType
|
|
16
|
+
|
|
17
|
+
root = "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2"
|
|
18
|
+
result = nano_rspow.generate_work(root, WorkType.Send)
|
|
19
|
+
|
|
20
|
+
print(result.nonce_hex)
|
|
21
|
+
assert result.is_valid
|
|
22
|
+
assert nano_rspow.validate_work(root, result.nonce_hex, WorkType.Send)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API reference
|
|
26
|
+
|
|
27
|
+
### `generate_work(hash_hex, work_type) -> WorkResult`
|
|
28
|
+
|
|
29
|
+
Generates work for a 32-byte hexadecimal block root. Raises `ValueError` for invalid hexadecimal input or a root that is not 32 bytes. Raises `RuntimeError` if generation does not return a result.
|
|
30
|
+
|
|
31
|
+
### `validate_work(hash_hex, work_hex, work_type) -> bool`
|
|
32
|
+
|
|
33
|
+
Tests a hexadecimal nonce against a block root and the threshold selected by `work_type`. Raises `ValueError` for invalid input.
|
|
34
|
+
|
|
35
|
+
### `compute_difficulty(hash_hex, nonce_hex) -> str`
|
|
36
|
+
|
|
37
|
+
Returns the raw difficulty as a 16-character lowercase hexadecimal string. Raises `ValueError` for invalid input.
|
|
38
|
+
|
|
39
|
+
### `backend_name() -> str`
|
|
40
|
+
|
|
41
|
+
Returns the selected backend name, such as `cpu`, `wgpu`, or `opencl`.
|
|
42
|
+
|
|
43
|
+
### `WorkType`
|
|
44
|
+
|
|
45
|
+
| Value | Use |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| `Send` | Epoch 2 send and change blocks |
|
|
48
|
+
| `Receive` | Epoch 2 receive blocks |
|
|
49
|
+
| `LegacyEpoch1` | Historical epoch-1 validation only |
|
|
50
|
+
| `Epoch1` | Compatibility alias for `LegacyEpoch1` |
|
|
51
|
+
|
|
52
|
+
### `WorkResult`
|
|
53
|
+
|
|
54
|
+
`generate_work` returns a read-only result with `nonce_hex`, `difficulty_hex`, `is_valid`, and `multiplier` properties.
|
|
55
|
+
|
|
56
|
+
### `thresholds`
|
|
57
|
+
|
|
58
|
+
The `nano_rspow.thresholds` submodule provides `EPOCH2_SEND`, `EPOCH2_RECEIVE`, `LEGACY_EPOCH1`, `EPOCH1`, `BETA_LEGACY_EPOCH1`, `BETA_EPOCH1`, `DEV`, and `BASE`.
|
|
@@ -46,7 +46,7 @@ class WorkResult:
|
|
|
46
46
|
def generate_work(hash_hex: str, work_type: WorkType) -> WorkResult:
|
|
47
47
|
"""Generate valid Proof of Work for a Nano block hash.
|
|
48
48
|
|
|
49
|
-
Uses the
|
|
49
|
+
Uses the selected CPU or GPU backend.
|
|
50
50
|
The GIL is released during computation, so other Python threads
|
|
51
51
|
continue to run while the PoW search is in progress.
|
|
52
52
|
|
|
@@ -97,7 +97,7 @@ def compute_difficulty(hash_hex: str, nonce_hex: str) -> str:
|
|
|
97
97
|
def backend_name() -> str:
|
|
98
98
|
"""Return the name of the active compute backend.
|
|
99
99
|
|
|
100
|
-
Returns one of: "
|
|
100
|
+
Returns one of: "cpu", "wgpu", "opencl".
|
|
101
101
|
"""
|
|
102
102
|
...
|
|
103
103
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
//! import nano_rspow
|
|
10
10
|
//! from nano_rspow import WorkType
|
|
11
11
|
//!
|
|
12
|
-
//! # Generate work (releases GIL
|
|
12
|
+
//! # Generate work (releases the GIL and selects an available backend)
|
|
13
13
|
//! result = nano_rspow.generate_work(
|
|
14
14
|
//! "718CC2121C3E641059BC1C2CFC45666C99E8AE922F7A807B7D07B62C995D79E2",
|
|
15
15
|
//! WorkType.Send,
|
|
@@ -151,7 +151,7 @@ fn parse_hash(hash_hex: &str) -> PyResult<[u8; 32]> {
|
|
|
151
151
|
|
|
152
152
|
/// Generate valid Proof of Work for a Nano block hash.
|
|
153
153
|
///
|
|
154
|
-
/// Uses the best available backend
|
|
154
|
+
/// Uses the best available backend, preferring a supported GPU and otherwise CPU.
|
|
155
155
|
/// The GIL is released during computation, so other Python threads
|
|
156
156
|
/// continue to run while the PoW search is in progress.
|
|
157
157
|
///
|
|
@@ -236,7 +236,7 @@ fn compute_difficulty(hash_hex: &str, nonce_hex: &str) -> PyResult<String> {
|
|
|
236
236
|
|
|
237
237
|
/// Return the name of the active compute backend.
|
|
238
238
|
///
|
|
239
|
-
/// Returns
|
|
239
|
+
/// Returns the selected backend name, such as ``"cpu"``, ``"wgpu"``, or ``"opencl"``.
|
|
240
240
|
#[pyfunction]
|
|
241
241
|
fn backend_name() -> &'static str {
|
|
242
242
|
get_generator().backend_name()
|
|
@@ -271,7 +271,7 @@ fn register_thresholds(parent: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
|
271
271
|
/// Hybrid CPU/GPU Nano (XNO) Proof of Work — Python bindings.
|
|
272
272
|
///
|
|
273
273
|
/// This module wraps the ``nano-rspow`` Rust library, providing access to
|
|
274
|
-
/// the
|
|
274
|
+
/// the available CPU or GPU work-generation backend.
|
|
275
275
|
#[pymodule]
|
|
276
276
|
fn nano_rspow(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
277
277
|
m.add_class::<WorkType>()?;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
version = 1
|
|
2
|
+
revision = 3
|
|
3
|
+
requires-python = ">=3.9"
|
|
4
|
+
resolution-markers = [
|
|
5
|
+
"python_full_version >= '3.10'",
|
|
6
|
+
"python_full_version < '3.10'",
|
|
7
|
+
]
|
|
8
|
+
|
|
9
|
+
[[package]]
|
|
10
|
+
name = "colorama"
|
|
11
|
+
version = "0.4.6"
|
|
12
|
+
source = { registry = "https://pypi.org/simple" }
|
|
13
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
|
|
14
|
+
wheels = [
|
|
15
|
+
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[[package]]
|
|
19
|
+
name = "exceptiongroup"
|
|
20
|
+
version = "1.3.1"
|
|
21
|
+
source = { registry = "https://pypi.org/simple" }
|
|
22
|
+
dependencies = [
|
|
23
|
+
{ name = "typing-extensions" },
|
|
24
|
+
]
|
|
25
|
+
sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" }
|
|
26
|
+
wheels = [
|
|
27
|
+
{ url = "https://files.pythonhosted.org/packages/8a/0e/97c33bf5009bdbac74fd2beace167cab3f978feb69cc36f1ef79360d6c4e/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598", size = 16740, upload-time = "2025-11-21T23:01:53.443Z" },
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[[package]]
|
|
31
|
+
name = "iniconfig"
|
|
32
|
+
version = "2.1.0"
|
|
33
|
+
source = { registry = "https://pypi.org/simple" }
|
|
34
|
+
resolution-markers = [
|
|
35
|
+
"python_full_version < '3.10'",
|
|
36
|
+
]
|
|
37
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" }
|
|
38
|
+
wheels = [
|
|
39
|
+
{ url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" },
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[[package]]
|
|
43
|
+
name = "iniconfig"
|
|
44
|
+
version = "2.3.0"
|
|
45
|
+
source = { registry = "https://pypi.org/simple" }
|
|
46
|
+
resolution-markers = [
|
|
47
|
+
"python_full_version >= '3.10'",
|
|
48
|
+
]
|
|
49
|
+
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
|
|
50
|
+
wheels = [
|
|
51
|
+
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
[[package]]
|
|
55
|
+
name = "maturin"
|
|
56
|
+
version = "1.14.1"
|
|
57
|
+
source = { registry = "https://pypi.org/simple" }
|
|
58
|
+
dependencies = [
|
|
59
|
+
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
60
|
+
]
|
|
61
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e7/b3/addd877f871fb1860d46d3a4f206ecb10b946c85846805e6367631926fd3/maturin-1.14.1.tar.gz", hash = "sha256:9d6577a62cd08e0ceba7a0db06fb098e0c9b1b3429bad747a4f3a18215a1b3df", size = 369637, upload-time = "2026-06-19T05:19:49.774Z" }
|
|
62
|
+
wheels = [
|
|
63
|
+
{ url = "https://files.pythonhosted.org/packages/f4/f0/97c5a5bd9c71653a066c0976a484eaaae50b9369557838a4176b7b0bdaa5/maturin-1.14.1-py3-none-linux_armv6l.whl", hash = "sha256:522292398945442cdafa9daeb2271b2340fbde57027b818f923f88eab04174f8", size = 10207496, upload-time = "2026-06-19T05:19:09.321Z" },
|
|
64
|
+
{ url = "https://files.pythonhosted.org/packages/fe/83/294bca639b0e052f1e2f65199b3db258780c7d4e31408b934c9c974a1379/maturin-1.14.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ffe5ad71f21d1e6603c4dd75f7fee34adf5ed5ebcebb692886549888ebb329ed", size = 19680113, upload-time = "2026-06-19T05:19:13.43Z" },
|
|
65
|
+
{ url = "https://files.pythonhosted.org/packages/43/b6/79c881410a3b1c187f7eb3d407aecae646c6a4433d630d72200359015e83/maturin-1.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f3306078070c1508fd715b9116070cbcaff5959024272a9f1e6f5cb29768b86c", size = 10169205, upload-time = "2026-06-19T05:19:16.615Z" },
|
|
66
|
+
{ url = "https://files.pythonhosted.org/packages/93/9d/44b6f26dcb7f7a04c5501ac2dbb6ca1490150682baa525ca5860504f9eab/maturin-1.14.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:cd457cd88961156e26379e1155bd287cc0ec1c8b2f1582b0660fb31b87c8842d", size = 10188098, upload-time = "2026-06-19T05:19:19.736Z" },
|
|
67
|
+
{ url = "https://files.pythonhosted.org/packages/1a/bd/9c0d5d6983905ce2c9edaa073a7e89355a9cf7f396988e05d32f1c37785d/maturin-1.14.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:dfc54ae32e6fcb18302193ab9a30b0b25eefffba994ae13238974805533ef75e", size = 10627576, upload-time = "2026-06-19T05:19:22.713Z" },
|
|
68
|
+
{ url = "https://files.pythonhosted.org/packages/e5/33/b096412bd6a7cb399652b260666f901adf88a687181a6dbd6a3f89f0a94e/maturin-1.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:a131d912b5267e640bc96d70f4914e10590aed64082ec9abacba7cea52004224", size = 10085181, upload-time = "2026-06-19T05:19:25.69Z" },
|
|
69
|
+
{ url = "https://files.pythonhosted.org/packages/56/8d/08c3bf469c38a23c9e6c877e338193001eb604d010fedc08341974e38528/maturin-1.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:be18fc568fb76884c0205456336892a75105ec398e6b667cd777c6268bd06d69", size = 10026363, upload-time = "2026-06-19T05:19:28.904Z" },
|
|
70
|
+
{ url = "https://files.pythonhosted.org/packages/3a/a4/c4d1a92839f8745ab4aab988a7db884a79d6d710bd3b286fcf9316dece1a/maturin-1.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:994a0c8ba3ad8a92b3a9ee1b02645d200d610216b15cff5102b0fe65e8e08666", size = 13321347, upload-time = "2026-06-19T05:19:32.411Z" },
|
|
71
|
+
{ url = "https://files.pythonhosted.org/packages/b3/fa/170f04624d03fd07d2a8b1b67de83a127af93aef9eaa425839553347297b/maturin-1.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be80866363e605d137991b491a741a84cde9ae350183c4c85f49690ca9aaaa65", size = 10877609, upload-time = "2026-06-19T05:19:35.448Z" },
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/61/ad/1ae2e1d0ded282bf2c55ac13f0811d87deb425e200ae64a15785675dede9/maturin-1.14.1-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:5282dffd4b539d2be245f4e5b1a5ab6bc1033b58f4a4872f5833f9d43c954aa4", size = 10417316, upload-time = "2026-06-19T05:19:38.28Z" },
|
|
73
|
+
{ url = "https://files.pythonhosted.org/packages/fb/27/bf677183920718da49cd7982d6a3ffc440aad8919329f571d189f81b7bdf/maturin-1.14.1-py3-none-win32.whl", hash = "sha256:1a04de0a20188f95c721b5702eed18140bdcccb28c386797093eca3f62f4d4e0", size = 8931293, upload-time = "2026-06-19T05:19:41.183Z" },
|
|
74
|
+
{ url = "https://files.pythonhosted.org/packages/63/4b/585adeb9167b08d3cdff0032a938b0e72655c92003df4f52c3f696a1bcc2/maturin-1.14.1-py3-none-win_amd64.whl", hash = "sha256:3c9f94640ecc4895e94abaf834a0684430032c865b2748a36c12461fd9252fdd", size = 10314067, upload-time = "2026-06-19T05:19:44.389Z" },
|
|
75
|
+
{ url = "https://files.pythonhosted.org/packages/51/d4/dac8c0720ae246be1700afb6fbdbbea20fe35b13f6570b2f70faa005df77/maturin-1.14.1-py3-none-win_arm64.whl", hash = "sha256:15cea8fcb3ba47dd636f50092bb34baea8b04ac777392f23e6bf8a9a61efb894", size = 9718943, upload-time = "2026-06-19T05:19:47.49Z" },
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
[[package]]
|
|
79
|
+
name = "nano-rspow-python"
|
|
80
|
+
source = { editable = "." }
|
|
81
|
+
|
|
82
|
+
[package.dev-dependencies]
|
|
83
|
+
test = [
|
|
84
|
+
{ name = "maturin" },
|
|
85
|
+
{ name = "pytest", version = "8.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
|
86
|
+
{ name = "pytest", version = "9.1.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
[package.metadata]
|
|
90
|
+
|
|
91
|
+
[package.metadata.requires-dev]
|
|
92
|
+
test = [
|
|
93
|
+
{ name = "maturin", specifier = ">=1.5" },
|
|
94
|
+
{ name = "pytest", specifier = ">=8" },
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
[[package]]
|
|
98
|
+
name = "packaging"
|
|
99
|
+
version = "26.3"
|
|
100
|
+
source = { registry = "https://pypi.org/simple" }
|
|
101
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/fa/3944b40b07da9ce895c0e6303a5ab7d53da063554f534556b134a54d6093/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79", size = 313412, upload-time = "2026-08-04T18:15:28.737Z" }
|
|
102
|
+
wheels = [
|
|
103
|
+
{ url = "https://files.pythonhosted.org/packages/63/34/ba1c580383c9eada3711951fef0795c80b829a078d72188184bcab9dd527/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c", size = 129956, upload-time = "2026-08-04T18:15:27.159Z" },
|
|
104
|
+
]
|
|
105
|
+
|
|
106
|
+
[[package]]
|
|
107
|
+
name = "pluggy"
|
|
108
|
+
version = "1.6.0"
|
|
109
|
+
source = { registry = "https://pypi.org/simple" }
|
|
110
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
|
|
111
|
+
wheels = [
|
|
112
|
+
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
[[package]]
|
|
116
|
+
name = "pygments"
|
|
117
|
+
version = "2.21.0"
|
|
118
|
+
source = { registry = "https://pypi.org/simple" }
|
|
119
|
+
sdist = { url = "https://files.pythonhosted.org/packages/49/2e/ced460408999b33da6b31b0021b0f37d329e202d4169aeb164493778f25b/pygments-2.21.0.tar.gz", hash = "sha256:610ca751c9bc2492b38eb9a38a7fbc93edbbb2d7182edaf34e66ae493dee5c8c", size = 5005329, upload-time = "2026-08-17T08:02:48.824Z" }
|
|
120
|
+
wheels = [
|
|
121
|
+
{ url = "https://files.pythonhosted.org/packages/71/46/17f022dd3e953bf20a04a028a21ec746d942f8d2af30fa0f124fa0e6a684/pygments-2.21.0-py3-none-any.whl", hash = "sha256:2363c69b61c4a97c838da3b130dcd6468f4848992b21a82f2a63ec34377137d9", size = 1250147, upload-time = "2026-08-17T08:02:44.912Z" },
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
[[package]]
|
|
125
|
+
name = "pytest"
|
|
126
|
+
version = "8.4.2"
|
|
127
|
+
source = { registry = "https://pypi.org/simple" }
|
|
128
|
+
resolution-markers = [
|
|
129
|
+
"python_full_version < '3.10'",
|
|
130
|
+
]
|
|
131
|
+
dependencies = [
|
|
132
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
133
|
+
{ name = "exceptiongroup" },
|
|
134
|
+
{ name = "iniconfig", version = "2.1.0", source = { registry = "https://pypi.org/simple" } },
|
|
135
|
+
{ name = "packaging" },
|
|
136
|
+
{ name = "pluggy" },
|
|
137
|
+
{ name = "pygments" },
|
|
138
|
+
{ name = "tomli" },
|
|
139
|
+
]
|
|
140
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" }
|
|
141
|
+
wheels = [
|
|
142
|
+
{ url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" },
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
[[package]]
|
|
146
|
+
name = "pytest"
|
|
147
|
+
version = "9.1.1"
|
|
148
|
+
source = { registry = "https://pypi.org/simple" }
|
|
149
|
+
resolution-markers = [
|
|
150
|
+
"python_full_version >= '3.10'",
|
|
151
|
+
]
|
|
152
|
+
dependencies = [
|
|
153
|
+
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
|
154
|
+
{ name = "exceptiongroup", marker = "python_full_version < '3.11'" },
|
|
155
|
+
{ name = "iniconfig", version = "2.3.0", source = { registry = "https://pypi.org/simple" } },
|
|
156
|
+
{ name = "packaging" },
|
|
157
|
+
{ name = "pluggy" },
|
|
158
|
+
{ name = "pygments" },
|
|
159
|
+
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
|
160
|
+
]
|
|
161
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
|
|
162
|
+
wheels = [
|
|
163
|
+
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
|
|
164
|
+
]
|
|
165
|
+
|
|
166
|
+
[[package]]
|
|
167
|
+
name = "tomli"
|
|
168
|
+
version = "2.4.1"
|
|
169
|
+
source = { registry = "https://pypi.org/simple" }
|
|
170
|
+
sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" }
|
|
171
|
+
wheels = [
|
|
172
|
+
{ url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" },
|
|
173
|
+
{ url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" },
|
|
174
|
+
{ url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" },
|
|
175
|
+
{ url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" },
|
|
176
|
+
{ url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" },
|
|
177
|
+
{ url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" },
|
|
178
|
+
{ url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" },
|
|
179
|
+
{ url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" },
|
|
180
|
+
{ url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" },
|
|
181
|
+
{ url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" },
|
|
182
|
+
{ url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" },
|
|
183
|
+
{ url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" },
|
|
184
|
+
{ url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" },
|
|
185
|
+
{ url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" },
|
|
186
|
+
{ url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" },
|
|
187
|
+
{ url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" },
|
|
188
|
+
{ url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" },
|
|
189
|
+
{ url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" },
|
|
190
|
+
{ url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" },
|
|
191
|
+
{ url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" },
|
|
192
|
+
{ url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" },
|
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" },
|
|
194
|
+
{ url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" },
|
|
195
|
+
{ url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" },
|
|
196
|
+
{ url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" },
|
|
197
|
+
{ url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" },
|
|
198
|
+
{ url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" },
|
|
199
|
+
{ url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" },
|
|
200
|
+
{ url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" },
|
|
201
|
+
{ url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" },
|
|
202
|
+
{ url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" },
|
|
203
|
+
{ url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" },
|
|
204
|
+
{ url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" },
|
|
205
|
+
{ url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" },
|
|
206
|
+
{ url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" },
|
|
207
|
+
{ url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" },
|
|
208
|
+
{ url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" },
|
|
209
|
+
{ url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" },
|
|
210
|
+
{ url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" },
|
|
211
|
+
{ url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" },
|
|
212
|
+
{ url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" },
|
|
213
|
+
{ url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" },
|
|
214
|
+
{ url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" },
|
|
215
|
+
{ url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" },
|
|
216
|
+
{ url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" },
|
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" },
|
|
218
|
+
]
|
|
219
|
+
|
|
220
|
+
[[package]]
|
|
221
|
+
name = "typing-extensions"
|
|
222
|
+
version = "4.16.0"
|
|
223
|
+
source = { registry = "https://pypi.org/simple" }
|
|
224
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
|
225
|
+
wheels = [
|
|
226
|
+
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
|
227
|
+
]
|
|
@@ -6,21 +6,37 @@ build-backend = "maturin"
|
|
|
6
6
|
name = "nano-rspow-python"
|
|
7
7
|
dynamic = ["version"]
|
|
8
8
|
description = "Hybrid CPU/GPU Nano (XNO) Proof of Work library — Python bindings."
|
|
9
|
+
readme = "README.md"
|
|
9
10
|
requires-python = ">=3.9"
|
|
10
|
-
license =
|
|
11
|
+
license = "MIT"
|
|
11
12
|
authors = [
|
|
12
13
|
{ name = "Conny Brunnkvist", email = "cbrunnkvist@gmail.com" },
|
|
13
14
|
]
|
|
14
15
|
keywords = ["nano", "xno", "proof-of-work", "blake2b", "gpu"]
|
|
15
16
|
classifiers = [
|
|
16
|
-
"Programming Language ::
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
17
25
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
18
|
-
"
|
|
26
|
+
"Programming Language :: Rust",
|
|
19
27
|
"Topic :: Security :: Cryptography",
|
|
20
28
|
]
|
|
21
29
|
|
|
22
30
|
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/CasualSecurityInc/nano-rspow"
|
|
23
32
|
Repository = "https://github.com/CasualSecurityInc/nano-rspow"
|
|
33
|
+
Issues = "https://github.com/CasualSecurityInc/nano-rspow/issues"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
test = [
|
|
37
|
+
"maturin>=1.5",
|
|
38
|
+
"pytest>=8",
|
|
39
|
+
]
|
|
24
40
|
|
|
25
41
|
[tool.maturin]
|
|
26
42
|
features = ["pyo3/extension-module"]
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: nano-rspow-python
|
|
3
|
-
Version: 0.12.0
|
|
4
|
-
Classifier: Programming Language :: Rust
|
|
5
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
7
|
-
Classifier: Topic :: Security :: Cryptography
|
|
8
|
-
Summary: Hybrid CPU/GPU Nano (XNO) Proof of Work library — Python bindings.
|
|
9
|
-
Keywords: nano,xno,proof-of-work,blake2b,gpu
|
|
10
|
-
Author-email: Conny Brunnkvist <cbrunnkvist@gmail.com>
|
|
11
|
-
License: MIT
|
|
12
|
-
Requires-Python: >=3.9
|
|
13
|
-
Project-URL: Repository, https://github.com/CasualSecurityInc/nano-rspow
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# nano-rspow
|
|
2
|
-
|
|
3
|
-
nano-rspow is a fast, zero-configuration hybrid CPU/GPU proof-of-work generator for [Nano](https://www.nano.org).
|
|
4
|
-
|
|
5
|
-
Developed for high-throughput node operations, client-side web integrations, and native app developers, this repository packages an optimized Blake2b hashing engine under a transparent, auto-detecting **hybrid race architecture**. It seamlessly runs multi-threaded CPU solvers (powered by `rayon` and Web Workers) or GPU pipelines (`wgpu`, `OpenCL`, and WebGPU) depending on target hardware availability. No boilerplate, no device selection headaches—just instant, maximum-performance PoW generation everywhere.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 🎯 Who is this for?
|
|
10
|
-
|
|
11
|
-
* **Exchange & Wallet Integrators** wanting low-latency, high-volume block generation in-process / without the complexity of adding a another external service.
|
|
12
|
-
* **Server-side Developers** using Node.js or Python who need native bindings running at C-level execution speed.
|
|
13
|
-
* **Frontend Web Developers** building sleek wallets or dApps requiring non-blocking WASM and hardware-accelerated WebGPU directly in user browsers.
|
|
14
|
-
* **Power Users & Node Operators** looking for an ultra-fast benchmarking tool to tune threshold multipliers.
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## ⚡ Quick Start
|
|
19
|
-
|
|
20
|
-
### 1. Standalone CLI
|
|
21
|
-
Install from crates.io (requires a Rust toolchain):
|
|
22
|
-
```bash
|
|
23
|
-
cargo install nano-rspow-cli
|
|
24
|
-
nano-rspow-cli benchmark --count 10
|
|
25
|
-
```
|
|
26
|
-
Alternatively, build from this repository:
|
|
27
|
-
```bash
|
|
28
|
-
cargo build -p nano-rspow-cli --release
|
|
29
|
-
./target/release/nano-rspow-cli benchmark --count 10
|
|
30
|
-
```
|
|
31
|
-
Or use `cargo run -p nano-rspow-cli -- <args>` to build and execute in one step.
|
|
32
|
-
|
|
33
|
-
### 2. Node.js (Programmatic API)
|
|
34
|
-
Use the native bindings for in-process PoW generation:
|
|
35
|
-
```bash
|
|
36
|
-
npm install nano-rspow-node
|
|
37
|
-
```
|
|
38
|
-
See [nano-rspow-node/README.md](nano-rspow-node/README.md) for API usage.
|
|
39
|
-
|
|
40
|
-
### 3. Interactive Web Dashboard
|
|
41
|
-
Build and open the self-contained HTML5 benchmarking tool with real-time performance stats, non-blocking Web Worker fallback, WebGPU execution, and customizable cellular-signal difficulty thresholds:
|
|
42
|
-
```bash
|
|
43
|
-
cargo benchmark-web
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## 📦 Documentation & Release Channels
|
|
49
|
-
|
|
50
|
-
Below is the directory mapping for each target, along with their primary release registries:
|
|
51
|
-
|
|
52
|
-
| Environment | Documentation Link | Latest Releases & Authoritative Registries |
|
|
53
|
-
| :--- | :--- | :--- |
|
|
54
|
-
| **Rust (Core)** | [nano-rspow/](nano-rspow/) | [GitHub Releases](https://github.com/CasualSecurityInc/nano-rspow/releases) |
|
|
55
|
-
| **Node.js & TS** | [nano-rspow-node/README.md](nano-rspow-node/README.md) | [Public NPM package](https://www.npmjs.com/package/nano-rspow-node) |
|
|
56
|
-
| **Python** | [nano-rspow-python/](nano-rspow-python/) | [PyPI (pip)](https://pypi.org/project/nano-rspow-python/) |
|
|
57
|
-
| **Web (WASM / WebGPU)** | [nano-rspow-web/README.md](nano-rspow-web/README.md) | [Public NPM package](https://www.npmjs.com/package/nano-rspow-web) + [🎛️ Demo](https://csi.ninzin.net/nano-rspow/) |
|
|
58
|
-
| **CLI Tool** | [nano-rspow-cli/](nano-rspow-cli/) | [crates.io](https://crates.io/crates/nano-rspow-cli) · [GitHub Releases](https://github.com/CasualSecurityInc/nano-rspow/releases) |
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## 🗂️ Repository Layout
|
|
63
|
-
|
|
64
|
-
This monorepo is organized into specialized workspaces to deliver native performance across all environments:
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
.
|
|
68
|
-
├── .cargo/ # Target-specific build configurations and cargo aliases
|
|
69
|
-
├── nano-rspow/ # Core Rust library containing cryptographic Blake2b logic & backends
|
|
70
|
-
├── nano-rspow-cli/ # Standalone CLI binary for hardware benchmarking & generation
|
|
71
|
-
├── nano-rspow-node/ # High-performance Node.js & TypeScript native bindings (N-API)
|
|
72
|
-
├── nano-rspow-python/ # Native PyO3 bindings for Python environments
|
|
73
|
-
└── nano-rspow-web/ # Web/WASM target crate & self-contained HTML benchmarking dashboard
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## 🔒 License
|
|
79
|
-
|
|
80
|
-
MIT License. See [LICENSE](LICENSE) for more details. Attribution is required.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|