Example #1
0
    def test_wallet_is_wallet_file_valid(self, encrypt_wallet, wallet_factory,
                                         wallet_path):
        wallet = wallet_factory()
        wallet.change_passphrase(passphrase="password",
                                 encrypt_wallet=encrypt_wallet,
                                 encrypt_secrets=False)
        wallet.save(wallet_path)

        assert Wallet.is_wallet_file_valid(wallet_path)
Example #2
0
    def test_wallet_load_secrets(self):
        # Load wallet with only encrypted secrets
        # Passphrase not required
        wallet = Wallet.load(SECRETS_ENCRYPTED_WALLET_PATH)
        assert not wallet.wallet_key
        assert not wallet.secret_key

        assert isinstance(wallet.properties.seed, Secret)
        for account in wallet.accounts:
            assert isinstance(account.private_key, Secret)
Example #3
0
def wallet_from_str(s):
    """
    Convenience function to load a Wallet instance from a JSON-encoded string.
    This is more performant for transferring the wallet to the mocked
    HTTP server.
    """
    if s is None:
        return None

    return Wallet.from_dict(json.loads(s))
Example #4
0
    def test_wallet_is_wallet_file_encrypted(self, encrypt_wallet,
                                             encrypt_secrets, wallet_factory,
                                             wallet_path):
        wallet = wallet_factory(balance=1000, confirmed=True)
        wallet.change_passphrase(
            passphrase="password",
            encrypt_wallet=encrypt_wallet,
            encrypt_secrets=encrypt_secrets,
        )
        wallet.save(wallet_path)

        assert Wallet.is_wallet_file_encrypted(wallet_path) == encrypt_wallet
Example #5
0
def create_wallet(
        server,
        wallet_path: FilePathParam(exists=False),
        seed: SecureStrOption,
        encrypt_secrets: BoolOption,
        encrypt_wallet: BoolOption,
        passphrase: SecureStrOption,
        gap_limit: IntRangeOption(minimum=0, maximum=10000, default=20),
        key_iteration_count: IntRangeOption(
            default=get_default_key_iteration_count,
            minimum=1, maximum=2**32
        )):
    if os.path.exists(wallet_path):
        raise WalletExists

    if not seed:
        logger.info("Seed not provided, generating one automatically.")
        seed = generate_seed()

    validate_seed(seed)

    wallet = Wallet(
        properties=WalletProperties(
            seed_algorithm=WalletSeedAlgorithm.NANO,
            seed=seed,
            gap_limit=gap_limit
        )
    )
    wallet.refill_accounts()

    if encrypt_secrets or encrypt_wallet:
        if not passphrase:
            raise MissingPassphrase

        wallet.change_passphrase(
            passphrase=passphrase,
            encrypt_secrets=encrypt_secrets,
            encrypt_wallet=encrypt_wallet,
            key_iteration_count=key_iteration_count)

    wallet.save(wallet_path)

    return StdioResult(
        {
            "message": "Saved wallet to {}".format(wallet_path),
            "wallet_encrypted": wallet.encryption.wallet_encrypted,
            "secrets_encrypted": wallet.encryption.secrets_encrypted
        }
    )
Example #6
0
    def test_wallet_load_encrypted_wallet(self):
        # Load wallet which has been encrypted entirely
        # Passphrase required
        with pytest.raises(WalletLocked) as exc:
            Wallet.load(BOTH_ENCRYPTED_WALLET_PATH)

        assert "Wallet is encrypted but passphrase was not provided" in str(
            exc.value)

        # Wrong passphrase
        with pytest.raises(InvalidEncryptionKey) as exc:
            Wallet.load(BOTH_ENCRYPTED_WALLET_PATH, passphrase="wrong")

        assert "Incorrect passphrase" in str(exc.value)

        # Correct passphrase
        wallet = Wallet.load(BOTH_ENCRYPTED_WALLET_PATH, passphrase="password")
        assert wallet.wallet_key
        assert not wallet.secret_key

        assert isinstance(wallet.properties.seed, Secret)

        for account in wallet.accounts:
            assert isinstance(account.private_key, Secret)
Example #7
0
    def create_wallet(balance=0, seed=None, confirmed=False):
        if not seed:
            seed = generate_seed()

        wallet = Wallet(
            properties=WalletProperties(
                seed=seed,
                seed_algorithm=WalletSeedAlgorithm.NANO,
                gap_limit=20
            )
        )
        wallet.refill_accounts()

        if balance > 0:
            account = wallet.accounts[0]
            block = account.receive_block(
                pocketable_block_factory(
                    account_id=account.account_id,
                    amount=balance
                )
            )

            if confirmed:
                block.sign(account.get_secret("private_key"))
                block.solve_work(difficulty=TEST_DIFFICULTY)
                block.confirmed = True
                account.update_confirmed_head()

        if is_encrypted_test:
            key_iteration_count = 200

            wallet.change_passphrase(
                passphrase="password", encrypt_wallet=True,
                encrypt_secrets=True, key_iteration_count=key_iteration_count
            )

            wallet.lock()

            assert not wallet.secrets_unlocked
            assert not wallet.secret_key
            assert wallet.encryption.secrets_encrypted

        return wallet
