Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies = [
"pycryptodome>=3.18.0,<4",
"eth-abi>=5.1.0,<6",
"python-dotenv>=1.2.1,<3",
"mnemonic>=0.21,<1",
]
classifiers = [
"Development Status :: 2 - Pre-Alpha",
Expand Down
21 changes: 21 additions & 0 deletions src/hiero_sdk_python/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

# Crypto
from .crypto.evm_address import EvmAddress
from .crypto.mnemonic import MnemonicPhrase
from .crypto.private_key import PrivateKey
from .crypto.public_key import PublicKey

Expand Down Expand Up @@ -66,6 +67,17 @@
from .logger.log_level import LogLevel
from .logger.logger import Logger

#Mirror Node
from .mirror_node.mirror_node_client import (
MirrorNodeAccount,
MirrorNodeBalance,
MirrorNodeClient,
MirrorNodeError,
MirrorNodePage,
MirrorNodeToken,
MirrorNodeTransaction,
)

# Nodes
from .nodes.node_create_transaction import NodeCreateTransaction
from .nodes.node_delete_transaction import NodeDeleteTransaction
Expand Down Expand Up @@ -172,6 +184,7 @@
"AccountRecordsQuery",
# Crypto
"PrivateKey",
"MnemonicPhrase",
"PublicKey",
"EvmAddress",
# Tokens
Expand Down Expand Up @@ -277,6 +290,14 @@
"ScheduleInfo",
"ScheduleSignTransaction",
"ScheduleDeleteTransaction",
# Mirror node
"MirrorNodeAccount",
"MirrorNodeBalance",
"MirrorNodeClient",
"MirrorNodeError",
"MirrorNodePage",
"MirrorNodeToken",
"MirrorNodeTransaction",
# Nodes
"NodeCreateTransaction",
"NodeUpdateTransaction",
Expand Down
8 changes: 8 additions & 0 deletions src/hiero_sdk_python/crypto/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from hiero_sdk_python.crypto.key import Key
from hiero_sdk_python.crypto.key_list import KeyList
from hiero_sdk_python.crypto.mnemonic import MnemonicPhrase
from hiero_sdk_python.crypto.private_key import PrivateKey
from hiero_sdk_python.crypto.public_key import PublicKey


__all__ = ["Key", "KeyList", "MnemonicPhrase", "PrivateKey", "PublicKey"]
45 changes: 45 additions & 0 deletions src/hiero_sdk_python/crypto/mnemonic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from __future__ import annotations

from dataclasses import dataclass

from mnemonic import Mnemonic

from hiero_sdk_python.crypto.private_key import PrivateKey


@dataclass(frozen=True)
class MnemonicPhrase:
"""BIP-39 mnemonic utilities for deterministic wallet workflows."""

phrase: str

@classmethod
def generate(cls, strength: int = 256) -> MnemonicPhrase:
"""Generate a valid English BIP-39 mnemonic phrase."""
return cls(Mnemonic("english").generate(strength=strength))

@classmethod
def from_phrase(cls, phrase: str) -> MnemonicPhrase:
"""Construct and validate a BIP-39 mnemonic phrase."""
mnemonic = Mnemonic("english")
normalized = " ".join(phrase.strip().split())
if not mnemonic.check(normalized):
raise ValueError("Invalid BIP-39 mnemonic phrase.")
return cls(normalized)

def is_valid(self) -> bool:
"""Check whether the phrase has valid BIP-39 checksum and words."""
return Mnemonic("english").check(self.phrase)

def to_seed(self, passphrase: str = "") -> bytes:
"""Convert mnemonic phrase to BIP-39 seed bytes."""
return Mnemonic.to_seed(self.phrase, passphrase=passphrase)

def to_private_key_ed25519(self, passphrase: str = "") -> PrivateKey:
"""Derive an Ed25519 private key from the first 32 bytes of BIP-39 seed.

This provides deterministic key material suitable for local development
and reproducible testing workflows.
"""
seed = self.to_seed(passphrase=passphrase)
return PrivateKey.from_bytes_ed25519(seed[:32])
Loading
Loading