diff --git a/README.rst b/README.rst index c184576..1b00068 100644 --- a/README.rst +++ b/README.rst @@ -5,19 +5,11 @@ Cryptnox Pro .. image:: https://img.shields.io/pypi/v/cryptnoxpro :target: https://pypi.org/project/cryptnoxpro - -**Warning: This is a beta release of the software. -It is released for development purposes. -Use at your own risk.** - A command line user interface to manage and use of `Cryptnox Smart cards `_. This provides basic wallets for `Bitcoin `_ and `Ethereum `_. -It is able to execute `cleos `_ commands and use -the keys on the card for signing. - To buy NFC enabled cards that are supported by this application go to: `https://www.cryptnox.com/ `_ diff --git a/cryptnoxpro/command/helper/ui.py b/cryptnoxpro/command/helper/ui.py index 7812363..5467c72 100644 --- a/cryptnoxpro/command/helper/ui.py +++ b/cryptnoxpro/command/helper/ui.py @@ -14,6 +14,7 @@ from tabulate import tabulate from . import security +from cryptnoxpro.config import MAX_PASSPHRASE_LENGTH InitData = namedtuple("InitData", ["name", "email", "pin", "puk"]) @@ -201,3 +202,61 @@ def _verify_input(card: cryptnoxpy.Card, method, text, verify_text, print(error) return value + + +def get_bip39_passphrase(confirm_required: bool = True) -> str: + print() + print_warning("BIP39 PASSPHRASE FEATURE") + print("A BIP39 passphrase is an optional extra password that provides additional security.") + print("Different passphrases create completely different wallets from the same mnemonic.") + print() + print("IMPORTANT WARNINGS:") + print(" • If you forget your passphrase, your funds are PERMANENTLY LOST") + print(" • Passphrases are case-sensitive and spaces matter") + print(" • There is NO way to recover funds without the exact passphrase") + print(" • Press ENTER to skip passphrase (standard BIP39 with empty passphrase)") + print() + + use_passphrase = confirm("Do you want to use a BIP39 passphrase?") + + if not use_passphrase: + return "" + + print() + print("Enter your BIP39 passphrase:") + print("(Any UTF-8 characters are valid, but avoid unusual characters you might forget)") + + if confirm_required: + passphrase = _verify_passphrase_input() + else: + passphrase = getpass("Passphrase: ") + + if len(passphrase) > MAX_PASSPHRASE_LENGTH: + print("ERROR: Passphrase must be at most 100 characters. Please try again.") + raise ExitException("Passphrase exceeds 100 characters") + + print() + print("Please write down your passphrase and store it securely.") + print("Without this exact passphrase, you CANNOT access your wallet.") + print() + + if not confirm("Have you securely stored your passphrase?"): + raise ExitException("User needs to store passphrase securely") + + return passphrase + + +def _verify_passphrase_input() -> str: + while True: + passphrase = getpass("Passphrase: ") + if len(passphrase) > MAX_PASSPHRASE_LENGTH: + print("ERROR: Passphrase must be at most 100 characters. Please try again.") + print() + continue + verify_passphrase = getpass("Confirm passphrase: ") + + if passphrase == verify_passphrase: + return passphrase + + print("ERROR: Passphrases do not match. Please try again.") + print() diff --git a/cryptnoxpro/command/seed.py b/cryptnoxpro/command/seed.py index ce5640e..975046c 100644 --- a/cryptnoxpro/command/seed.py +++ b/cryptnoxpro/command/seed.py @@ -66,7 +66,21 @@ def _execute(self, card) -> int: return result @staticmethod - def _backup(card: cryptnoxpy.Card, pin_code: str = None, seed: bytes = None) -> int: + def _backup(card: cryptnoxpy.Card, pin_code: str = None, seed: bytes = None, + passphrase: str = '') -> int: + """ + Backup seed to AWS KMS and load onto card with optional BIP39 passphrase. + + Note: The backup service stores only the raw seed entropy, not the passphrase. + The passphrase is used only when loading the mnemonic onto the card. + Users must remember their passphrase separately. + + :param card: The Cryptnox card + :param pin_code: The card PIN code + :param seed: Optional pre-generated seed bytes + :param passphrase: Optional BIP39 passphrase + :return: 0 on success, -1 on error + """ pin_code = pin_code or Seed._get_pin_code(card) credentials_file = Path(get_download_folder()).joinpath('rootkey.csv') @@ -121,7 +135,7 @@ def _backup(card: cryptnoxpy.Card, pin_code: str = None, seed: bytes = None) -> print("Seed successfully saved. Writing card.") mnemonic = cryptos.entropy_to_words(seed) - Seed._load_mnemonic(card, mnemonic, pin_code) + Seed._load_mnemonic(card, mnemonic, pin_code, passphrase=passphrase) data = list(service.region.items()) data.append(("name", name)) @@ -131,6 +145,13 @@ def _backup(card: cryptnoxpy.Card, pin_code: str = None, seed: bytes = None) -> backup_file.write_text(tabulate(data)) print(f"\nBackup data also saved to: {backup_file}") + if passphrase: + print() + ui.print_warning("IMPORTANT: BIP39 PASSPHRASE IN USE") + print("The backup service stores only the seed entropy, NOT your passphrase.") + print("You must remember and store your BIP39 passphrase separately!") + print("To restore this wallet, you will need BOTH the backup AND your passphrase.") + Seed._remove_credentials(credentials_file, service) return 0 @@ -162,8 +183,23 @@ def _backup_service(access_key_id: str = '', secret_access_key: str = '') -> Uni @staticmethod def _chip(card: cryptnoxpy.Card) -> int: + """ + Generate seed directly in the card's secure chip. + + Note: This method generates the seed entirely on the card's hardware and does not + use BIP39 mnemonics. Therefore, BIP39 passphrases do not apply to this seed + generation method. The seed cannot be exported or backed up as a mnemonic phrase. + + :param card: The Cryptnox card + :return: 0 on success + """ pin_code = Seed._get_pin_code(card) + print("Generating seed directly in card's secure chip...") + print("Note: This seed is generated on-chip and does not use BIP39 mnemonics.") + print("BIP39 passphrases do not apply to this generation method.") + print() + card.generate_seed(pin_code) print("New key generated in card.") @@ -191,6 +227,17 @@ def _credentials(credential_file: Path = None) -> Tuple[str, str]: return access_key_id, secret_access_key def _dual_seed(self, card: cryptnoxpy.Card) -> int: + """ + Generate the same seed on two cards using secure dual-card generation. + + Note: This method generates seeds using a secure two-card protocol and does not + use BIP39 mnemonics. Therefore, BIP39 passphrases do not apply to this seed + generation method. The seed is generated securely on both cards and never leaves + the hardware. + + :param card: The first Cryptnox card + :return: 0 on success, -1 or -2 on error + """ try: card.dual_seed_public_key() except NotImplementedError as error: @@ -199,6 +246,11 @@ def _dual_seed(self, card: cryptnoxpy.Card) -> int: except cryptnoxpy.exceptions.DataValidationException: pass + print("Dual seed generation process starting...") + print("Note: This method uses secure on-chip generation and does not use BIP39 mnemonics.") + print("BIP39 passphrases do not apply to this generation method.") + print() + pin_code = Seed._get_pin_code(card) serial_number = card.serial_number @@ -287,20 +339,42 @@ def _get_second_card(self, index: int, first_card_serial_number: int) -> cryptno return card @staticmethod - def _load_mnemonic(card: cryptnoxpy.Card, mnemonic: str, pin_code: str) -> None: + def _load_mnemonic(card: cryptnoxpy.Card, mnemonic: str, pin_code: str, + passphrase: str = '') -> None: + """ + Load mnemonic onto card with optional BIP39 passphrase. + + :param card: The Cryptnox card + :param mnemonic: The BIP39 mnemonic phrase (12 or 24 words) + :param pin_code: The card PIN code + :param passphrase: Optional BIP39 passphrase (13th/25th word) + """ if len(mnemonic.split(' ')) not in (12, 24): raise ValueError('Only mnemonic passphrases of length 12 and 24 are supported') - seed = cryptos.bip39_mnemonic_to_seed(mnemonic) + seed = cryptos.bip39_mnemonic_to_seed(mnemonic, passphrase=passphrase) card.load_seed(seed, pin_code) @staticmethod def _recover(card: cryptnoxpy.Card) -> int: + """ + Recover wallet from BIP39 mnemonic phrase with optional passphrase. + + :param card: The Cryptnox card + :return: 0 on success, -1 on error + """ pin_code = Seed._get_pin_code(card) print("\nEnter the mnemonic root to recover (12 or 24 words):") mnemonic = ui.input_with_exit("> ") + try: - seed = cryptos.bip39_mnemonic_to_seed(mnemonic) + passphrase = ui.get_bip39_passphrase(confirm_required=True) + except ui.ExitException as error: + print(error) + return -1 + + try: + seed = cryptos.bip39_mnemonic_to_seed(mnemonic, passphrase=passphrase) except Exception as error: print(error) return -1 @@ -308,14 +382,16 @@ def _recover(card: cryptnoxpy.Card) -> int: do_backup = ui.confirm('Do you wish to backup your seed to AWS KMS?') try: if do_backup: - Seed._backup(card, pin_code, seed) + Seed._backup(card, pin_code, seed, passphrase=passphrase) else: - Seed._load_mnemonic(card, mnemonic, pin_code) + Seed._load_mnemonic(card, mnemonic, pin_code, passphrase=passphrase) except Exception as error: print(error) return -1 print("Mnemonic loaded, please keep it safe for backup.") + if passphrase: + print("You MUST use the same passphrase when restoring this wallet.") return 0 @@ -331,6 +407,15 @@ def _remove_credentials(credentials_file: Path, service: backup.AWS) -> None: @staticmethod def _restore(card: cryptnoxpy.Card) -> int: + """ + Restore seed from AWS KMS backup with optional BIP39 passphrase. + + Note: The backup service stores only the seed entropy. If a BIP39 passphrase + was used when creating the wallet, it must be provided again during restore. + + :param card: The Cryptnox card + :return: 0 on success, -1 on error + """ pin_code = Seed._get_pin_code(card) credentials_file = Path(get_download_folder()).joinpath('rootkey.csv') access_key_id, secret_access_key = Seed._credentials(credentials_file) @@ -357,8 +442,19 @@ def _restore(card: cryptnoxpy.Card) -> int: print("There was an issue with the retrieved backup in converting it to a mnemonic.") return -1 - print("Seed successfully retrieved. Writing card.") - Seed._load_mnemonic(card, mnemonic, pin_code) + print("Seed successfully retrieved.") + print() + print("If you used a BIP39 passphrase when creating this wallet,") + print("you must provide the same passphrase now.") + + try: + passphrase = ui.get_bip39_passphrase(confirm_required=False) + except ui.ExitException as error: + print(error) + return -1 + + print("Writing card.") + Seed._load_mnemonic(card, mnemonic, pin_code, passphrase=passphrase) print("\nMnemonic loaded from backup service.") Seed._remove_credentials(credentials_file, service) @@ -367,16 +463,29 @@ def _restore(card: cryptnoxpy.Card) -> int: @staticmethod def _upload(card: cryptnoxpy.Card) -> int: + """ + Generate new seed, optionally with BIP39 passphrase, and upload to card. + + :param card: The Cryptnox card + :return: 0 on success, -1 on error + """ pin_code = Seed._get_pin_code(card) seed = card.generate_random_number(32) mnemonic = cryptos.entropy_to_words(seed) + + try: + passphrase = ui.get_bip39_passphrase(confirm_required=True) + except ui.ExitException as error: + print(error) + return -1 + do_backup = ui.confirm('Do you wish to backup your seed to AWS KMS?') try: if do_backup: - Seed._backup(card, pin_code, seed) + Seed._backup(card, pin_code, seed, passphrase=passphrase) else: - Seed._load_mnemonic(card, mnemonic, pin_code) + Seed._load_mnemonic(card, mnemonic, pin_code, passphrase=passphrase) except Exception as error: print(error) return -1 @@ -386,4 +495,15 @@ def _upload(card: cryptnoxpy.Card) -> int: print("\nMnemonic loaded, please save this root mnemonic for backup.") + if passphrase: + print() + ui.print_warning("IMPORTANT: BIP39 PASSPHRASE IN USE") + print("You are using a BIP39 passphrase with this wallet.") + print("To restore this wallet, you will need BOTH:") + print(" 1. The mnemonic phrase shown above") + print(" 2. Your BIP39 passphrase") + print() + print("Store your passphrase separately and securely!") + print("Without the exact passphrase, you CANNOT access your funds.") + return 0 diff --git a/cryptnoxpro/config.py b/cryptnoxpro/config.py index 63323ac..b1eb555 100644 --- a/cryptnoxpro/config.py +++ b/cryptnoxpro/config.py @@ -18,6 +18,7 @@ _CONFIGURATION = {} REMOTE_CONNECTIONS = [] +MAX_PASSPHRASE_LENGTH = 100 def get_default_configuration() -> Dict: diff --git a/docs/cli.rst b/docs/cli.rst new file mode 100644 index 0000000..2029365 --- /dev/null +++ b/docs/cli.rst @@ -0,0 +1,677 @@ +Command Line Interface +====================== + +The ``cryptnox`` command provides a comprehensive CLI for managing Cryptnox cards and performing cryptocurrency operations. + +Installation +------------ + +After installing the cryptnoxpro package, the ``cryptnox`` command becomes available in your system: + +.. code-block:: bash + + pip install cryptnoxpro + +Basic Usage +----------- + +.. code-block:: bash + + cryptnox [OPTIONS] COMMAND [ARGS]... + +Global Options +-------------- + +.. option:: -v, --version + + Show the version and exit. + +.. option:: --verbose + + Turn on logging for detailed output. + +.. option:: -s, --serial SERIAL + + Serial number of the card to be used for the command. + +.. option:: --port PORT + + Define port to enable remote feature. + +Commands Overview +----------------- + +Card Management Commands +~~~~~~~~~~~~~~~~~~~~~~~~ + +list +^^^^ + +List all connected Cryptnox cards. + +.. code-block:: bash + + cryptnox list + +init +^^^^ + +Initialize a Cryptnox card with owner information and PIN/PUK codes. + +.. code-block:: bash + + cryptnox init [OPTIONS] + +Options: + - ``-e, --easy_mode``: Initialize card in easy mode (sets PIN and PUK to all zeros) + +reset +^^^^^ + +Reset the card to factory defaults. + +.. code-block:: bash + + cryptnox reset + +**Warning:** This will erase all data on the card. + +info +^^^^ + +Display default accounts information for the card. + +.. code-block:: bash + + cryptnox info + +Shows: + - Card serial number and type + - Ethereum and Bitcoin addresses + - Public keys + - Derivation information + +Seed Management Commands +~~~~~~~~~~~~~~~~~~~~~~~~ + +seed backup +^^^^^^^^^^^ + +Generate seed in host, backup to AWS KMS, and upload to card. + +.. code-block:: bash + + cryptnox seed backup + +**Features:** + - Generates new 32-byte random seed + - Stores encrypted backup in AWS KMS (Hardware Security Module) + - Supports BIP39 passphrase (13th/25th word) + - Loads seed onto card + +seed chip +^^^^^^^^^ + +Generate new root key directly in the card's secure chip. + +.. code-block:: bash + + cryptnox seed chip + +**Note:** The seed never leaves the card and cannot be backed up. + +seed dual +^^^^^^^^^ + +Generate the same seed on two cards for redundancy. + +.. code-block:: bash + + cryptnox seed dual + +**Requirements:** Two initialized Cryptnox cards + +**Process:** + 1. Generate seed on first card + 2. Swap cards + 3. Load same seed on second card + 4. Results in two cards with identical keys + +seed recover +^^^^^^^^^^^^ + +Recover a wallet from an existing BIP39 mnemonic phrase (12 or 24 words). + +.. code-block:: bash + + cryptnox seed recover + +**Input Required:** + - Existing BIP39 mnemonic (12 or 24 words) + - Optional: BIP39 passphrase (13th/25th word) + +**Options:** + - Backup to AWS KMS + - Load directly to card + +**Use Cases:** + - Restoring existing wallet + - Migrating wallet from another device + - Recovering from backup mnemonic + +**Important:** If the original wallet used a BIP39 passphrase, you **must** provide the same passphrase during recovery. + +seed restore +^^^^^^^^^^^^ + +Restore seed from AWS KMS backup. + +.. code-block:: bash + + cryptnox seed restore + +**Requirements:** + - AWS access credentials + - Backup name/alias in KMS + +**Important:** If a BIP39 passphrase was used when creating the backup, you must provide the same passphrase during restore. + +seed upload +^^^^^^^^^^^ + +Generate new random seed, upload to card, and display BIP39 mnemonic for backup. + +.. code-block:: bash + + cryptnox seed upload + +**Features:** + - Generates new 32-byte random seed using card's hardware RNG + - Converts to BIP39 mnemonic (12 or 24 words) + - Optional: Add BIP39 passphrase (13th/25th word) for extra security + - Displays mnemonic for manual backup + - Optional: Backup to AWS KMS + +**Output:** The generated mnemonic phrase (save it securely!) + +**Important:** If you use a BIP39 passphrase, you **must** remember it. It cannot be recovered. + +Security Commands +~~~~~~~~~~~~~~~~~ + +change_pin +^^^^^^^^^^ + +Change the PIN code of the card. + +.. code-block:: bash + + cryptnox change_pin + +**Requirements:** Current PIN code + +change_puk +^^^^^^^^^^ + +Change the PUK (PIN Unblocking Key) code of the card. + +.. code-block:: bash + + cryptnox change_puk + +**Requirements:** Current PUK code + +unlock_pin +^^^^^^^^^^ + +Unlock a card with blocked PIN using the PUK code and set a new PIN. + +.. code-block:: bash + + cryptnox unlock_pin + +**Requirements:** PUK code + +**Note:** PIN becomes blocked after multiple failed attempts. + +Card Configuration +~~~~~~~~~~~~~~~~~~ + +card_conf +^^^^^^^^^ + +Show or modify card configuration settings. + +.. code-block:: bash + + cryptnox card_conf [KEY] [VALUE] + +**Available Settings:** + +- ``pinless``: Enable/disable PIN-less path +- ``pin``: Enable/disable PIN authentication + +**Values:** ``yes`` or ``no`` + +**Examples:** + +.. code-block:: bash + + # Show current configuration + cryptnox card_conf + + # Enable PIN-less path + cryptnox card_conf pinless yes + + # Disable PIN-less path + cryptnox card_conf pinless no + +Bitcoin Commands +~~~~~~~~~~~~~~~~ + +btc send +^^^^^^^^ + +Send Bitcoin to an address. + +.. code-block:: bash + + cryptnox btc send ADDRESS AMOUNT [OPTIONS] + +**Arguments:** + - ``ADDRESS``: Bitcoin address (P2PKH, P2SH, or Bech32) + - ``AMOUNT``: Amount in BTC + +**Options:** + - ``-n, --network {mainnet,testnet}``: Network to use + - ``-f, --fees SATOSHIS``: Transaction fees in satoshis per byte + +**Example:** + +.. code-block:: bash + + cryptnox btc send 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa 0.001 -n mainnet -f 10 + +btc config +^^^^^^^^^^ + +View or modify Bitcoin configuration. + +.. code-block:: bash + + cryptnox btc config [KEY] [VALUE] + +**Settings:** + - ``network``: mainnet or testnet + - ``derivation``: Key derivation method + +Ethereum Commands +~~~~~~~~~~~~~~~~~ + +eth send +^^^^^^^^ + +Send Ether (ETH) to an address. + +.. code-block:: bash + + cryptnox eth send ADDRESS AMOUNT [OPTIONS] + +**Arguments:** + - ``ADDRESS``: Ethereum address (0x...) + - ``AMOUNT``: Amount in ETH + +**Options:** + - ``-n, --network {mainnet,sepolia,goerli}``: Network to use + - ``--price GWEI``: Gas price in Gwei + - ``--limit GAS``: Gas limit + +**Example:** + +.. code-block:: bash + + cryptnox eth send 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb 0.1 -n mainnet --price 20 + +eth config +^^^^^^^^^^ + +View or modify Ethereum configuration. + +.. code-block:: bash + + cryptnox eth config [KEY] [VALUE] + +**Settings:** + - ``network``: mainnet, sepolia, or other networks + - ``derivation``: Key derivation method + - ``api_key``: Etherscan/Infura API key + - ``endpoint``: RPC endpoint + +ERC Token Commands +~~~~~~~~~~~~~~~~~~ + +eth erc20 init +^^^^^^^^^^^^^^ + +Initialize ERC-20 token contract for transactions. + +.. code-block:: bash + + cryptnox eth erc20 init CONTRACT_ADDRESS [OPTIONS] + +eth erc20 info +^^^^^^^^^^^^^^ + +Display information about configured ERC-20 tokens. + +.. code-block:: bash + + cryptnox eth erc20 info + +eth erc20 send +^^^^^^^^^^^^^^ + +Send ERC-20 tokens. + +.. code-block:: bash + + cryptnox eth erc20 send TOKEN_ADDRESS RECIPIENT_ADDRESS AMOUNT [OPTIONS] + +transfer +^^^^^^^^ + +Transfer ERC-20 or ERC-721 tokens. + +.. code-block:: bash + + cryptnox transfer ADDRESS AMOUNT [OPTIONS] + +**Options:** + - ``--price GWEI``: Gas price + - ``--limit GAS``: Gas limit + +Configuration Commands +~~~~~~~~~~~~~~~~~~~~~~ + +config +^^^^^^ + +List or modify blockchain configurations. + +.. code-block:: bash + + cryptnox config [SECTION] [KEY] [VALUE] + +**Examples:** + +.. code-block:: bash + + # Show all configuration + cryptnox config + + # Show Ethereum configuration + cryptnox config eth + + # Set Ethereum network + cryptnox config eth network mainnet + + # Set Bitcoin derivation + cryptnox config btc derivation DERIVE + +History and Information +~~~~~~~~~~~~~~~~~~~~~~~ + +history +^^^^^^^ + +List performed signatures and transactions. + +.. code-block:: bash + + cryptnox history [PAGE] + +**Arguments:** + - ``PAGE``: Page number to display (default: 1) + +**Note:** Shows up to 148 entries, 25 per page. + +Advanced Commands +~~~~~~~~~~~~~~~~~ + +get_xpub +^^^^^^^^ + +Get extended public key (xpub) for hierarchical deterministic wallets. + +.. code-block:: bash + + cryptnox get_xpub [OPTIONS] + +**Options:** + - Derivation path + - Key type + +get_clearpubkey +^^^^^^^^^^^^^^^ + +Get clear (uncompressed) public key from the card. + +.. code-block:: bash + + cryptnox get_clearpubkey [OPTIONS] + +decrypt +^^^^^^^ + +Decrypt data using the card's private key. + +.. code-block:: bash + + cryptnox decrypt [OPTIONS] + +User Key Management +~~~~~~~~~~~~~~~~~~~ + +user_key list +^^^^^^^^^^^^^ + +List all configured user keys for authentication. + +.. code-block:: bash + + cryptnox user_key list + +user_key add +^^^^^^^^^^^^ + +Add a new user key for authentication (AWS KMS, PIV card, Windows Hello). + +.. code-block:: bash + + cryptnox user_key add TYPE [DESCRIPTION] + +**Available Types:** + - ``aws_kms``: AWS Key Management Service + - ``piv``: PIV-compatible smart card + - ``hello``: Windows Hello (biometric) + +**Example:** + +.. code-block:: bash + + cryptnox user_key add aws_kms "My AWS Key" + +user_key delete +^^^^^^^^^^^^^^^ + +Delete a user key. + +.. code-block:: bash + + cryptnox user_key delete TYPE + +Server Mode +~~~~~~~~~~~ + +server +^^^^^^ + +Start a server or establish connection to a remote server. + +.. code-block:: bash + + cryptnox server [OPTIONS] + +**Options:** + - ``--port PORT``: Server port (default: 5050) + - ``--host HOST``: Server host (default: 0.0.0.0) + +**Use Case:** Remote card access over network + +Interactive Mode +---------------- + +Launch interactive CLI mode: + +.. code-block:: bash + + cryptnox + +In interactive mode, you can: + - Execute commands without repeating ``cryptnox`` + - Use ``use`` command to switch between multiple cards + - Use ``exit`` to quit + +**Example Session:** + +.. code-block:: text + + $ cryptnox + Cryptnox Pro 2.9.1 + + > list + [Shows available cards] + + > info + [Shows card information] + + > exit + +BIP39 Passphrase Support +------------------------- + +The ``seed recover`` and ``seed upload`` commands support BIP39 passphrases (also known as the 13th/25th word). + +What is a BIP39 Passphrase? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A BIP39 passphrase is an optional additional word that enhances security: + - Acts as a "second factor" for your seed + - Creates a completely different wallet from the same mnemonic + - Must be remembered separately (not stored with the mnemonic) + - Cannot be recovered if forgotten + +Using BIP39 Passphrase +~~~~~~~~~~~~~~~~~~~~~~~ + +**During seed upload (new wallet):** + +.. code-block:: bash + + cryptnox seed upload + +The command will prompt: + +.. code-block:: text + + Do you want to use a BIP39 passphrase? [y/N] + +If you choose ``yes``: + - Enter your desired passphrase + - Confirm the passphrase + - **Remember it!** You'll need it for recovery + +**During seed recover (existing wallet):** + +.. code-block:: bash + + cryptnox seed recover + +If your wallet was created with a passphrase, you **must** provide the same passphrase when recovering. + +**Important Notes:** + - ⚠️ The passphrase is **NOT** backed up by AWS KMS + - ⚠️ If you forget your passphrase, your funds are **permanently lost** + - ✅ Same mnemonic + different passphrase = completely different wallet + - ✅ Passphrase can be any UTF-8 string (including spaces and special characters) + +Exit Codes +---------- + +The CLI returns the following exit codes: + +- ``0``: Success +- ``-1``: Error occurred +- ``-2``: Card error or card not found + +Error Handling +-------------- + +When errors occur: + - Detailed error messages are displayed + - Errors are logged to: ``~/.local/share/cryptnoxpro/error.log`` (Linux/macOS) or ``%LOCALAPPDATA%\\cryptnox\\cryptnoxpro\\error.log`` (Windows) + - You can report errors to help improve the application + +Examples +-------- + +**Initialize a new card:** + +.. code-block:: bash + + cryptnox init + +**Generate and backup a seed:** + +.. code-block:: bash + + cryptnox seed backup + +**Recover from existing mnemonic:** + +.. code-block:: bash + + cryptnox seed recover + +**Send Bitcoin:** + +.. code-block:: bash + + cryptnox btc send 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa 0.001 -n testnet + +**Send Ethereum:** + +.. code-block:: bash + + cryptnox eth send 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb 0.1 -n mainnet + +**View card info:** + +.. code-block:: bash + + cryptnox info + +**Change PIN:** + +.. code-block:: bash + + cryptnox change_pin + +See Also +-------- + +- :doc:`overview` - Overview of CryptnoxPro +- :mod:`cryptnoxpro.command.seed` - Seed command implementation details +- :doc:`cryptnoxpro.command` - All command implementations +- :doc:`modules` - Complete API Reference + diff --git a/docs/conf.py b/docs/conf.py index 950892a..0dfd197 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,6 +8,7 @@ import os import sys + sys.path.insert(0, os.path.abspath("..")) project = 'cryptnoxpro' @@ -25,33 +26,79 @@ "sphinx.ext.viewcode", ] +# Disable autosummary generation to prevent hangs +autosummary_generate = False + templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +# autodoc_mock_imports - Sphinx will create mock imports for these modules +# This is safer than manual sys.modules mocking and prevents hangs autodoc_mock_imports = [ - 'winsdk', + # Cryptnox 'cryptnoxpy', - 'boto3', - 'botocore', - 'cryptography', + # Input/Output 'stdiomask', 'tabulate', - 'requests', + # AWS + 'boto3', + 'botocore', + 'botocore.exceptions', + 'botocore.client', + 'botocore.config', + # Web3 and Ethereum 'web3', - 'eth_typing', + 'web3.eth', + 'web3.contract', + 'web3.middleware', 'eth_account', + 'eth_account._utils', + 'eth_account._utils.legacy_transactions', 'eth_account.transactions', 'eth_account.account', - 'eth_account._utils', 'eth_account.datastructures', - 'pydantic', - 'pydantic_core', 'eth_utils', + 'eth_utils.curried', + 'eth_typing', + 'eth_keys', + 'eth_rlp', + 'eth_abi', + 'eth_hash', 'hexbytes', - 'enums', - 'config' + 'ecdsa', + 'rlp', + # Validation + 'pydantic', + 'pydantic_core', + # Smart card + 'pyscard', + 'smartcard', + 'smartcard.CardConnection', + 'smartcard.System', + 'smartcard.Exceptions', + 'smartcard.CardType', + 'smartcard.CardRequest', + 'smartcard.util', + 'smartcard.scard', + # Utilities + 'cytoolz', + 'toolz', + 'winsdk', + 'base58', ] +# Autodoc configuration +autodoc_default_options = { + 'members': True, + 'member-order': 'bysource', + 'special-members': '__init__', + 'undoc-members': True, + 'exclude-members': '__weakref__' +} + +# Set autodoc to not fail on import errors +autoclass_content = 'both' + # Handle ambiguous cross-references nitpicky = False nitpick_ignore = [ diff --git a/docs/cryptnoxpro.command.card.rst b/docs/cryptnoxpro.command.card.rst index 678bdf6..2084c6d 100644 --- a/docs/cryptnoxpro.command.card.rst +++ b/docs/cryptnoxpro.command.card.rst @@ -28,3 +28,17 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command.card`` package provides card management functionality and exports: + +.. py:currentmodule:: cryptnoxpro.command.card + +.. py:class:: Info + :no-index: + + Command class for displaying card information. See :class:`cryptnoxpro.command.card.info.Info` for details. + +.. py:class:: Initialize + :no-index: + + Command class for initializing cards. See :class:`cryptnoxpro.command.card.initialize.Initialize` for details. + diff --git a/docs/cryptnoxpro.command.erc_token.rst b/docs/cryptnoxpro.command.erc_token.rst index b05d892..1717487 100644 --- a/docs/cryptnoxpro.command.erc_token.rst +++ b/docs/cryptnoxpro.command.erc_token.rst @@ -36,3 +36,17 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command.erc_token`` package provides ERC token management and exports: + +.. py:currentmodule:: cryptnoxpro.command.erc_token + +.. py:class:: Info + :no-index: + + Command class for displaying ERC token information. See :class:`cryptnoxpro.command.erc_token.info.Info` for details. + +.. py:class:: Initialize + :no-index: + + Command class for initializing ERC tokens. See :class:`cryptnoxpro.command.erc_token.initialize.Initialize` for details. + diff --git a/docs/cryptnoxpro.command.helper.rst b/docs/cryptnoxpro.command.helper.rst index c8949ba..f0434e5 100644 --- a/docs/cryptnoxpro.command.helper.rst +++ b/docs/cryptnoxpro.command.helper.rst @@ -84,3 +84,7 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command.helper`` package provides utility functions and helper modules for command implementations. +This package contains shared functionality used across multiple commands, including user interface components, +security helpers, configuration management, and backup utilities. + diff --git a/docs/cryptnoxpro.command.options.rst b/docs/cryptnoxpro.command.options.rst index af4453c..232bcfb 100644 --- a/docs/cryptnoxpro.command.options.rst +++ b/docs/cryptnoxpro.command.options.rst @@ -36,3 +36,12 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command.options`` package provides command-line argument parsing and exports: + +.. py:currentmodule:: cryptnoxpro.command.options + +.. py:function:: add(subparsers, command_class) + :no-index: + + Add command-line options for a command class. See :func:`cryptnoxpro.command.options.options.add` for details. + diff --git a/docs/cryptnoxpro.command.rst b/docs/cryptnoxpro.command.rst index 42008a3..f04e52f 100644 --- a/docs/cryptnoxpro.command.rst +++ b/docs/cryptnoxpro.command.rst @@ -200,3 +200,6 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command`` package provides command-line interface commands for interacting with Cryptnox cards. +This package contains all command implementations that can be executed from the CLI. + diff --git a/docs/cryptnoxpro.command.user_keys.rst b/docs/cryptnoxpro.command.user_keys.rst index cc089ce..94133ff 100644 --- a/docs/cryptnoxpro.command.user_keys.rst +++ b/docs/cryptnoxpro.command.user_keys.rst @@ -38,3 +38,27 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.command.user_keys`` package provides authentication functionality and exports: + +.. py:currentmodule:: cryptnoxpro.command.user_keys + +.. py:function:: add(data) + :no-index: + + Add a new authentication method. See :func:`cryptnoxpro.command.user_keys.authentication.add` for details. + +.. py:function:: authenticate(data) + :no-index: + + Authenticate using a configured method. See :func:`cryptnoxpro.command.user_keys.authentication.authenticate` for details. + +.. py:function:: delete(data) + :no-index: + + Delete an authentication method. See :func:`cryptnoxpro.command.user_keys.authentication.delete` for details. + +.. py:function:: get(data) + :no-index: + + Get information about authentication methods. See :func:`cryptnoxpro.command.user_keys.authentication.get` for details. + diff --git a/docs/cryptnoxpro.lib.cryptos.coins.rst b/docs/cryptnoxpro.lib.cryptos.coins.rst index 6699707..a19a6b9 100644 --- a/docs/cryptnoxpro.lib.cryptos.coins.rst +++ b/docs/cryptnoxpro.lib.cryptos.coins.rst @@ -28,3 +28,12 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.lib.cryptos.coins`` package provides cryptocurrency coin implementations and exports: + +.. py:currentmodule:: cryptnoxpro.lib.cryptos.coins + +.. py:class:: Bitcoin + :no-index: + + Bitcoin cryptocurrency implementation. See :class:`cryptnoxpro.lib.cryptos.coins.bitcoin.Bitcoin` for details. + diff --git a/docs/cryptnoxpro.lib.cryptos.rst b/docs/cryptnoxpro.lib.cryptos.rst index e042543..b7a8289 100644 --- a/docs/cryptnoxpro.lib.cryptos.rst +++ b/docs/cryptnoxpro.lib.cryptos.rst @@ -140,3 +140,19 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.lib.cryptos`` package provides cryptocurrency utilities and re-exports functionality from: + +* :mod:`cryptnoxpro.lib.cryptos.blocks` - Block-related utilities +* :mod:`cryptnoxpro.lib.cryptos.composite` - Composite key handling +* :mod:`cryptnoxpro.lib.cryptos.deterministic` - Deterministic wallet functions +* :mod:`cryptnoxpro.lib.cryptos.main` - Main crypto operations +* :mod:`cryptnoxpro.lib.cryptos.mnemonic` - Mnemonic phrase handling +* :mod:`cryptnoxpro.lib.cryptos.specials` - Special cryptocurrency operations +* :mod:`cryptnoxpro.lib.cryptos.stealth` - Stealth address support +* :mod:`cryptnoxpro.lib.cryptos.transaction` - Transaction handling +* :mod:`cryptnoxpro.lib.cryptos.coins` - Coin implementations +* :mod:`cryptnoxpro.lib.cryptos.keystore` - Key storage utilities +* :mod:`cryptnoxpro.lib.cryptos.wallet` - Wallet functionality + +All public members from these modules are available directly from ``cryptnoxpro.lib.cryptos``. + diff --git a/docs/cryptnoxpro.lib.rst b/docs/cryptnoxpro.lib.rst index ed15d2d..541ae76 100644 --- a/docs/cryptnoxpro.lib.rst +++ b/docs/cryptnoxpro.lib.rst @@ -17,3 +17,6 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.lib`` package provides library functionality for cryptocurrency operations. +The main subpackage is :mod:`cryptnoxpro.lib.cryptos` which contains comprehensive cryptocurrency utilities. + diff --git a/docs/cryptnoxpro.rst b/docs/cryptnoxpro.rst index 20f3b56..7407f2d 100644 --- a/docs/cryptnoxpro.rst +++ b/docs/cryptnoxpro.rst @@ -54,3 +54,11 @@ Module contents :undoc-members: :show-inheritance: +The main ``cryptnoxpro`` package exports: + +.. py:data:: __version__ + :type: str + :value: "2.9.1" + + Current version of the CryptnoxPro package. + diff --git a/docs/cryptnoxpro.wallet.eth.rst b/docs/cryptnoxpro.wallet.eth.rst index 51b3c9e..7537fed 100644 --- a/docs/cryptnoxpro.wallet.eth.rst +++ b/docs/cryptnoxpro.wallet.eth.rst @@ -28,3 +28,27 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.wallet.eth`` package provides Ethereum wallet utilities and exports: + +.. py:currentmodule:: cryptnoxpro.wallet.eth + +.. py:function:: address(public_key) + :no-index: + + Generate an Ethereum address from a public key. See :func:`cryptnoxpro.wallet.eth.api.address` for details. + +.. py:class:: Api + :no-index: + + Ethereum API interface. See :class:`cryptnoxpro.wallet.eth.api.Api` for details. + +.. py:function:: checksum_address(address_str) + :no-index: + + Convert an address to checksummed format. See :func:`cryptnoxpro.wallet.eth.api.checksum_address` for details. + +.. py:class:: EthValidator + :no-index: + + Ethereum address and transaction validator. See :class:`cryptnoxpro.wallet.eth.api.EthValidator` for details. + diff --git a/docs/cryptnoxpro.wallet.rst b/docs/cryptnoxpro.wallet.rst index f930f56..843535b 100644 --- a/docs/cryptnoxpro.wallet.rst +++ b/docs/cryptnoxpro.wallet.rst @@ -36,3 +36,6 @@ Module contents :undoc-members: :show-inheritance: +The ``cryptnoxpro.wallet`` package provides wallet functionality for various cryptocurrencies. +It includes Bitcoin wallet operations, Ethereum wallet utilities, and validation functions. + diff --git a/docs/index.rst b/docs/index.rst index 49fb59a..ea6d915 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,6 +8,7 @@ Welcome to the technical documentation of Cryptnoxpro. :caption: Contents: overview + cli modules license diff --git a/setup.cfg b/setup.cfg index 016cff5..5ff49fd 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,7 +8,6 @@ keywords = cryptography bitcoin ethereum - cleos cryptocurrency wallet license = GPLv3+