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)
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)
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))
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
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 } )
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)
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
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
def load_wallet(path, passphrase=None): if is_encrypted_test: passphrase = "password" return Wallet.load(path, passphrase=passphrase)
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)
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)