wallet.restore_wallet_from_text: support creating wallet in-memory
This commit is contained in:
@@ -102,7 +102,7 @@ class WalletStorage(Logger):
|
||||
def file_exists(self) -> bool:
|
||||
return self._file_exists
|
||||
|
||||
def is_past_initial_decryption(self):
|
||||
def is_past_initial_decryption(self) -> bool:
|
||||
"""Return if storage is in a usable state for normal operations.
|
||||
|
||||
The value is True exactly
|
||||
@@ -111,14 +111,14 @@ class WalletStorage(Logger):
|
||||
"""
|
||||
return not self.is_encrypted() or bool(self.pubkey)
|
||||
|
||||
def is_encrypted(self):
|
||||
def is_encrypted(self) -> bool:
|
||||
"""Return if storage encryption is currently enabled."""
|
||||
return self.get_encryption_version() != StorageEncryptionVersion.PLAINTEXT
|
||||
|
||||
def is_encrypted_with_user_pw(self):
|
||||
def is_encrypted_with_user_pw(self) -> bool:
|
||||
return self.get_encryption_version() == StorageEncryptionVersion.USER_PASSWORD
|
||||
|
||||
def is_encrypted_with_hw_device(self):
|
||||
def is_encrypted_with_hw_device(self) -> bool:
|
||||
return self.get_encryption_version() == StorageEncryptionVersion.XPUB_PASSWORD
|
||||
|
||||
def get_encryption_version(self):
|
||||
|
||||
@@ -195,6 +195,19 @@ class TestCreateRestoreWallet(WalletTestCase):
|
||||
self.assertEqual(encrypt_file, wallet.storage.is_encrypted())
|
||||
self.assertEqual('bc1q2ccr34wzep58d4239tl3x3734ttle92a8srmuw', wallet.get_receiving_addresses()[0])
|
||||
|
||||
def test_restore_wallet_from_text_no_storage(self):
|
||||
text = 'bitter grass shiver impose acquire brush forget axis eager alone wine silver'
|
||||
d = restore_wallet_from_text(
|
||||
text,
|
||||
path=None,
|
||||
gap_limit=1,
|
||||
config=self.config,
|
||||
)
|
||||
wallet = d['wallet'] # type: Standard_Wallet
|
||||
self.assertEqual(None, wallet.storage)
|
||||
self.assertEqual(text, wallet.keystore.get_seed(None))
|
||||
self.assertEqual('bc1q3g5tmkmlvxryhh843v4dz026avatc0zzr6h3af', wallet.get_receiving_addresses()[0])
|
||||
|
||||
def test_restore_wallet_from_text_xpub(self):
|
||||
text = 'zpub6nydoME6CFdJtMpzHW5BNoPz6i6XbeT9qfz72wsRqGdgGEYeivso6xjfw8cGcCyHwF7BNW4LDuHF35XrZsovBLWMF4qXSjmhTXYiHbWqGLt'
|
||||
d = restore_wallet_from_text(text, path=self.wallet_path, gap_limit=1, config=self.config)
|
||||
|
||||
@@ -2561,7 +2561,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
def can_delete_address(self):
|
||||
return False
|
||||
|
||||
def has_password(self):
|
||||
def has_password(self) -> bool:
|
||||
return self.has_keystore_encryption() or self.has_storage_encryption()
|
||||
|
||||
def can_have_keystore_encryption(self):
|
||||
@@ -2578,18 +2578,18 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
||||
else:
|
||||
return StorageEncryptionVersion.USER_PASSWORD
|
||||
|
||||
def has_keystore_encryption(self):
|
||||
def has_keystore_encryption(self) -> bool:
|
||||
"""Returns whether encryption is enabled for the keystore.
|
||||
|
||||
If True, e.g. signing a transaction will require a password.
|
||||
"""
|
||||
if self.can_have_keystore_encryption():
|
||||
return self.db.get('use_encryption', False)
|
||||
return bool(self.db.get('use_encryption', False))
|
||||
return False
|
||||
|
||||
def has_storage_encryption(self):
|
||||
def has_storage_encryption(self) -> bool:
|
||||
"""Returns whether encryption is enabled for the wallet file on disk."""
|
||||
return self.storage and self.storage.is_encrypted()
|
||||
return bool(self.storage) and self.storage.is_encrypted()
|
||||
|
||||
@classmethod
|
||||
def may_have_password(cls):
|
||||
@@ -3484,15 +3484,18 @@ def create_new_wallet(*, path, config: SimpleConfig, passphrase=None, password=N
|
||||
return {'seed': seed, 'wallet': wallet, 'msg': msg}
|
||||
|
||||
|
||||
def restore_wallet_from_text(text, *, path, config: SimpleConfig,
|
||||
def restore_wallet_from_text(text, *, path: Optional[str], config: SimpleConfig,
|
||||
passphrase=None, password=None, encrypt_file=True,
|
||||
gap_limit=None) -> dict:
|
||||
"""Restore a wallet from text. Text can be a seed phrase, a master
|
||||
public key, a master private key, a list of bitcoin addresses
|
||||
or bitcoin private keys."""
|
||||
storage = WalletStorage(path)
|
||||
if storage.file_exists():
|
||||
raise Exception("Remove the existing wallet first!")
|
||||
if path is None: # create wallet in-memory
|
||||
storage = None
|
||||
else:
|
||||
storage = WalletStorage(path)
|
||||
if storage.file_exists():
|
||||
raise Exception("Remove the existing wallet first!")
|
||||
db = WalletDB('', manual_upgrades=False)
|
||||
text = text.strip()
|
||||
if keystore.is_address_list(text):
|
||||
@@ -3525,7 +3528,8 @@ def restore_wallet_from_text(text, *, path, config: SimpleConfig,
|
||||
if gap_limit is not None:
|
||||
db.put('gap_limit', gap_limit)
|
||||
wallet = Wallet(db, storage, config=config)
|
||||
assert not storage.file_exists(), "file was created too soon! plaintext keys might have been written to disk"
|
||||
if storage:
|
||||
assert not storage.file_exists(), "file was created too soon! plaintext keys might have been written to disk"
|
||||
wallet.update_password(old_pw=None, new_pw=password, encrypt_storage=encrypt_file)
|
||||
wallet.synchronize()
|
||||
msg = ("This wallet was restored offline. It may contain more addresses than displayed. "
|
||||
|
||||
Reference in New Issue
Block a user