neo-n3-wallet v0.2.1
The Python wallet library for Neo N3 — with BIP-39 mnemonic support, HD key derivation, and full key management. Filling the gap that Rust and neon-js filled for other languages.
Aligned with Neo-CLI v3.10.0's expanded BIP-39 support (12 and 24-word phrases).
pip install neo-n3-wallet
Features
| Feature | Details |
|---|---|
| BIP-39 Mnemonics | 12 / 15 / 18 / 21 / 24 words, 8 languages |
| HD Derivation | BIP-32 over secp256r1 (NIST P-256), BIP-44 path m/44'/888'/0'/0/0 |
| NEP-2 Encryption | scrypt + AES-256-ECB passphrase-protected private keys |
| NEP-6 Wallets | Save / load standard Neo wallet JSON files |
| WIF | Wallet Import Format encode / decode |
| Signing | secp256r1 sign & verify |
What's New in v0.2.1
- Fixed
verifymsg()— it previously always returnedFalse. The implementation now recovers candidate public keys from the ECDSA signature and compares the derived Neo N3 address, matching Neo-CLI'sverifymsgRPC behavior. - Correct message-signing prefix —
signmsg()/verifymsg()now use the Neo magic prefix"Neo Signed Message:\n"before SHA-256 hashing, so signatures are compatible with the official neo-project/neo implementation.
What's New in v0.2.0
- Neo-CLI v3.10.0 RPC parity: added local helpers
signmsg()/verifymsg()for message-signing workflows. - DeferredRelay: added
DeferredRelayAttribute+create_deferred_relay_attribute()helpers for attaching DeferredRelay-compatible attributes to raw transactions. - NEP-6 mnemonic wallet interop: added
Wallet.from_mnemonic(mnemonic_phrase, passphrase="")for mnemonic-first wallet creation aligned with Neo-CLI v3.10.0 expectations. - Gorgon hard fork fee estimation: added
fee_estimate(tx_size_bytes, fork="gorgon")helper with a simplified Gorgon-aware fee model.
What's New in v0.1.2 — NEP-6 Compliance Fix
Full NEP-6 spec compliance after COZ team review:
- NFC password normalization — passphrase is Unicode NFC-normalized before any scrypt/encrypt/decrypt operation per NEP-2 spec
- Variable scrypt params — wallet JSON
n/r/pvalues are now read and applied instead of ignored lock,contract,extrafields — Account now stores and round-trips all NEP-6 fields includingcontract.script(base64),contract.parameters,contract.deployed, andextra- Single default account — setting one account as default now clears all others; enforced on load too
- Thread safety —
threading.RLock()added to all wallet operations wallet.save()password fix — tracks current password so save() always uses the right one after a password change- Duplicate prevention —
derive_accounts()andload()deduplicate by address
Quick Start
from neo_n3_wallet import Wallet, MnemonicManager, Account, KeyPair
# --- Create a brand-new HD wallet (24-word mnemonic) ---
wallet = Wallet.create(word_count=24)
print(wallet.mnemonic) # 24 BIP-39 words
# Derive the first account (m/44'/888'/0'/0/0)
account = wallet.derive_account(index=0)
print(account.address) # NXxx... Neo N3 address
# Derive 5 accounts at once
accounts = wallet.derive_accounts(count=5)
# Save as NEP-6 JSON (accounts are encrypted with the passphrase)
wallet.save("my_wallet.json", passphrase="s3cur3!")
# --- Restore a wallet from an existing mnemonic ---
wallet2 = Wallet.from_mnemonic(
"abandon abandon abandon ... art",
passphrase="" # optional BIP-39 passphrase
)
# --- Load a NEP-6 file ---
loaded = Wallet.load("my_wallet.json", passphrase="s3cur3!")
print(loaded.accounts[0].address)
Mnemonic Management
from neo_n3_wallet import MnemonicManager
m = MnemonicManager() # default: English
phrase = m.generate(24) # 24-word mnemonic
assert m.validate(phrase) # True
seed = m.to_seed(phrase) # 64-byte BIP-39 seed
entropy = m.to_entropy(phrase) # recover original entropy
restored = m.from_entropy(entropy) # back to phrase
# Other languages
m_jp = MnemonicManager("japanese")
phrase_jp = m_jp.generate(12)
Key Pair & Accounts
from neo_n3_wallet import KeyPair, Account
# Random key pair
kp = KeyPair.generate()
print(kp.address) # Neo N3 address
print(kp.public_key_hex) # 33-byte compressed public key
print(kp.to_wif()) # WIF-encoded private key
# From WIF
kp2 = KeyPair.from_wif("KwdMAjGmer...")
# Sign & verify
sig = kp.sign(b"my message")
assert kp.verify(b"my message", sig)
# Account with NEP-2 encryption
acct = Account.from_private_key(bytes.fromhex("..."))
nep2 = acct.encrypt("my-passphrase") # encrypt in-place
acct.lock() # wipe key from memory
acct.unlock("my-passphrase") # restore it
HD Derivation Paths
Neo N3 uses SLIP-0044 coin type 888 and secp256r1:
m / 44' / 888' / account' / change / index
Wallet.derivation_path(account=0, change=0, index=0)
# → "m/44'/888'/0'/0/0"
Running Tests
python -m pytest tests/ -v --no-cov # fast
python -m pytest tests/ -v # with coverage
Project Layout
neo_n3_wallet/
├── __init__.py public API
├── wallet.py Wallet (HD + NEP-6)
├── account.py Account (NEP-2 lock/unlock)
├── key_pair.py KeyPair (sign / verify)
├── mnemonic.py BIP-39 MnemonicManager
├── hd.py BIP-32 derivation (secp256r1)
├── nep2.py NEP-2 encrypt / decrypt
├── wif.py WIF encode / decode
├── address.py Neo N3 address utilities
├── crypto.py secp256r1 primitives
├── constants.py Neo N3 constants
└── exceptions.py Custom exceptions
License
Apache 2.0
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neo_n3_wallet-0.2.1.tar.gz.
File metadata
- Download URL: neo_n3_wallet-0.2.1.tar.gz
- Upload date:
- Size: 32.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5b11c217c9e7d4c91510ab53416e77644d1a95a88b4d6708cedb2777771e8e8
|
|
| MD5 |
480cb2c66bb7efdb86f5412c8cff20f9
|
|
| BLAKE2b-256 |
1039936dc86700c6bce1d6a89464d92b4e52a58907c75a656ec1d9658299bf6f
|
File details
Details for the file neo_n3_wallet-0.2.1-py3-none-any.whl.
File metadata
- Download URL: neo_n3_wallet-0.2.1-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a5a3545a34ab7355d1c8c9534a04504ff29ddede17fd564b3e18962e045fe880
|
|
| MD5 |
047e54e1e572679cdb868de8cb729cc5
|
|
| BLAKE2b-256 |
329dda1a81fffb9f571df1742bee0680601e1157b84a24bac9dc488558d3bd2f
|