def test_wallet_storage_new() -> None: base_storage_path = tempfile.mkdtemp() wallet_filepath = os.path.join(base_storage_path, "walletfile") storage = WalletStorage(wallet_filepath) assert type(storage._store) is DatabaseStore assert storage.get("wallet_author") == "ESV" assert storage.get("seed_version") == DatabaseStore.INITIAL_SEED_VERSION key = storage.get("tx_store_aeskey") assert type(key) is str
def test_wallet_storage_database_nonexistent_creates(tmp_path) -> None: wallet_filepath = os.path.join(tmp_path, "walletfile") storage = WalletStorage(wallet_filepath) try: assert type(storage._store) is DatabaseStore assert storage.get("migration") == DatabaseStore.CURRENT_MIGRATION finally: storage.close()
def init_cmdline(config_options, server): config = SimpleConfig(config_options) cmdname = config.get('cmd') cmd = known_commands[cmdname] if cmdname == 'signtransaction' and config.get('privkey'): cmd.requires_wallet = False cmd.requires_password = False if cmdname in ['payto', 'paytomany'] and config.get('unsigned'): cmd.requires_password = False if cmdname in ['payto', 'paytomany'] and config.get('broadcast'): cmd.requires_network = True wallet_path = config.get_wallet_path() if cmd.requires_wallet and not WalletStorage.files_are_matched_by_path( wallet_path): print("Error: Wallet file not found.") print("Type 'electrum-sv create' to create a new wallet, " "or provide a path to a wallet with the -w option") sys.exit(0) # instantiate wallet for command-line storage = WalletStorage(wallet_path) # important warning if cmd.name in ['getprivatekeys']: print("WARNING: ALL your private keys are secret.", file=sys.stderr) print( "Exposing a single private key can compromise your entire wallet!", file=sys.stderr) print( "In particular, DO NOT use 'redeem private key' services " "proposed by third parties.", file=sys.stderr) # commands needing password if ((cmd.requires_wallet and storage.is_encrypted() and server is None) or (cmd.requires_password and (storage.get('use_encryption') or storage.is_encrypted()))): if config.get('password'): password = config.get('password') else: password = prompt_password('Password:'******'password'] = password if cmd.name == 'password': new_password = prompt_password('New password:'******'new_password'] = new_password return cmd, password
def test_read_dictionary_from_file(self): some_dict = {"a": "b", "c": "d"} contents = json.dumps(some_dict) with open(self.wallet_path, "w") as f: contents = f.write(contents) storage = WalletStorage(self.wallet_path, manual_upgrades=True) self.assertEqual("b", storage.get("a")) self.assertEqual("d", storage.get("c"))
def create_file_state(wallet_path: str) -> Optional[FileState]: if not os.path.exists(wallet_path): return None try: storage = WalletStorage(wallet_path) except Exception: logger.exception("problem looking at selected wallet '%s'", wallet_path) return None is_too_modern = False try: storage_info = categorise_file(wallet_path) if storage_info.kind == StorageKind.HYBRID: return None wallet_action = WalletAction.OPEN password_state = PasswordState.UNKNOWN if storage_info.kind == StorageKind.FILE: text_store = storage.get_text_store() try: text_store.attempt_load_data() except IOError: # IOError: storage.py:load_data() raises when selected file cannot be parsed. return None if storage.get("use_encryption"): # If there is a password and the wallet is not encrypted, then the private data # is encrypted. password_state = PasswordState.PASSWORDED elif text_store.is_encrypted(): # If there is a password and the wallet is encrypted, then the private data is # encrypted and the file is encrypted. password_state = PasswordState.PASSWORDED | PasswordState.ENCRYPTED else: # Neither the private data is encrypted or the file itself. password_state = PasswordState.NONE else: assert storage_info.kind == StorageKind.DATABASE password_state = PasswordState.PASSWORDED database_store = storage.get_database_store() is_too_modern = database_store.get("migration") > MIGRATION_CURRENT requires_upgrade = storage.requires_split( ) or storage.requires_upgrade() finally: storage.close() name = get_wallet_name_from_path(wallet_path) modification_time = os.path.getmtime(wallet_path) return FileState(name, wallet_path, wallet_action, storage_info.kind, password_state, requires_upgrade, modification_time, is_too_modern)
def _attempt_open_wallet(self, wallet_path: str, change_page: bool = False) -> bool: try: storage = WalletStorage(wallet_path) except Exception: logger.exception("problem looking at selected wallet '%s'", wallet_path) MessageBox.show_error( _("Unrecognised or unsupported wallet file.")) return False try: storage_info = categorise_file(wallet_path) if storage_info.kind == StorageKind.HYBRID: MessageBox.show_error( _("Unrecognised or unsupported wallet file.")) return False wallet_type = StorageKind.FILE if storage.is_legacy_format( ) else StorageKind.DATABASE if wallet_type == StorageKind.FILE: text_store = storage.get_text_store() text_store.attempt_load_data() if storage.get("use_encryption") or text_store.is_encrypted(): # If there is a password and the wallet is not encrypted, then the private data # is encrypted. If there is a password and the wallet is encrypted, then the # private data is encrypted and the file is encrypted. self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_REQUEST else: # Neither the private data is encrypted or the file itself. self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_ADDITION else: self._next_page_id = WalletPage.PREMIGRATION_PASSWORD_REQUEST finally: storage.close() self._force_completed = True wizard: WalletWizard = self.wizard() wizard.set_wallet_action(WalletAction.OPEN) wizard.set_wallet_type(wallet_type) wizard.set_wallet_path(wallet_path) if change_page: wizard.next() return True
def test_write_dictionary_to_file(self): storage = WalletStorage(self.wallet_path) some_dict = { "a": "b", "c": "d", "seed_version": FINAL_SEED_VERSION, "tx_store_aeskey": storage.get("tx_store_aeskey"), "wallet_author": "ESV"} for key, value in some_dict.items(): storage.put(key, value) storage.write() contents = "" with open(self.wallet_path, "r") as f: contents = f.read() self.assertEqual(some_dict, json.loads(contents))
def run_offline_command(config, config_options): cmdname = config.get('cmd') cmd = known_commands[cmdname] password = config_options.get('password') if cmd.requires_wallet: storage = WalletStorage(config.get_wallet_path()) if storage.is_encrypted(): storage.decrypt(password) wallet = Wallet(storage) else: wallet = None # check password if cmd.requires_password and storage.get('use_encryption'): try: seed = wallet.check_password(password) except InvalidPassword: print("Error: This password does not decode this wallet.") sys.exit(1) if cmd.requires_network: print("Warning: running command offline") # arguments passed to function args = [config.get(x) for x in cmd.params] # decode json arguments if cmdname not in ('setconfig', ): args = [json_decode(arg) for arg in args] # options kwargs = {} for x in cmd.options: kwargs[x] = (config_options.get(x) if x in ['password', 'new_password'] else config.get(x)) cmd_runner = Commands(config, wallet, None) func = getattr(cmd_runner, cmd.name) result = func(*args, **kwargs) # save wallet if wallet: wallet.storage.write() return result
def test_wallet_storage_set_password(password, flag) -> None: base_storage_path = tempfile.mkdtemp() wallet_filepath = os.path.join(base_storage_path, "walletfile") storage = WalletStorage(wallet_filepath) storage.set_password(password) assert storage.get("use_encryption") is flag