voidnote 0.3.0__tar.gz → 0.4.1__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.
- voidnote-0.4.1/.gitignore +11 -0
- voidnote-0.4.1/PKG-INFO +154 -0
- voidnote-0.4.1/README.md +133 -0
- {voidnote-0.3.0 → voidnote-0.4.1}/pyproject.toml +1 -1
- voidnote-0.4.1/voidnote/__init__.py +564 -0
- voidnote-0.3.0/PKG-INFO +0 -67
- voidnote-0.3.0/README.md +0 -46
- voidnote-0.3.0/voidnote/__init__.py +0 -461
voidnote-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: voidnote
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Official SDK for VoidNote — zero-knowledge self-destructing notes and live encrypted streams
|
|
5
|
+
Project-URL: Homepage, https://voidnote.net
|
|
6
|
+
Project-URL: Repository, https://github.com/quantum-encoding/voidnote-python
|
|
7
|
+
Project-URL: Documentation, https://voidnote.net/docs
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
Keywords: encryption,one-time,secrets,voidnote,zero-knowledge
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Requires-Dist: cryptography>=41.0.0
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: mypy; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# voidnote
|
|
23
|
+
|
|
24
|
+
Official Python SDK for [VoidNote](https://voidnote.net) — zero-knowledge self-destructing notes and live encrypted streams.
|
|
25
|
+
|
|
26
|
+
**v0.4.1** · Python 3.9+ · zero-knowledge v1 API
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install voidnote
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import voidnote
|
|
38
|
+
|
|
39
|
+
# Create a note — content is encrypted locally, server never sees plaintext
|
|
40
|
+
result = voidnote.create(
|
|
41
|
+
"my secret value",
|
|
42
|
+
api_key="vn_...",
|
|
43
|
+
max_views=1, # destroy after this many reads (1–100)
|
|
44
|
+
expires_in=1, # hours until expiry (1–720)
|
|
45
|
+
)
|
|
46
|
+
print(result.url) # https://voidnote.net/n/<tokenId>#<secret>
|
|
47
|
+
print(result.token) # 32-char tokenId
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## API
|
|
51
|
+
|
|
52
|
+
### `voidnote.create(content, *, api_key, max_views=1, expires_in=1) → CreateResult`
|
|
53
|
+
|
|
54
|
+
Encrypt `content` locally and store the ciphertext. Requires an API key from your [dashboard](https://voidnote.net/dashboard).
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
result = voidnote.create("deploy key: abc123", api_key="vn_...", max_views=3)
|
|
58
|
+
print(result.url) # full shareable URL — includes #secret
|
|
59
|
+
print(result.token) # 32-char tokenId only
|
|
60
|
+
print(result.expires_at)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `voidnote.read(url) → ReadResult`
|
|
64
|
+
|
|
65
|
+
Fetch and decrypt a note. Consumes one view. Accepts both v1 URLs (`/n/<token>#<secret>`) and legacy URLs.
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
note = voidnote.read("https://voidnote.net/n/<tokenId>#<secret>")
|
|
69
|
+
print(note.content) # decrypted plaintext
|
|
70
|
+
print(note.views_remaining) # views left after this read
|
|
71
|
+
print(note.destroyed) # True if this was the last view
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `voidnote.peek(url) → PeekResult`
|
|
75
|
+
|
|
76
|
+
Check metadata without consuming a view.
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
meta = voidnote.peek("https://voidnote.net/n/<tokenId>#<secret>")
|
|
80
|
+
print(meta.exists)
|
|
81
|
+
print(meta.views_remaining)
|
|
82
|
+
print(meta.expires_at)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Void Streams
|
|
86
|
+
|
|
87
|
+
Live encrypted real-time channels. Messages are encrypted before leaving your machine.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import voidnote
|
|
91
|
+
|
|
92
|
+
# Create a channel
|
|
93
|
+
stream = voidnote.create_stream(api_key="vn_...", title="Deploy #42")
|
|
94
|
+
print(stream.url) # share this URL with watchers
|
|
95
|
+
|
|
96
|
+
# Write messages (write and close are authenticated with the same API key)
|
|
97
|
+
stream.write("Starting deployment...")
|
|
98
|
+
stream.write("Build complete.")
|
|
99
|
+
stream.close() # self-destructs all content
|
|
100
|
+
|
|
101
|
+
# Watch a stream — yields decrypted messages as they arrive
|
|
102
|
+
for message in voidnote.watch(stream.url):
|
|
103
|
+
print(message)
|
|
104
|
+
|
|
105
|
+
# Password-protected stream
|
|
106
|
+
for message in voidnote.watch(url, password="hunter2"):
|
|
107
|
+
print(message)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Crypto payments
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
# Create a payment order
|
|
114
|
+
order = voidnote.create_crypto_order(
|
|
115
|
+
api_key="vn_...",
|
|
116
|
+
bundle_id="starter", # "test" | "starter" | "standard" | "pro"
|
|
117
|
+
chain="polygon",
|
|
118
|
+
token="USDT",
|
|
119
|
+
)
|
|
120
|
+
print(f"Send {order.amount} {order.token} to {order.to_address}")
|
|
121
|
+
|
|
122
|
+
# After sending, submit the tx hash
|
|
123
|
+
result = voidnote.submit_crypto_payment(
|
|
124
|
+
api_key="vn_...",
|
|
125
|
+
order_id=order.order_id,
|
|
126
|
+
tx_hash="0x...",
|
|
127
|
+
)
|
|
128
|
+
print(f"+{result.credits_added} credits, balance: {result.credits}")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Security model
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
server generates tokenId (32-char hex — stored as lookup key)
|
|
135
|
+
client generates secret (32-char hex — NEVER sent to server)
|
|
136
|
+
|
|
137
|
+
key = SHA-256(bytes.fromhex(secret))
|
|
138
|
+
ciphertext = AES-256-GCM(plaintext, key, random_12_byte_iv)
|
|
139
|
+
share URL = https://voidnote.net/n/{tokenId}#{secret}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The `#fragment` is never transmitted to HTTP servers per spec. The server has ciphertext; you have the key.
|
|
143
|
+
|
|
144
|
+
## Requirements
|
|
145
|
+
|
|
146
|
+
- Python 3.9+
|
|
147
|
+
- `cryptography >= 41.0.0` (installed automatically)
|
|
148
|
+
|
|
149
|
+
## Links
|
|
150
|
+
|
|
151
|
+
- [voidnote.net](https://voidnote.net)
|
|
152
|
+
- [API reference](https://voidnote.net/docs)
|
|
153
|
+
- [CLI reference](https://voidnote.net/cli)
|
|
154
|
+
- [GitHub](https://github.com/quantum-encoding/voidnote-python)
|
voidnote-0.4.1/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# voidnote
|
|
2
|
+
|
|
3
|
+
Official Python SDK for [VoidNote](https://voidnote.net) — zero-knowledge self-destructing notes and live encrypted streams.
|
|
4
|
+
|
|
5
|
+
**v0.4.1** · Python 3.9+ · zero-knowledge v1 API
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install voidnote
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick start
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
import voidnote
|
|
17
|
+
|
|
18
|
+
# Create a note — content is encrypted locally, server never sees plaintext
|
|
19
|
+
result = voidnote.create(
|
|
20
|
+
"my secret value",
|
|
21
|
+
api_key="vn_...",
|
|
22
|
+
max_views=1, # destroy after this many reads (1–100)
|
|
23
|
+
expires_in=1, # hours until expiry (1–720)
|
|
24
|
+
)
|
|
25
|
+
print(result.url) # https://voidnote.net/n/<tokenId>#<secret>
|
|
26
|
+
print(result.token) # 32-char tokenId
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
### `voidnote.create(content, *, api_key, max_views=1, expires_in=1) → CreateResult`
|
|
32
|
+
|
|
33
|
+
Encrypt `content` locally and store the ciphertext. Requires an API key from your [dashboard](https://voidnote.net/dashboard).
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
result = voidnote.create("deploy key: abc123", api_key="vn_...", max_views=3)
|
|
37
|
+
print(result.url) # full shareable URL — includes #secret
|
|
38
|
+
print(result.token) # 32-char tokenId only
|
|
39
|
+
print(result.expires_at)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `voidnote.read(url) → ReadResult`
|
|
43
|
+
|
|
44
|
+
Fetch and decrypt a note. Consumes one view. Accepts both v1 URLs (`/n/<token>#<secret>`) and legacy URLs.
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
note = voidnote.read("https://voidnote.net/n/<tokenId>#<secret>")
|
|
48
|
+
print(note.content) # decrypted plaintext
|
|
49
|
+
print(note.views_remaining) # views left after this read
|
|
50
|
+
print(note.destroyed) # True if this was the last view
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### `voidnote.peek(url) → PeekResult`
|
|
54
|
+
|
|
55
|
+
Check metadata without consuming a view.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
meta = voidnote.peek("https://voidnote.net/n/<tokenId>#<secret>")
|
|
59
|
+
print(meta.exists)
|
|
60
|
+
print(meta.views_remaining)
|
|
61
|
+
print(meta.expires_at)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Void Streams
|
|
65
|
+
|
|
66
|
+
Live encrypted real-time channels. Messages are encrypted before leaving your machine.
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import voidnote
|
|
70
|
+
|
|
71
|
+
# Create a channel
|
|
72
|
+
stream = voidnote.create_stream(api_key="vn_...", title="Deploy #42")
|
|
73
|
+
print(stream.url) # share this URL with watchers
|
|
74
|
+
|
|
75
|
+
# Write messages (write and close are authenticated with the same API key)
|
|
76
|
+
stream.write("Starting deployment...")
|
|
77
|
+
stream.write("Build complete.")
|
|
78
|
+
stream.close() # self-destructs all content
|
|
79
|
+
|
|
80
|
+
# Watch a stream — yields decrypted messages as they arrive
|
|
81
|
+
for message in voidnote.watch(stream.url):
|
|
82
|
+
print(message)
|
|
83
|
+
|
|
84
|
+
# Password-protected stream
|
|
85
|
+
for message in voidnote.watch(url, password="hunter2"):
|
|
86
|
+
print(message)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Crypto payments
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
# Create a payment order
|
|
93
|
+
order = voidnote.create_crypto_order(
|
|
94
|
+
api_key="vn_...",
|
|
95
|
+
bundle_id="starter", # "test" | "starter" | "standard" | "pro"
|
|
96
|
+
chain="polygon",
|
|
97
|
+
token="USDT",
|
|
98
|
+
)
|
|
99
|
+
print(f"Send {order.amount} {order.token} to {order.to_address}")
|
|
100
|
+
|
|
101
|
+
# After sending, submit the tx hash
|
|
102
|
+
result = voidnote.submit_crypto_payment(
|
|
103
|
+
api_key="vn_...",
|
|
104
|
+
order_id=order.order_id,
|
|
105
|
+
tx_hash="0x...",
|
|
106
|
+
)
|
|
107
|
+
print(f"+{result.credits_added} credits, balance: {result.credits}")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Security model
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
server generates tokenId (32-char hex — stored as lookup key)
|
|
114
|
+
client generates secret (32-char hex — NEVER sent to server)
|
|
115
|
+
|
|
116
|
+
key = SHA-256(bytes.fromhex(secret))
|
|
117
|
+
ciphertext = AES-256-GCM(plaintext, key, random_12_byte_iv)
|
|
118
|
+
share URL = https://voidnote.net/n/{tokenId}#{secret}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The `#fragment` is never transmitted to HTTP servers per spec. The server has ciphertext; you have the key.
|
|
122
|
+
|
|
123
|
+
## Requirements
|
|
124
|
+
|
|
125
|
+
- Python 3.9+
|
|
126
|
+
- `cryptography >= 41.0.0` (installed automatically)
|
|
127
|
+
|
|
128
|
+
## Links
|
|
129
|
+
|
|
130
|
+
- [voidnote.net](https://voidnote.net)
|
|
131
|
+
- [API reference](https://voidnote.net/docs)
|
|
132
|
+
- [CLI reference](https://voidnote.net/cli)
|
|
133
|
+
- [GitHub](https://github.com/quantum-encoding/voidnote-python)
|