Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
649dc18
Work toward raw hex seeds for SLIP-39 derivation support
pjkundert Jul 19, 2025
80f92dd
Begin adding SLIP39 entropy and seed support
pjkundert Jul 19, 2025
3307093
Initial entropies.slip39 tests pass
pjkundert Jul 19, 2025
3f16a21
Progress toward SLIP39 entropy
pjkundert Jul 20, 2025
3933945
Test BIP-39 and raw hex SLIP-39 seeds
pjkundert Jul 20, 2025
6f93825
Get Nix and venv environment automation and install working
pjkundert Aug 15, 2025
efb9b94
Seeds support raw entropy generally; support SLIP39 seeds
pjkundert Aug 16, 2025
729ad1c
Begin to implement SLIP39 mnemonics w/ language specifying specs
pjkundert Aug 18, 2025
f7c831e
Working implementation of SLIP39 Mnemonics
pjkundert Aug 19, 2025
a8a5e5e
Improve SLIP39 Mnemonic support, and general wordlist handling
pjkundert Aug 20, 2025
3d4208a
Clean up multi-mnemonic handling for SLIP-39
pjkundert Aug 20, 2025
8ceedf1
Update version to 3.7.0 and add to CHANGELOG.md
pjkundert Aug 20, 2025
07ff88e
Update shamir_mnemonic for compatibility with new recovery APIs
pjkundert Aug 21, 2025
3ea38dd
Clean up, add analyze target
pjkundert Aug 21, 2025
bcd1cda
Implement SLIP39Mnemonic.encode tabulate for human readable mnemonics
pjkundert Aug 22, 2025
3da7a72
Fix remaining whitespace, etc. issues found by analyze target
pjkundert Aug 21, 2025
c5bec4e
Begin attempt to match unambiguous abbrevs
pjkundert Aug 29, 2025
28bbc26
Support abbreviations and optional UTF-8 "Marks" for mnemonic languages
pjkundert Sep 12, 2025
410d86a
Ensure ambiguity is detected, and resolved w/ preferred language
pjkundert Sep 12, 2025
2722610
Rendering of Trie, work toward korean language support
pjkundert Sep 16, 2025
2b46f39
Passing BIP-39 unit tests
pjkundert Sep 16, 2025
949a0c4
Progress toward passing all tests; restore custom words_list function…
pjkundert Sep 26, 2025
f72194a
Progress toward preferred language for mnemonics
pjkundert Sep 30, 2025
77941d6
Correct Electrum V2 mnemonic type detection
pjkundert Sep 30, 2025
17e8838
Improve handling of electrum word lists, cache wordlist indices
pjkundert Oct 3, 2025
445d3e8
Correct handling of Monero mnemonic checksum Unicode normalization
pjkundert Oct 3, 2025
03cef22
Ensure language is passed through in generate mnemonic CLI
pjkundert Oct 3, 2025
2929e81
Clean up some test output
pjkundert Oct 4, 2025
eb964fd
Begin work toward mypy type checking
pjkundert Oct 4, 2025
be6236c
Improve memory of SLIP-39 language encoding
pjkundert Oct 5, 2025
a3b4c23
Fix static analysis, add examples/mnemonics/slip39.py
pjkundert Oct 6, 2025
0f0325f
Begin working through some mypy typing issues
pjkundert Oct 6, 2025
7d507d5
Implement IMnemonic.collect to support collecting a mnemonic word
pjkundert Oct 7, 2025
2a3adb4
Remove some pytest output, and some unnecessary Electrum v2 validity …
pjkundert Oct 22, 2025
8ed1b2f
Correct IMnemonic.decode implementations to try all possible languages
pjkundert Oct 25, 2025
6bdd84c
Upgrade tabulate to tabulate-slip39 for downstream projects
pjkundert Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,8 @@ __pycache__/

# py.test stuff
.pytest_cache/

# NixOS stuff
flake.lock
CLAUDE.md
.claude
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Changelog

## [v3.7.0](https://github.com/hdwallet-io/python-hdwallet/tree/v3.7.0) (2025-08-20)

