libcrypto 1.6.0__tar.gz → 1.6.2__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.
- libcrypto-1.6.2/PKG-INFO +601 -0
- libcrypto-1.6.2/README.md +571 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/_version.py +1 -1
- libcrypto-1.6.2/src/libcrypto.egg-info/PKG-INFO +601 -0
- libcrypto-1.6.0/PKG-INFO +0 -230
- libcrypto-1.6.0/README.md +0 -200
- libcrypto-1.6.0/src/libcrypto.egg-info/PKG-INFO +0 -230
- {libcrypto-1.6.0 → libcrypto-1.6.2}/LICENSE +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/MANIFEST.in +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/pyproject.toml +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/setup.cfg +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/setup.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/__init__.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/_keccak.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/_ripemd160.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/addresses.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/bip32.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/cli.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/constants.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/formats.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/hash.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/keys.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/mnemonic.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/py.typed +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/secp256k1.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto/wallet.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto.egg-info/SOURCES.txt +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto.egg-info/dependency_links.txt +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto.egg-info/entry_points.txt +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/src/libcrypto.egg-info/top_level.txt +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_addresses.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_bip32.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_constants.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_formats.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_hash.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_keys.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_mnemonic.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_secp256k1.py +0 -0
- {libcrypto-1.6.0 → libcrypto-1.6.2}/tests/test_wallet.py +0 -0
libcrypto-1.6.2/PKG-INFO
ADDED
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: libcrypto
|
|
3
|
+
Version: 1.6.2
|
|
4
|
+
Summary: Pure Python cryptocurrency address generation and cryptographic utilities.
|
|
5
|
+
Author-email: Pymmdrza <pymmdrza@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://gitlab.com/0xmdrza/libcrypto
|
|
8
|
+
Project-URL: Repository, https://gitlab.com/0xmdrza/libcrypto
|
|
9
|
+
Project-URL: Issues, https://gitlab.com/0xmdrza/libcrypto/-/issues
|
|
10
|
+
Project-URL: Documentation, https://gitlab.com/0xmdrza/libcrypto
|
|
11
|
+
Keywords: bitcoin,ethereum,tron,wallet,address,cryptocurrency,secp256k1,keccak,base58,bech32
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Security :: Cryptography
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Operating System :: OS Independent
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# libcrypto
|
|
32
|
+
|
|
33
|
+
A lightweight, dependency-free Python library for deterministic cryptocurrency key and address generation.
|
|
34
|
+
|
|
35
|
+
`libcrypto` is designed for developers who need a clean, portable, and auditable cryptographic address engine without unnecessary runtime dependencies. It provides pure Python implementations for core wallet operations, including private key handling, public key derivation, address encoding, WIF conversion, mnemonic-based HD wallets, and multi-chain address generation.
|
|
36
|
+
|
|
37
|
+
The library focuses on predictable output, compatibility with established address formats, and a stable public API suitable for production tools, research utilities, wallet infrastructure, offline generators, and blockchain automation systems.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Key Features
|
|
42
|
+
|
|
43
|
+
* Pure Python implementation
|
|
44
|
+
* No required runtime dependencies
|
|
45
|
+
* Deterministic private key to public address conversion
|
|
46
|
+
* secp256k1 public key derivation
|
|
47
|
+
* Real Keccak-256 implementation for Ethereum and TRON
|
|
48
|
+
* RIPEMD-160 support with internal fallback
|
|
49
|
+
* Base58Check, Bech32, Bech32m, and CashAddr support
|
|
50
|
+
* Bitcoin legacy, nested SegWit, native SegWit, and Taproot addresses
|
|
51
|
+
* Ethereum-compatible EVM address generation
|
|
52
|
+
* TRON Base58 and hex address generation
|
|
53
|
+
* WIF import and export
|
|
54
|
+
* Public key based address generation
|
|
55
|
+
* BIP39 mnemonic utilities
|
|
56
|
+
* BIP32/BIP44-style HD wallet support
|
|
57
|
+
* Clean API for single-wallet and batch generation workflows
|
|
58
|
+
* Suitable for offline and local-first key/address operations
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Installation
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install libcrypto
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Upgrade to the latest version:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install --upgrade libcrypto
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
Practical usage examples are available in the [`examples/`](examples/) directory.
|
|
79
|
+
|
|
80
|
+
The Examples Cover Multi-chain Address Generation, Secure Wallet Creation, WIF import/export, Public-key-only Workflows, HD wallet Derivation, Batch CSV Generation, and Deterministic Address Test Vectors.
|
|
81
|
+
|
|
82
|
+
> See [More Details](examples/README.md) for the Full Example Guide.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Basic Usage
|
|
87
|
+
|
|
88
|
+
Generate multiple blockchain addresses from a single private key:
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from libcrypto import Wallet
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
private_key = "0000000000000000000000000000000000000000000000000000000000000001"
|
|
95
|
+
|
|
96
|
+
wallet = Wallet(private_key)
|
|
97
|
+
|
|
98
|
+
print("Bitcoin P2PKH:", wallet.get_address("bitcoin", "p2pkh"))
|
|
99
|
+
print("Bitcoin P2SH-P2WPKH:", wallet.get_address("bitcoin", "p2sh-p2wpkh"))
|
|
100
|
+
print("Bitcoin P2WPKH:", wallet.get_address("bitcoin", "p2wpkh"))
|
|
101
|
+
print("Bitcoin Taproot:", wallet.get_address("bitcoin", "p2tr"))
|
|
102
|
+
|
|
103
|
+
print("Ethereum:", wallet.get_address("ethereum"))
|
|
104
|
+
|
|
105
|
+
print("TRON:", wallet.get_address("tron"))
|
|
106
|
+
print("TRON Hex:", wallet.get_address("tron", "hex"))
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Expected deterministic output for private key `1`:
|
|
110
|
+
|
|
111
|
+
```text
|
|
112
|
+
Bitcoin P2PKH: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
|
|
113
|
+
Bitcoin P2SH-P2WPKH: 3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN
|
|
114
|
+
Bitcoin P2WPKH: bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
|
|
115
|
+
Bitcoin Taproot: bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9
|
|
116
|
+
Ethereum: 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf
|
|
117
|
+
TRON: TMVQGm1qAQYVdetCeGRRkTWYYrLXuHK2HC
|
|
118
|
+
TRON Hex: 417E5F4552091A69125D5DFCB7B8C2659029395BDF
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Generate a New Wallet
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from libcrypto import Wallet
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
wallet = Wallet.generate()
|
|
130
|
+
|
|
131
|
+
print("Private key:", wallet.private_key.hex)
|
|
132
|
+
print("WIF:", wallet.private_key.to_wif(compressed=True))
|
|
133
|
+
|
|
134
|
+
print("Bitcoin:", wallet.get_address("bitcoin", "p2pkh"))
|
|
135
|
+
print("Ethereum:", wallet.get_address("ethereum"))
|
|
136
|
+
print("TRON:", wallet.get_address("tron"))
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Security note: never expose, log, upload, or commit real private keys.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Supported Address Types
|
|
144
|
+
|
|
145
|
+
### Bitcoin
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from libcrypto import Wallet
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
wallet = Wallet.generate()
|
|
152
|
+
|
|
153
|
+
print(wallet.get_address("bitcoin", "p2pkh"))
|
|
154
|
+
print(wallet.get_address("bitcoin", "p2sh-p2wpkh"))
|
|
155
|
+
print(wallet.get_address("bitcoin", "p2wpkh"))
|
|
156
|
+
print(wallet.get_address("bitcoin", "p2tr"))
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Supported Bitcoin formats:
|
|
160
|
+
|
|
161
|
+
| Type | Description | Prefix |
|
|
162
|
+
| ------------- | ----------------------------- | ------ |
|
|
163
|
+
| `p2pkh` | Legacy Pay-to-Public-Key-Hash | `1` |
|
|
164
|
+
| `p2sh-p2wpkh` | Nested SegWit | `3` |
|
|
165
|
+
| `p2wpkh` | Native SegWit v0 | `bc1q` |
|
|
166
|
+
| `p2tr` | Taproot / Native SegWit v1 | `bc1p` |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
### Ethereum and EVM Networks
|
|
171
|
+
|
|
172
|
+
Ethereum and EVM-compatible chains use the same address derivation method.
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from libcrypto import Wallet
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
wallet = Wallet.generate()
|
|
179
|
+
|
|
180
|
+
print("Ethereum:", wallet.get_address("ethereum"))
|
|
181
|
+
print("BSC:", wallet.get_address("bsc"))
|
|
182
|
+
print("Polygon:", wallet.get_address("polygon"))
|
|
183
|
+
print("Avalanche:", wallet.get_address("avalanche"))
|
|
184
|
+
print("Arbitrum:", wallet.get_address("arbitrum"))
|
|
185
|
+
print("Optimism:", wallet.get_address("optimism"))
|
|
186
|
+
print("Base:", wallet.get_address("base"))
|
|
187
|
+
print("Ethereum Classic:", wallet.get_address("ethereum_classic"))
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
EVM addresses are generated using Keccak-256 and returned with EIP-55 checksum formatting.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### TRON
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from libcrypto import Wallet
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
wallet = Wallet.generate()
|
|
201
|
+
|
|
202
|
+
print("TRON Base58:", wallet.get_address("tron"))
|
|
203
|
+
print("TRON Hex:", wallet.get_address("tron", "hex"))
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
TRON addresses are generated from the same secp256k1 public key model used by Ethereum, but encoded with TRON's `0x41` address prefix and Base58Check representation.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### Litecoin, Dogecoin, Dash, Bitcoin Cash, DigiByte, and Namecoin
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from libcrypto import Wallet
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
wallet = Wallet.generate()
|
|
217
|
+
|
|
218
|
+
print("Litecoin:", wallet.get_address("litecoin", "p2pkh"))
|
|
219
|
+
print("Dogecoin:", wallet.get_address("dogecoin", "p2pkh"))
|
|
220
|
+
print("Dash:", wallet.get_address("dash", "p2pkh"))
|
|
221
|
+
print("Bitcoin Cash:", wallet.get_address("bitcoin_cash", "cashaddr"))
|
|
222
|
+
print("DigiByte:", wallet.get_address("digibyte", "p2pkh"))
|
|
223
|
+
print("Namecoin:", wallet.get_address("namecoin", "p2pkh"))
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Get All Addresses for a Coin
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from libcrypto import Wallet
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
wallet = Wallet.generate()
|
|
235
|
+
|
|
236
|
+
addresses = wallet.get_all_addresses("bitcoin")
|
|
237
|
+
|
|
238
|
+
for address_type, address in addresses.items():
|
|
239
|
+
print(address_type, address)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Example output:
|
|
243
|
+
|
|
244
|
+
```text
|
|
245
|
+
p2pkh 1...
|
|
246
|
+
p2sh-p2wpkh 3...
|
|
247
|
+
p2wpkh bc1q...
|
|
248
|
+
p2tr bc1p...
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Private Key Handling
|
|
254
|
+
|
|
255
|
+
Create a private key from hex:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from libcrypto import PrivateKey
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
private_key = PrivateKey(
|
|
262
|
+
"0000000000000000000000000000000000000000000000000000000000000001"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
print(private_key.hex)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Generate a secure private key:
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
from libcrypto import PrivateKey
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
private_key = PrivateKey.generate()
|
|
275
|
+
|
|
276
|
+
print(private_key.hex)
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Export to WIF:
|
|
280
|
+
|
|
281
|
+
```python
|
|
282
|
+
from libcrypto import PrivateKey
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
private_key = PrivateKey.generate(network="bitcoin")
|
|
286
|
+
|
|
287
|
+
print(private_key.to_wif(compressed=True))
|
|
288
|
+
print(private_key.to_wif(compressed=False))
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Import from WIF:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
from libcrypto import PrivateKey, Wallet
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
wif = "your_wif_private_key_here"
|
|
298
|
+
|
|
299
|
+
private_key = PrivateKey(wif)
|
|
300
|
+
wallet = Wallet(private_key)
|
|
301
|
+
|
|
302
|
+
print(wallet.get_address("bitcoin", "p2pkh"))
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Public Key Usage
|
|
308
|
+
|
|
309
|
+
Generate addresses directly from public keys:
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
from libcrypto import PrivateKey, PublicKey
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
private_key = PrivateKey(
|
|
316
|
+
"0000000000000000000000000000000000000000000000000000000000000001"
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
compressed_public_key = private_key.get_public_key(compressed=True)
|
|
320
|
+
uncompressed_public_key = private_key.get_public_key(compressed=False)
|
|
321
|
+
|
|
322
|
+
bitcoin_public_key = PublicKey(compressed_public_key.hex)
|
|
323
|
+
ethereum_public_key = PublicKey(uncompressed_public_key.hex)
|
|
324
|
+
|
|
325
|
+
print(bitcoin_public_key.get_address("p2pkh", "bitcoin"))
|
|
326
|
+
print(bitcoin_public_key.get_address("p2wpkh", "bitcoin"))
|
|
327
|
+
print(ethereum_public_key.get_address("default", "ethereum"))
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## HD Wallets and Mnemonics
|
|
333
|
+
|
|
334
|
+
Generate a mnemonic phrase:
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
from libcrypto import generate_mnemonic, validate_mnemonic
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
mnemonic = generate_mnemonic(12)
|
|
341
|
+
|
|
342
|
+
print(mnemonic)
|
|
343
|
+
print(validate_mnemonic(mnemonic))
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Create an HD wallet from a mnemonic:
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
from libcrypto import HDWallet, Wallet, generate_mnemonic
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
mnemonic = generate_mnemonic(12)
|
|
353
|
+
|
|
354
|
+
hd_wallet = HDWallet.from_mnemonic(
|
|
355
|
+
mnemonic,
|
|
356
|
+
passphrase="",
|
|
357
|
+
network="mainnet",
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
node = hd_wallet.derive_from_path("m/44'/60'/0'/0/0")
|
|
361
|
+
|
|
362
|
+
if node.private_key is None:
|
|
363
|
+
raise RuntimeError("Derived node does not contain a private key.")
|
|
364
|
+
|
|
365
|
+
wallet = Wallet(node.private_key)
|
|
366
|
+
|
|
367
|
+
print(wallet.get_address("ethereum"))
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Bitcoin derivation example:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
from libcrypto import HDWallet, Wallet, generate_mnemonic
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
mnemonic = generate_mnemonic(12)
|
|
377
|
+
|
|
378
|
+
hd_wallet = HDWallet.from_mnemonic(
|
|
379
|
+
mnemonic,
|
|
380
|
+
passphrase="",
|
|
381
|
+
network="mainnet",
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
node = hd_wallet.derive_from_path("m/84'/0'/0'/0/0")
|
|
385
|
+
|
|
386
|
+
if node.private_key is None:
|
|
387
|
+
raise RuntimeError("Derived node does not contain a private key.")
|
|
388
|
+
|
|
389
|
+
wallet = Wallet(node.private_key)
|
|
390
|
+
|
|
391
|
+
print(wallet.get_address("bitcoin", "p2wpkh"))
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
TRON derivation example:
|
|
395
|
+
|
|
396
|
+
```python
|
|
397
|
+
from libcrypto import HDWallet, Wallet, generate_mnemonic
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
mnemonic = generate_mnemonic(12)
|
|
401
|
+
|
|
402
|
+
hd_wallet = HDWallet.from_mnemonic(
|
|
403
|
+
mnemonic,
|
|
404
|
+
passphrase="",
|
|
405
|
+
network="mainnet",
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
node = hd_wallet.derive_from_path("m/44'/195'/0'/0/0")
|
|
409
|
+
|
|
410
|
+
if node.private_key is None:
|
|
411
|
+
raise RuntimeError("Derived node does not contain a private key.")
|
|
412
|
+
|
|
413
|
+
wallet = Wallet(node.private_key)
|
|
414
|
+
|
|
415
|
+
print(wallet.get_address("tron"))
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## Batch Wallet Generation
|
|
421
|
+
|
|
422
|
+
```python
|
|
423
|
+
import csv
|
|
424
|
+
from pathlib import Path
|
|
425
|
+
|
|
426
|
+
from libcrypto import Wallet
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
output_path = Path("wallets.csv")
|
|
430
|
+
|
|
431
|
+
fieldnames = [
|
|
432
|
+
"index",
|
|
433
|
+
"private_key_hex",
|
|
434
|
+
"bitcoin_p2pkh",
|
|
435
|
+
"bitcoin_p2wpkh",
|
|
436
|
+
"bitcoin_p2tr",
|
|
437
|
+
"ethereum",
|
|
438
|
+
"tron",
|
|
439
|
+
]
|
|
440
|
+
|
|
441
|
+
with output_path.open("w", newline="", encoding="utf-8") as file:
|
|
442
|
+
writer = csv.DictWriter(file, fieldnames=fieldnames)
|
|
443
|
+
writer.writeheader()
|
|
444
|
+
|
|
445
|
+
for index in range(1, 11):
|
|
446
|
+
wallet = Wallet.generate()
|
|
447
|
+
|
|
448
|
+
writer.writerow(
|
|
449
|
+
{
|
|
450
|
+
"index": index,
|
|
451
|
+
"private_key_hex": wallet.private_key.hex,
|
|
452
|
+
"bitcoin_p2pkh": wallet.get_address("bitcoin", "p2pkh"),
|
|
453
|
+
"bitcoin_p2wpkh": wallet.get_address("bitcoin", "p2wpkh"),
|
|
454
|
+
"bitcoin_p2tr": wallet.get_address("bitcoin", "p2tr"),
|
|
455
|
+
"ethereum": wallet.get_address("ethereum"),
|
|
456
|
+
"tron": wallet.get_address("tron"),
|
|
457
|
+
}
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
print(f"Wallets written to {output_path.resolve()}")
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
Warning: this CSV file contains private keys. Store it offline and protect it carefully.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Deterministic Test Vector
|
|
468
|
+
|
|
469
|
+
This example verifies that the library produces deterministic and standard addresses from a known secp256k1 private key.
|
|
470
|
+
|
|
471
|
+
```python
|
|
472
|
+
from libcrypto import Wallet
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
private_key = "0000000000000000000000000000000000000000000000000000000000000001"
|
|
476
|
+
|
|
477
|
+
wallet = Wallet(private_key)
|
|
478
|
+
|
|
479
|
+
assert wallet.get_address("bitcoin", "p2pkh") == "1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH"
|
|
480
|
+
assert wallet.get_address("bitcoin", "p2sh-p2wpkh") == "3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN"
|
|
481
|
+
assert wallet.get_address("bitcoin", "p2wpkh") == "bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4"
|
|
482
|
+
assert wallet.get_address("bitcoin", "p2tr") == "bc1pmfr3p9j00pfxjh0zmgp99y8zftmd3s5pmedqhyptwy6lm87hf5sspknck9"
|
|
483
|
+
|
|
484
|
+
assert wallet.get_address("ethereum") == "0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf"
|
|
485
|
+
|
|
486
|
+
assert wallet.get_address("tron") == "TMVQGm1qAQYVdetCeGRRkTWYYrLXuHK2HC"
|
|
487
|
+
assert wallet.get_address("tron", "hex") == "417E5F4552091A69125D5DFCB7B8C2659029395BDF"
|
|
488
|
+
|
|
489
|
+
print("All deterministic address vectors passed.")
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
---
|
|
493
|
+
|
|
494
|
+
## Command Line Usage
|
|
495
|
+
|
|
496
|
+
If installed with console script support:
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
libcrypto --help
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
Example usage:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
libcrypto generate
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
Depending on the installed version, CLI commands may expose wallet generation, address conversion, and inspection utilities.
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
## Design Goals
|
|
513
|
+
|
|
514
|
+
`libcrypto` is built around a few strict design principles:
|
|
515
|
+
|
|
516
|
+
1. Keep the public API simple and stable.
|
|
517
|
+
2. Avoid unnecessary runtime dependencies.
|
|
518
|
+
3. Provide deterministic and reproducible address generation.
|
|
519
|
+
4. Use correct cryptographic primitives for each chain.
|
|
520
|
+
5. Keep private key operations local and offline-friendly.
|
|
521
|
+
6. Make the implementation easy to inspect, test, and package.
|
|
522
|
+
|
|
523
|
+
---
|
|
524
|
+
|
|
525
|
+
## Security Considerations
|
|
526
|
+
|
|
527
|
+
`libcrypto` performs local cryptographic key and address operations. It does not protect users from unsafe operational practices.
|
|
528
|
+
|
|
529
|
+
Follow these rules carefully:
|
|
530
|
+
|
|
531
|
+
* Never use demo private keys for real funds.
|
|
532
|
+
* Never commit private keys, mnemonic phrases, WIF keys, or seed material.
|
|
533
|
+
* Never log private keys in production systems.
|
|
534
|
+
* Never send private keys to remote APIs unless your application explicitly requires it and users fully understand the risk.
|
|
535
|
+
* Prefer offline execution for sensitive key generation workflows.
|
|
536
|
+
* Always verify address output with independent test vectors before integrating into high-value systems.
|
|
537
|
+
* Use secure backups for mnemonic phrases and private keys.
|
|
538
|
+
* Treat generated CSV, JSON, and text files containing private keys as highly sensitive data.
|
|
539
|
+
|
|
540
|
+
This library is intended for developers who understand the responsibility of handling private keys and wallet material.
|
|
541
|
+
|
|
542
|
+
---
|
|
543
|
+
|
|
544
|
+
## Testing
|
|
545
|
+
|
|
546
|
+
Run the test suite:
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
python -m pytest -q
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Build the package locally:
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
python -m pip install --upgrade build twine
|
|
556
|
+
python -m build --sdist --wheel
|
|
557
|
+
python -m twine check dist/*
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Install locally from source:
|
|
561
|
+
|
|
562
|
+
```bash
|
|
563
|
+
pip install .
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## Packaging
|
|
569
|
+
|
|
570
|
+
The package is designed to be distributed as a pure Python wheel:
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
python -m build --wheel
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Generated distributions are placed in:
|
|
577
|
+
|
|
578
|
+
```text
|
|
579
|
+
dist/
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## Project Links
|
|
585
|
+
|
|
586
|
+
* Repository: https://gitlab.com/0xmdrza/libcrypto
|
|
587
|
+
* PyPI: https://pypi.org/project/libcrypto/
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## License
|
|
592
|
+
|
|
593
|
+
This project is distributed under the MIT License.
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## Disclaimer
|
|
598
|
+
|
|
599
|
+
This software is provided for development, research, and infrastructure use. Cryptocurrency private key handling is security-critical. The authors and contributors are not responsible for lost funds, insecure deployments, compromised keys, incorrect integrations, or misuse of the library.
|
|
600
|
+
|
|
601
|
+
Always test carefully before using any cryptographic tool in production.
|