Example #8
0
    def load_wallet(self, path, passphrase=None):
        """
        Load a wallet from the given path

        :raises WalletFileLocked: If the wallet file is already in use by
                                  another app instance

        """
        if self.wallet_lock:
            self.wallet_lock.release()

        self.wallet_lock = filelock.FileLock("{}.lock".format(path), timeout=0)

        try:
            self.wallet_lock.acquire()
        except filelock.Timeout:
            raise WalletFileLocked(
                "The wallet file is in use by another Siliqua instance"
            )

        wallet = Wallet.load(path, passphrase=passphrase)

        self.wallet = wallet
        self.wallet_path = path
Example #9
0
    def load_wallet(path, passphrase=None):
        if is_encrypted_test:
            passphrase = "password"

        return Wallet.load(path, passphrase=passphrase)
Example #10
0
    def test_wallet_is_wallet_file_valid_invalid_content(
            self, wallet_path, content):
        with open(wallet_path, "w+") as f:
            f.write(content)

        assert not Wallet.is_wallet_file_valid(wallet_path)
Example #11
0
        def wrapper(*args, **kwargs):
            server = kwargs.get("server", None)
            passphrase = kwargs.get("passphrase", None)

            # Convert empty string parameters to None
            kwargs = {
                k: None if v == "" else v for k, v in kwargs.items()
            }

            try:
                server.work.validate_config()
            except ConfigurationError as exc:
                raise StdioError(
                    "work_configuration_error",
                    "Work plugin has incomplete configuration: {}".format(
                        str(exc)
                    )
                )

            try:
                server.network.validate_config()
            except ConfigurationError as exc:
                raise StdioError(
                    "network_configuration_error",
                    "Network plugin has incomplete configuration: {}".format(
                        str(exc)
                    )
                )

            if wallet_required:
                if not kwargs["wallet_path"]:
                    raise StdioError(
                        "wallet_required",
                        "--wallet is required"
                    )

                try:
                    wallet_encrypted = Wallet.is_wallet_file_encrypted(
                        kwargs["wallet_path"]
                    )

                    if wallet_encrypted and sys.stdout.isatty():
                        print("Passphrase required to open encrypted wallet.")
                        passphrase = getpass("Passphrase: ")

                    server.load_wallet(
                        path=kwargs["wallet_path"],
                        passphrase=passphrase
                    )
                except InvalidEncryptionKey:
                    raise StdioError(
                        "incorrect_passphrase",
                        "Incorrect passphrase"
                    )
                except WalletLocked:
                    raise StdioError(
                        "wallet_encrypted",
                        "Wallet is encrypted but no passphrase was provided"
                    )
                except WalletFileLocked:
                    raise StdioError(
                        "wallet_locked",
                        "Wallet is locked and in use by another process"
                    )
                except WalletFileInvalid:
                    raise StdioError(
                        "wallet_invalid",
                        "Wallet file is invalid. It may be corrupted."
                    )
                except WalletMigrationRequired as exc:
                    raise StdioError(
                        "wallet_migration_required",
                        "Wallet file needs to be migrated before it can be "
                        "used. Current version: {}, "
                        "required version: {}".format(
                            exc.wallet_version, exc.required_version
                        )
                    )
                except UnsupportedWalletVersion as exc:
                    raise StdioError(
                        "unsupported_wallet_version",
                        "Wallet file with newer version {} was loaded but "
                        "only {} is supported. The wallet might have been "
                        "created with a newer version of this "
                        "application.".format(
                            exc.wallet_version, exc.required_version
                        )
                    )

                kwargs["server"] = server

                if start_work:
                    server.start_work()
                if start_network:
                    server.start_network()
                    try:
                        server.network.wait_for_connection(timeout=5)
                    except TimeoutError:
                        raise StdioError(
                            "network_connection_failure",
                            "Network plugin couldn't establish a connection."
                        )
                    except UnsupportedProtocolVersion as exc:
                        raise StdioError(
                            "unsupported_protocol_version",
                            "NANO node only supports protocol version "
                            f"{exc.current_version} while "
                            f"protocol version {exc.required_version} is "
                            "required"
                        )

                del kwargs["wallet_path"]

            try:
                return func(*args, **kwargs)
            except Exception as exc:
                # Raise a corresponding StdioError for a common error
                # if possible
                raise_common_error(exc)