[Full Changelog](https://github.com/hdwallet-io/python-hdwallet/compare/v3.6.1...v3.7.0)

**New Additions:**

- Add: SLIP-39 mnemonic and seed support with multi-language wordlist handling
- Add: Raw entropy support for SLIP-39 seeds

**Enhancements:**

- Improve: SLIP-39 mnemonic implementation and multi-mnemonic handling

## [v3.6.1](https://github.com/hdwallet-io/python-hdwallet/tree/v3.6.1) (2025-08-04)

[Full Changelog](https://github.com/hdwallet-io/python-hdwallet/compare/v3.6.0...v3.6.1)
Expand Down
23 changes: 22 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ with the owners of this repository before making a change.

## Development

To get started, just fork this repo, clone it locally, and run:
### Using Nix (Recommended)

The easiest way to get a complete development environment is to use Nix. This approach provides the correct Python version and all dependencies automatically.

If you have Nix installed, you can get a full development/runtime environment by running:

```
make nix-venv
```

This will activate an interactive shell with the Nix environment and Python virtual environment set up.

To run specific commands in the Nix + venv environment, use the pattern `make nix-venv-target`:

```
make nix-venv-test # Run tests in Nix + venv environment
make nix-venv-install # Install package in Nix + venv environment
```

### Manual Setup

Alternatively, you can set up the development environment manually. Fork this repo, clone it locally, and run:

```
pip install -e .[cli,tests,docs]
Expand Down
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
include LICENSE
include README.md
include requirements.txt
include requirements/cli.txt
include requirements/tests.txt
include requirements/docs.txt
include requirements/dev.txt

recursive-include hdwallet/mnemonics/algorand/wordlist *.txt
recursive-include hdwallet/mnemonics/bip39/wordlist *.txt
recursive-include hdwallet/mnemonics/slip39/wordlist *.txt
recursive-include hdwallet/mnemonics/electrum/v1/wordlist *.txt
recursive-include hdwallet/mnemonics/electrum/v2/wordlist *.txt
recursive-include hdwallet/mnemonics/monero/wordlist *.txt
Expand Down
100 changes: 94 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,18 +1,106 @@
# Minimal makefile for Sphinx documentation
# Minimal makefile for Sphinx documentation, Nix and venv
#

SHELL := /bin/bash

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = docs
BUILDDIR = build
export SPHINXOPTS ?=
export SPHINXBUILD ?= sphinx-build
export SOURCEDIR = docs
export BUILDDIR = build

export PYTHON ?= $(shell python3 --version >/dev/null 2>&1 && echo python3 || echo python )

# Ensure $(PYTHON), $(VENV) are re-evaluated at time of expansion, when target 'python' and 'poetry' are known to be available
PYTHON_V = $(shell $(PYTHON) -c "import sys; print('-'.join((('venv' if sys.prefix != sys.base_prefix else next(iter(filter(None,sys.base_prefix.split('/'))))),sys.platform,sys.implementation.cache_tag)))" 2>/dev/null )

export PYTEST ?= $(PYTHON) -m pytest
export PYTEST_OPTS ?= # -vv --capture=no


VERSION = $(shell $(PYTHON) -c "exec(open('hdwallet/info.py').read()); print(__version__[1:])" )
WHEEL = dist/hdwallet-$(VERSION)-py3-none-any.whl
VENV = $(CURDIR)-$(VERSION)-$(PYTHON_V)

# Force export of variables that might be set from command line
export VENV_OPTS ?=
export NIX_OPTS ?=

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile
.PHONY: help wheel install test analyze types venv Makefile FORCE


wheel: $(WHEEL)

$(WHEEL): FORCE
$(PYTHON) -m build
@ls -last dist

# Install from wheel, including all optional extra dependencies (doesn't include dev)
install: $(WHEEL) FORCE
$(PYTHON) -m pip install --force-reinstall $<[cli,tests,docs]

# Install from requirements/*; eg. install-dev, always getting the latest version
install-%: FORCE
$(PYTHON) -m pip install --upgrade -r requirements/$*.txt


unit-%:
$(PYTEST) $(PYTEST_OPTS) -k $*

test:
$(PYTEST) $(PYTEST_OPTS) tests

analyze:
$(PYTHON) -m flake8 --color never -j 1 --max-line-length=250 \
--ignore=W503,W504,E201,E202,E223,E226 \
hdwallet

types:
mypy .

#
# Nix and VirtualEnv build, install and activate
#
# Create, start and run commands in "interactive" shell with a python venv's activate init-file.
# Doesn't allow recursive creation of a venv with a venv-supplied python. Alters the bin/activate
# to include the user's .bashrc (eg. Git prompts, aliases, ...). Use to run Makefile targets in a
# proper context, for example to obtain a Nix environment containing the proper Python version,
# create a python venv with the current Python environment.
#
# make nix-venv-build
#
nix-%:
@if [ -r flake.nix ]; then \
nix develop $(NIX_OPTS) --command make $*; \
else \
nix-shell $(NIX_OPTS) --run "make $*"; \
fi

venv-%: $(VENV)
@echo; echo "*** Running in $< VirtualEnv: make $*"
@bash --init-file $</bin/activate -ic "make $*"

venv: $(VENV)
@echo; echo "*** Activating $< VirtualEnv for Interactive $(SHELL)"
@bash --init-file $</bin/activate -i

$(VENV):
@[[ "$(PYTHON_V)" =~ "^venv" ]] && ( echo -e "\n\n!!! $@ Cannot start a venv within a venv"; false ) || true
@echo; echo "*** Building $@ VirtualEnv..."
@rm -rf $@ && $(PYTHON) -m venv $(VENV_OPTS) $@ && sed -i -e '1s:^:. $$HOME/.bashrc\n:' $@/bin/activate \
&& source $@/bin/activate \
&& make install-dev install

print-%:
@echo $* = $($*)
@echo $*\'s origin is $(origin $*)



# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ Python-based library implementing a Hierarchical Deterministic (HD) Wallet gener
| Features | Protocols |
|:------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Cryptocurrencies | <a href="https://hdwallet.io/cryptocurrencies">#supported-cryptocurrencies</a> |
| Entropies | `Algorand`, `BIP39`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Mnemonics | `Algorand`, `BIP39`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Seeds | `Algorand`, `BIP39`, `Cardano`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Entropies | `Algorand`, `BIP39`, `SLIP39`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Mnemonics | `Algorand`, `BIP39`, `SLIP39`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Seeds | `Algorand`, `BIP39`, `SLIP39`, `Cardano`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Elliptic Curve Cryptography's | `Kholaw-Ed25519`, `SLIP10-Ed25519`, `SLIP10-Ed25519-Blake2b`, `SLIP10-Ed25519-Monero`, `SLIP10-Nist256p1`, `SLIP10-Secp256k1` |
| Hierarchical Deterministic's | `Algorand`, `BIP32`, `BIP44`, `BIP49`, `BIP84`, `BIP86`, `BIP141`, `Cardano`, `Electrum-V1`, `Electrum-V2`, `Monero` |
| Derivations | `BIP44`, `BIP49`, `BIP84`, `BIP86`, `CIP1852`, `Custom`, `Electrum`, `Monero`, `HDW (Our own custom derivation)` |
Expand Down
92 changes: 92 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
{ pkgs ? import ./nixpkgs.nix {} }:

with pkgs;

let
in
{
py314 = stdenv.mkDerivation rec {
name = "python314-with-poetry";

buildInputs = [
cacert
git
gnumake
openssh
python314
python314Packages.pytest
python314Packages.coincurve
python314Packages.scikitlearn
python314Packages.pycryptodome
python314Packages.pynacl
];
};

py313 = stdenv.mkDerivation rec {
name = "python313-with-poetry";

buildInputs = [
cacert
git
gnumake
openssh
python313
python313Packages.pytest
python313Packages.coincurve
python313Packages.scikitlearn
python313Packages.pycryptodome
python313Packages.pynacl
];
};

py312 = stdenv.mkDerivation rec {
name = "python312-with-poetry";

buildInputs = [
cacert
git
gnumake
openssh
python312
python312Packages.pytest
python312Packages.coincurve
python312Packages.scikitlearn
python312Packages.pycryptodome
python312Packages.pynacl
];
};

py311 = stdenv.mkDerivation rec {
name = "python311-with-poetry";

buildInputs = [
cacert
git
gnumake
openssh
python311
python311Packages.pytest
python311Packages.coincurve
python311Packages.scikitlearn
python311Packages.pycryptodome
python311Packages.pynacl
];
};

py310 = stdenv.mkDerivation rec {
name = "python310-with-poetry";

buildInputs = [
cacert
git
gnumake
openssh
python310
python310Packages.pytest
python310Packages.coincurve
python310Packages.scikitlearn
python310Packages.pycryptodome
python310Packages.pynacl
];
};
}
2 changes: 1 addition & 1 deletion examples/hdwallet/bips/from_entropy.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
BIP39Entropy, BIP39_ENTROPY_STRENGTHS
)
from hdwallet.mnemonics import BIP39_MNEMONIC_LANGUAGES
from hdwallet.cryptocurrencies import Qtum as Cryptocurrency
from hdwallet.cryptocurrencies import Bitcoin as Cryptocurrency
from hdwallet.consts import PUBLIC_KEY_TYPES
from hdwallet.derivations import (
BIP44Derivation, CHANGES
Expand Down
Loading