diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b2051225..a92c18c6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,9 +28,9 @@ jobs: - name: Install dependencies run: | poetry install - - name: Lint with flake8 + - name: Run static analyses run: | - poetry run flake8 pycardano + make qa - name: Run unit tests run: | poetry run pytest --doctest-modules --ignore=examples --cov=pycardano --cov-config=.coveragerc --cov-report=xml diff --git a/Makefile b/Makefile index 3c42464d..4b3cbf67 100644 --- a/Makefile +++ b/Makefile @@ -60,8 +60,9 @@ test: ## runs tests test-single: ## runs tests with "single" markers poetry run pytest -s -vv -m single -qa: ## runs static analysis with flake8 +qa: ## runs static analyses poetry run flake8 pycardano + poetry run mypy --install-types --non-interactive pycardano format: ## runs code style and formatter poetry run isort . diff --git a/poetry.lock b/poetry.lock index ac696d6b..5bb34053 100644 --- a/poetry.lock +++ b/poetry.lock @@ -29,7 +29,7 @@ tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900 tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] -name = "Babel" +name = "babel" version = "2.10.3" description = "Internationalization utilities" category = "dev" @@ -141,11 +141,11 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" -version = "0.4.5" +version = "0.4.6" description = "Cross-platform colored terminal text." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" [[package]] name = "cose" @@ -227,7 +227,7 @@ gmpy = ["gmpy"] gmpy2 = ["gmpy2"] [[package]] -name = "ECPy" +name = "ecpy" version = "1.2.5" description = "Pure Pyhton Elliptic Curve Library" category = "main" @@ -260,7 +260,7 @@ pycodestyle = ">=2.9.0,<2.10.0" pyflakes = ">=2.5.0,<2.6.0" [[package]] -name = "Flask" +name = "flask" version = "2.2.2" description = "A simple framework for building complex web applications." category = "dev" @@ -341,7 +341,7 @@ optional = false python-versions = ">=3.7" [[package]] -name = "Jinja2" +name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." category = "dev" @@ -355,7 +355,7 @@ MarkupSafe = ">=2.0" i18n = ["Babel (>=2.7)"] [[package]] -name = "MarkupSafe" +name = "markupsafe" version = "2.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" @@ -378,6 +378,25 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "mypy" +version = "0.982" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + [[package]] name = "mypy-extensions" version = "0.4.3" @@ -484,7 +503,7 @@ optional = false python-versions = ">=3.6" [[package]] -name = "Pygments" +name = "pygments" version = "2.13.0" description = "Pygments is a syntax highlighting package written in Python." category = "dev" @@ -495,7 +514,7 @@ python-versions = ">=3.6" plugins = ["importlib-metadata"] [[package]] -name = "PyNaCl" +name = "pynacl" version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" category = "main" @@ -588,7 +607,7 @@ testing = ["filelock"] [[package]] name = "pytz" -version = "2022.4" +version = "2022.5" description = "World timezone definitions, modern and historical" category = "dev" optional = false @@ -626,7 +645,7 @@ py = ">=1.4.26,<2.0.0" [[package]] name = "setuptools" -version = "65.4.1" +version = "65.5.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "dev" optional = false @@ -654,7 +673,7 @@ optional = false python-versions = "*" [[package]] -name = "Sphinx" +name = "sphinx" version = "4.3.2" description = "Python documentation generator" category = "dev" @@ -849,7 +868,7 @@ optional = ["python-socks", "wsaccel"] test = ["websockets"] [[package]] -name = "Werkzeug" +name = "werkzeug" version = "2.2.2" description = "The comprehensive WSGI web application library." category = "dev" @@ -864,7 +883,7 @@ watchdog = ["watchdog"] [[package]] name = "zipp" -version = "3.9.0" +version = "3.10.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false @@ -877,7 +896,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "aaf69be3861ac1e76a5b23ae5cc705ba0eb636dedb8d9511f553ebace7eaa919" +content-hash = "c4bdd6a7f5302d4c06ee5a97b8ddf3fc85df270cbf3f20d2e8981187d7b8ecfa" [metadata.files] alabaster = [ @@ -892,7 +911,7 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] -Babel = [ +babel = [ {file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"}, {file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"}, ] @@ -1036,8 +1055,8 @@ click = [ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [ - {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"}, - {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"}, + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] cose = [ {file = "cose-0.9.dev8-py3-none-any.whl", hash = "sha256:f1c3be98e50724e846e3a1d23efe19a150665a4f24917ac8bfbc8e5abb31ccb0"}, @@ -1135,7 +1154,7 @@ ecdsa = [ {file = "ecdsa-0.18.0-py2.py3-none-any.whl", hash = "sha256:80600258e7ed2f16b9aa1d7c295bd70194109ad5a30fdee0eaeefef1d4c559dd"}, {file = "ecdsa-0.18.0.tar.gz", hash = "sha256:190348041559e21b22a1d65cee485282ca11a6f81d503fddb84d5017e9ed1e49"}, ] -ECPy = [ +ecpy = [ {file = "ECPy-1.2.5-py3-none-any.whl", hash = "sha256:559c92e42406d9d1a6b2b8fc26e6ad7bc985f33903b72f426a56cb1073a25ce3"}, {file = "ECPy-1.2.5.tar.gz", hash = "sha256:9635cffb9b6ecf7fd7f72aea1665829ac74a1d272006d0057d45a621aae20228"}, ] @@ -1147,7 +1166,7 @@ flake8 = [ {file = "flake8-5.0.4-py2.py3-none-any.whl", hash = "sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248"}, {file = "flake8-5.0.4.tar.gz", hash = "sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db"}, ] -Flask = [ +flask = [ {file = "Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"}, {file = "Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"}, ] @@ -1175,11 +1194,11 @@ itsdangerous = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, ] -Jinja2 = [ +jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] -MarkupSafe = [ +markupsafe = [ {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"}, {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"}, {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"}, @@ -1229,6 +1248,32 @@ mnemonic = [ {file = "mnemonic-0.20-py3-none-any.whl", hash = "sha256:acd2168872d0379e7a10873bb3e12bf6c91b35de758135c4fbd1015ef18fafc5"}, {file = "mnemonic-0.20.tar.gz", hash = "sha256:7c6fb5639d779388027a77944680aee4870f0fcd09b1e42a5525ee2ce4c625f6"}, ] +mypy = [ + {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, + {file = "mypy-0.982-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:41fd1cf9bc0e1c19b9af13a6580ccb66c381a5ee2cf63ee5ebab747a4badeba3"}, + {file = "mypy-0.982-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f793e3dd95e166b66d50e7b63e69e58e88643d80a3dcc3bcd81368e0478b089c"}, + {file = "mypy-0.982-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ebe67adf4d021b28c3f547da6aa2cce660b57f0432617af2cca932d4d378a6"}, + {file = "mypy-0.982-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:175f292f649a3af7082fe36620369ffc4661a71005aa9f8297ea473df5772046"}, + {file = "mypy-0.982-cp310-cp310-win_amd64.whl", hash = "sha256:8ee8c2472e96beb1045e9081de8e92f295b89ac10c4109afdf3a23ad6e644f3e"}, + {file = "mypy-0.982-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58f27ebafe726a8e5ccb58d896451dd9a662a511a3188ff6a8a6a919142ecc20"}, + {file = "mypy-0.982-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6af646bd46f10d53834a8e8983e130e47d8ab2d4b7a97363e35b24e1d588947"}, + {file = "mypy-0.982-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7aeaa763c7ab86d5b66ff27f68493d672e44c8099af636d433a7f3fa5596d40"}, + {file = "mypy-0.982-cp37-cp37m-win_amd64.whl", hash = "sha256:724d36be56444f569c20a629d1d4ee0cb0ad666078d59bb84f8f887952511ca1"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14d53cdd4cf93765aa747a7399f0961a365bcddf7855d9cef6306fa41de01c24"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ae64555d480ad4b32a267d10cab7aec92ff44de35a7cd95b2b7cb8e64ebe3e"}, + {file = "mypy-0.982-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6389af3e204975d6658de4fb8ac16f58c14e1bacc6142fee86d1b5b26aa52bda"}, + {file = "mypy-0.982-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b35ce03a289480d6544aac85fa3674f493f323d80ea7226410ed065cd46f206"}, + {file = "mypy-0.982-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6e564f035d25c99fd2b863e13049744d96bd1947e3d3d2f16f5828864506763"}, + {file = "mypy-0.982-cp38-cp38-win_amd64.whl", hash = "sha256:cebca7fd333f90b61b3ef7f217ff75ce2e287482206ef4a8b18f32b49927b1a2"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a705a93670c8b74769496280d2fe6cd59961506c64f329bb179970ff1d24f9f8"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75838c649290d83a2b83a88288c1eb60fe7a05b36d46cbea9d22efc790002146"}, + {file = "mypy-0.982-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:91781eff1f3f2607519c8b0e8518aad8498af1419e8442d5d0afb108059881fc"}, + {file = "mypy-0.982-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa97b9ddd1dd9901a22a879491dbb951b5dec75c3b90032e2baa7336777363b"}, + {file = "mypy-0.982-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a692a8e7d07abe5f4b2dd32d731812a0175626a90a223d4b58f10f458747dd8a"}, + {file = "mypy-0.982-cp39-cp39-win_amd64.whl", hash = "sha256:eb7a068e503be3543c4bd329c994103874fa543c1727ba5288393c21d912d795"}, + {file = "mypy-0.982-py3-none-any.whl", hash = "sha256:1021c241e8b6e1ca5a47e4d52601274ac078a89845cfde66c6d5f769819ffa1d"}, + {file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, @@ -1273,11 +1318,11 @@ pyflakes = [ {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"}, {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] -Pygments = [ +pygments = [ {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, ] -PyNaCl = [ +pynacl = [ {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, @@ -1310,8 +1355,8 @@ pytest-xdist = [ {file = "pytest_xdist-2.5.0-py3-none-any.whl", hash = "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65"}, ] pytz = [ - {file = "pytz-2022.4-py2.py3-none-any.whl", hash = "sha256:2c0784747071402c6e99f0bafdb7da0fa22645f06554c7ae06bf6358897e9c91"}, - {file = "pytz-2022.4.tar.gz", hash = "sha256:48ce799d83b6f8aab2020e369b627446696619e79645419610b9facd909b3174"}, + {file = "pytz-2022.5-py2.py3-none-any.whl", hash = "sha256:335ab46900b1465e714b4fda4963d87363264eb662aab5e65da039c25f1f5b22"}, + {file = "pytz-2022.5.tar.gz", hash = "sha256:c4d88f472f54d615e9cd582a5004d1e5f624854a6a27a6211591c251f22a6914"}, ] requests = [ {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, @@ -1322,8 +1367,8 @@ retry = [ {file = "retry-0.9.2.tar.gz", hash = "sha256:f8bfa8b99b69c4506d6f5bd3b0aabf77f98cdb17f3c9fc3f5ca820033336fba4"}, ] setuptools = [ - {file = "setuptools-65.4.1-py3-none-any.whl", hash = "sha256:1b6bdc6161661409c5f21508763dc63ab20a9ac2f8ba20029aaaa7fdb9118012"}, - {file = "setuptools-65.4.1.tar.gz", hash = "sha256:3050e338e5871e70c72983072fe34f6032ae1cdeeeb67338199c2f74e083a80e"}, + {file = "setuptools-65.5.0-py3-none-any.whl", hash = "sha256:f62ea9da9ed6289bfe868cd6845968a2c854d1427f8548d52cae02a42b4f0356"}, + {file = "setuptools-65.5.0.tar.gz", hash = "sha256:512e5536220e38146176efb833d4a62aa726b7bbff82cfbc8ba9eaa3996e0b17"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -1333,7 +1378,7 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] -Sphinx = [ +sphinx = [ {file = "Sphinx-4.3.2-py3-none-any.whl", hash = "sha256:6a11ea5dd0bdb197f9c2abc2e0ce73e01340464feaece525e64036546d24c851"}, {file = "Sphinx-4.3.2.tar.gz", hash = "sha256:0a8836751a68306b3fe97ecbe44db786f8479c3bf4b80e3a7f5c838657b4698c"}, ] @@ -1415,11 +1460,11 @@ websocket-client = [ {file = "websocket-client-1.4.1.tar.gz", hash = "sha256:f9611eb65c8241a67fb373bef040b3cf8ad377a9f6546a12b620b6511e8ea9ef"}, {file = "websocket_client-1.4.1-py3-none-any.whl", hash = "sha256:398909eb7e261f44b8f4bd474785b6ec5f5b499d4953342fe9755e01ef624090"}, ] -Werkzeug = [ +werkzeug = [ {file = "Werkzeug-2.2.2-py3-none-any.whl", hash = "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"}, {file = "Werkzeug-2.2.2.tar.gz", hash = "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f"}, ] zipp = [ - {file = "zipp-3.9.0-py3-none-any.whl", hash = "sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980"}, - {file = "zipp-3.9.0.tar.gz", hash = "sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb"}, + {file = "zipp-3.10.0-py3-none-any.whl", hash = "sha256:4fcb6f278987a6605757302a6e40e896257570d11c51628968ccb2a47e80c6c1"}, + {file = "zipp-3.10.0.tar.gz", hash = "sha256:7a7262fd930bd3e36c50b9a64897aec3fafff3dfdeec9623ae22b40e93f99bb8"}, ] diff --git a/pycardano/crypto/bip32.py b/pycardano/crypto/bip32.py index 25e59eaa..3095666b 100644 --- a/pycardano/crypto/bip32.py +++ b/pycardano/crypto/bip32.py @@ -11,7 +11,7 @@ import hmac import unicodedata from binascii import hexlify, unhexlify -from typing import Optional +from typing import Optional, Tuple from mnemonic import Mnemonic from nacl import bindings @@ -82,24 +82,18 @@ class HDWallet: def __init__( self, + root_xprivate_key: bytes, + root_public_key: bytes, + root_chain_code: bytes, + xprivate_key: bytes, + public_key: bytes, + chain_code: bytes, + path: str = "m", seed: Optional[bytes] = None, mnemonic: Optional[str] = None, passphrase: Optional[str] = None, entropy: Optional[str] = None, - root_xprivate_key: Optional[bytes] = None, - root_public_key: Optional[bytes] = None, - root_chain_code: Optional[bytes] = None, - xprivate_key: Optional[bytes] = None, - public_key: Optional[bytes] = None, - chain_code: Optional[bytes] = None, - path: Optional[str] = None, ): - - self._seed = seed - self._mnemonic = mnemonic - self._passphrase = passphrase - self._entropy = entropy - self._root_xprivate_key = root_xprivate_key self._root_public_key = root_public_key self._root_chain_code = root_chain_code @@ -108,7 +102,12 @@ def __init__( self._public_key = public_key self._chain_code = chain_code - self._path = path if path else "m" + self._path = path + + self._seed = seed + self._mnemonic = mnemonic + self._passphrase = passphrase + self._entropy = entropy @classmethod def from_seed( @@ -131,8 +130,8 @@ def from_seed( HDWallet -- Hierarchical Deterministic Wallet instance. """ - seed = bytearray(bytes.fromhex(seed)) - seed_modified = cls._tweak_bits(seed) + seed_converted = bytearray(bytes.fromhex(seed)) + seed_modified = cls._tweak_bits(seed_converted) kL, c = seed_modified[:32], seed_modified[64:] @@ -140,16 +139,16 @@ def from_seed( A = bindings.crypto_scalarmult_ed25519_base_noclamp(kL) return cls( - seed=seed_modified, - mnemonic=mnemonic, - entropy=entropy, - passphrase=passphrase, root_xprivate_key=seed_modified[:64], root_public_key=A, root_chain_code=c, xprivate_key=seed_modified[:64], public_key=A, chain_code=c, + seed=seed_modified, + mnemonic=mnemonic, + passphrase=passphrase, + entropy=entropy, ) @classmethod @@ -241,17 +240,17 @@ def _copy_hdwallet(self): """ return HDWallet( - self._seed, - self._mnemonic, - self._passphrase, - self._entropy, - self._root_xprivate_key, - self._root_public_key, - self._root_chain_code, - self._xprivate_key, - self._public_key, - self._chain_code, - self._path, + root_xprivate_key=self._root_xprivate_key, + root_public_key=self._root_public_key, + root_chain_code=self._root_chain_code, + xprivate_key=self._xprivate_key, + public_key=self._public_key, + chain_code=self._chain_code, + path=self._path, + seed=self._seed, + mnemonic=self._mnemonic, + passphrase=self._passphrase, + entropy=self._entropy, ) def derive_from_path(self, path: str, private: bool = True) -> HDWallet: @@ -329,29 +328,25 @@ def derive( if hardened: index += 2**31 - # derive private child key if private: - node = ( + private_node = ( self._xprivate_key[:32], self._xprivate_key[32:], self._public_key, self._chain_code, self._path, ) - derived_hdwallet = self._derive_private_child_key_by_index(node, index) - # derive public child key - else: - node = ( - self._public_key, - self._chain_code, - self._path, - ) - derived_hdwallet = self._derive_public_child_key_by_index(node, index) + return self._derive_private_child_key_by_index(private_node, index) - return derived_hdwallet + public_node = ( + self._public_key, + self._chain_code, + self._path, + ) + return self._derive_public_child_key_by_index(public_node, index) def _derive_private_child_key_by_index( - self, private_pnode: (bytes, bytes, bytes, bytes, str), index: int + self, private_pnode: Tuple[bytes, bytes, bytes, bytes, str], index: int ) -> HDWallet: """ Derive private child keys from parent node. @@ -391,10 +386,6 @@ def _derive_private_child_key_by_index( HDWallet with child node derived. """ - - if not private_pnode: - return None - # unpack argument (kLP, kRP, AP, cP, path) = private_pnode assert 0 <= index < 2**32 @@ -429,19 +420,23 @@ def _derive_private_child_key_by_index( path += "/" + str(index) derived_hdwallet = HDWallet( + root_xprivate_key=self._root_xprivate_key, + root_public_key=self._root_public_key, + root_chain_code=self._root_chain_code, xprivate_key=kL + kR, public_key=A, chain_code=c, path=path, - root_xprivate_key=self.root_xprivate_key, - root_public_key=self.root_public_key, - root_chain_code=self.root_chain_code, + seed=self._seed, + mnemonic=self._mnemonic, + passphrase=self._passphrase, + entropy=self._entropy, ) return derived_hdwallet def _derive_public_child_key_by_index( - self, public_pnode: (bytes, bytes, str), index: int + self, public_pnode: Tuple[bytes, bytes, str], index: int ) -> HDWallet: """ Derive public child keys from parent node. @@ -453,10 +448,6 @@ def _derive_public_child_key_by_index( Returns: HDWallet with child node derived. """ - - if not public_pnode: - return None - # unpack argument (AP, cP, path) = public_pnode assert 0 <= index < 2**32 @@ -489,12 +480,17 @@ def _derive_public_child_key_by_index( path += "/" + str(index) derived_hdwallet = HDWallet( + root_xprivate_key=self._root_xprivate_key, + root_public_key=self._root_public_key, + root_chain_code=self._root_chain_code, + xprivate_key=self._xprivate_key, public_key=A, chain_code=c, path=path, - root_xprivate_key=self.root_xprivate_key, - root_public_key=self.root_public_key, - root_chain_code=self.root_chain_code, + seed=self._seed, + mnemonic=self._mnemonic, + passphrase=self._passphrase, + entropy=self._entropy, ) return derived_hdwallet @@ -575,11 +571,11 @@ def is_mnemonic(mnemonic: str, language: Optional[str] = None) -> bool: for _language in SUPPORTED_MNEMONIC_LANGS: if Mnemonic(language=_language).check(mnemonic=mnemonic) is True: return True - return False except ValueError: logger.warning( "The input mnemonic words are not valid. Words should be in string format seperated by space." ) + return False @staticmethod def is_entropy(entropy: str) -> bool: diff --git a/pyproject.toml b/pyproject.toml index b4c71b5c..2a719e34 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ sphinx-copybutton = "^0.5.0" retry = "^0.9.2" Flask = "^2.0.3" pytest-xdist = "^2.5.0" +mypy = "^0.982" [build-system] requires = ["poetry-core>=1.0.0"] @@ -59,3 +60,30 @@ markers = [ [tool.isort] profile = "black" + +[tool.mypy] +ignore_missing_imports = true +python_version = 3.7 +exclude = [ + '^pycardano/backend/base.py$', + '^pycardano/backend/blockfrost.py$', + '^pycardano/backend/ogmios.py$', + '^pycardano/cip/cip8.py$', + '^pycardano/crypto/bech32.py$', + '^pycardano/address.py$', + '^pycardano/certificate.py$', + '^pycardano/coinselection.py$', + '^pycardano/exception.py$', + '^pycardano/hash.py$', + '^pycardano/key.py$', + '^pycardano/logging.py$', + '^pycardano/metadata.py$', + '^pycardano/nativescript.py$', + '^pycardano/network.py$', + '^pycardano/plutus.py$', + '^pycardano/serialization.py$', + '^pycardano/transaction.py$', + '^pycardano/txbuilder.py$', + '^pycardano/utils.py$', + '^pycardano/witness.py$', +]