Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hierarchical Deterministic Wallet Implementation #85

Merged
merged 57 commits into from
Oct 6, 2022

Conversation

henryyuanheng-wang
Copy link
Contributor

HDWallet that supports generation of private keys, public keys and chain codes for Shelley Address. Changes include:

  • poycardano/hdwallet.py: HDWallet class definition and functions, including ingestion of seed, mnemonic words and entropy. Can derive keys based on index or derivation path.

  • test/pycardano/test_hdwallet: test and verify address generation from implementation. Test cases are copied from cardano-seriliazation-lib.

  • pyproject.toml/poetry.lock: add mnemonic and ecpy dependencies.

Yuanheng Wang and others added 30 commits February 19, 2022 23:51
Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.0.1 to 7.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](pytest-dev/pytest@7.0.1...7.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@codecov-commenter
Copy link

codecov-commenter commented Sep 18, 2022

Codecov Report

Base: 85.86% // Head: 85.76% // Decreases project coverage by -0.09% ⚠️

Coverage data is based on head (80b4373) compared to base (919e796).
Patch coverage: 50.00% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #85      +/-   ##
==========================================
- Coverage   85.86%   85.76%   -0.10%     
==========================================
  Files          22       22              
  Lines        2440     2445       +5     
  Branches      554      555       +1     
==========================================
+ Hits         2095     2097       +2     
- Misses        253      256       +3     
  Partials       92       92              
Impacted Files Coverage Δ
pycardano/key.py 86.61% <50.00%> (-1.71%) ⬇️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@robinboening
Copy link

Thanks for working on this! I haven't tried your branch, but by looking through the code it looks nice and clean to me 👍

Copy link
Collaborator

@cffls cffls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Henry for raising this PR, this is really amazing! Looks pretty good in general. I added a few minor comments.

One thing to consider is to integrate this with the existing extended public key and signing key in PyCardano. I am thinking about adding a method to_extended_signing_key() in HDWallet. Don't feel the pressure to add it in this PR. We can do it in future PRs.


return self

def from_mnemonic(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is better to be a classmethod?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Jerry for taking the time to review! Yeah I was actually thinking of turning those into classmethods. I'll make the modifications.

self._depth: int = 0
self._index: int = 0

def from_seed(self, seed: str) -> "HDWallet":
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as from_mnemonic, this could be a classmethod.

Comment on lines 301 to 305
self._xprivate_key = (kL, kR)
self._public_key = A
self._chain_code = c

return self
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may be more intuitive to return a new instance of HDWallet rather than changing the current one and returning self, so people can keep keys derived from different paths at the same time. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a a good question. I was thinking of keeping derive_from_path and derive_from_index to have similar behavior - for user to call derive_from_index, they may call the function multiple times, so I was thinking of modifying the keys in place while keeping the extended keys intact. Definitely interested in chatting more on this and figure out the most intuitive implementation :)

# Tests copied from: https://github.com/Emurgo/cardano-serialization-lib/blob/master/rust/src/address.rs

MNEMONIC_12 = "test walk nut penalty hip pave soap entry language right filter choice"
MNEMONIC_15 = "art forum devote street sure rather head chuckle guard poverty release quote oak craft enemy"
Copy link
Collaborator

@cffls cffls Sep 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this support 24 words mnemonic?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep it supports 24 words too and I tested it. I'll add in the test case.

@cffls
Copy link
Collaborator

cffls commented Sep 21, 2022

One thing I forgot to mention, sorry.. since HDWallet was initially proposed in bip32, it may be a good idea to move this into the bip32 module here.

@henryyuanheng-wang
Copy link
Contributor Author

The following changes were made:

  • modified from_seed, from_mnemonic and from_entropy to class method
  • return child hdwallet instance during derivation instead of overwriting the original hdwallet instance
  • added a function to Key so that ExtendedSigningKey can be created from an HDWallet instance. I added function as part of ExtendedSigningKey class instead of a HDWallet class since it resides in bip32 crypto base file. So users should be able to initiate a signing key if they have a valid hdwallet instance. Let me know if this implementation makes sense or if there is a better place to integrate the function with existing code base. Thanks!

Copy link
Collaborator

@cffls cffls left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you Henry for the amazing work!

@cffls cffls merged commit c426f5f into Python-Cardano:main Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants