wallet encryption
This commit is contained in:
parent
dc580b9eff
commit
270f77df24
4 changed files with 55 additions and 133 deletions
|
@ -252,8 +252,6 @@ class WalletComponent(Component):
|
||||||
'blocks': max(local_height, 0),
|
'blocks': max(local_height, 0),
|
||||||
'blocks_behind': max(remote_height - local_height, 0),
|
'blocks_behind': max(remote_height - local_height, 0),
|
||||||
'best_blockhash': best_hash,
|
'best_blockhash': best_hash,
|
||||||
'is_encrypted': self.wallet_manager.use_encryption,
|
|
||||||
'is_locked': not self.wallet_manager.is_wallet_unlocked,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async def start(self):
|
async def start(self):
|
||||||
|
|
|
@ -1166,6 +1166,22 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
)
|
)
|
||||||
return dict_values_to_lbc(balance)
|
return dict_values_to_lbc(balance)
|
||||||
|
|
||||||
|
def jsonrpc_wallet_status(self, wallet_id=None):
|
||||||
|
"""
|
||||||
|
Status of wallet including encryption/lock state.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
wallet_status [<wallet_id> | --wallet_id=<wallet_id>]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--wallet_id=<wallet_id> : (str) status of specific wallet
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary of wallet status information.
|
||||||
|
"""
|
||||||
|
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||||
|
return {'is_encrypted': wallet.is_encrypted, 'is_locked': wallet.is_locked}
|
||||||
|
|
||||||
@requires(WALLET_COMPONENT)
|
@requires(WALLET_COMPONENT)
|
||||||
def jsonrpc_wallet_unlock(self, password, wallet_id=None):
|
def jsonrpc_wallet_unlock(self, password, wallet_id=None):
|
||||||
"""
|
"""
|
||||||
|
@ -1501,98 +1517,6 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
|
|
||||||
return account
|
return account
|
||||||
|
|
||||||
@deprecated('wallet_unlock')
|
|
||||||
@requires(WALLET_COMPONENT)
|
|
||||||
def jsonrpc_account_unlock(self, password, account_id=None, wallet_id=None):
|
|
||||||
"""
|
|
||||||
Unlock an encrypted account
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
account_unlock (<password> | --password=<password>)
|
|
||||||
[<account_id> | --account_id=<account_id>]
|
|
||||||
[--wallet_id=<wallet_id>]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--password=<password> : (str) password to use for unlocking
|
|
||||||
--account_id=<account_id> : (str) id for the account to unlock, unlocks default account
|
|
||||||
if not provided
|
|
||||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(bool) true if account is unlocked, otherwise false
|
|
||||||
"""
|
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
|
||||||
return self.wallet_manager.unlock_account(
|
|
||||||
password, wallet.get_account_or_default(account_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
@deprecated('wallet_lock')
|
|
||||||
@requires(WALLET_COMPONENT)
|
|
||||||
def jsonrpc_account_lock(self, account_id=None, wallet_id=None):
|
|
||||||
"""
|
|
||||||
Lock an unlocked account
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
account_lock [<account_id> | --account_id=<account_id>] [--wallet_id=<wallet_id>]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--account_id=<account_id> : (str) id for the account to lock
|
|
||||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(bool) true if account is locked, otherwise false
|
|
||||||
"""
|
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
|
||||||
return self.wallet_manager.lock_account(
|
|
||||||
wallet.get_account_or_default(account_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
@deprecated('wallet_decrypt')
|
|
||||||
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
|
|
||||||
def jsonrpc_account_decrypt(self, account_id=None, wallet_id=None):
|
|
||||||
"""
|
|
||||||
Decrypt an encrypted account, this will remove the wallet password. The account must be unlocked to decrypt it
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
account_decrypt [<account_id> | --account_id=<account_id>] [--wallet_id=<wallet_id>]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--account_id=<account_id> : (str) id for the account to decrypt
|
|
||||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(bool) true if wallet is decrypted, otherwise false
|
|
||||||
"""
|
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
|
||||||
return self.wallet_manager.decrypt_account(
|
|
||||||
wallet.get_account_or_default(account_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
@deprecated('wallet_encrypt')
|
|
||||||
@requires(WALLET_COMPONENT, conditions=[WALLET_IS_UNLOCKED])
|
|
||||||
def jsonrpc_account_encrypt(self, new_password, account_id=None, wallet_id=None):
|
|
||||||
"""
|
|
||||||
Encrypt an unencrypted account with a password
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
account_encrypt (<new_password> | --new_password=<new_password>)
|
|
||||||
[<account_id> | --account_id=<account_id>]
|
|
||||||
[--wallet_id=<wallet_id>]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--new_password=<new_password> : (str) password to encrypt account
|
|
||||||
--account_id=<account_id> : (str) id for the account to encrypt, encrypts
|
|
||||||
default account if not provided
|
|
||||||
--wallet_id=<wallet_id> : (str) restrict operation to specific wallet
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(bool) true if wallet is decrypted, otherwise false
|
|
||||||
"""
|
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
|
||||||
return self.wallet_manager.encrypt_account(
|
|
||||||
new_password, wallet.get_account_or_default(account_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
@requires("wallet")
|
@requires("wallet")
|
||||||
def jsonrpc_account_max_address_gap(self, account_id, wallet_id=None):
|
def jsonrpc_account_max_address_gap(self, account_id, wallet_id=None):
|
||||||
"""
|
"""
|
||||||
|
@ -1720,6 +1644,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||||
|
assert not wallet.is_locked, "Cannot sync apply on a locked wallet."
|
||||||
if data is not None:
|
if data is not None:
|
||||||
added_accounts = wallet.merge(self.wallet_manager, password, data)
|
added_accounts = wallet.merge(self.wallet_manager, password, data)
|
||||||
if added_accounts and self.ledger.network.is_connected:
|
if added_accounts and self.ledger.network.is_connected:
|
||||||
|
|
|
@ -26,42 +26,8 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
def db(self) -> WalletDatabase:
|
def db(self) -> WalletDatabase:
|
||||||
return self.ledger.db
|
return self.ledger.db
|
||||||
|
|
||||||
@property
|
|
||||||
def use_encryption(self):
|
|
||||||
return self.default_account.serialize_encrypted
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_wallet_unlocked(self):
|
|
||||||
return not self.default_account.encrypted
|
|
||||||
|
|
||||||
def check_locked(self):
|
def check_locked(self):
|
||||||
return self.default_account.encrypted
|
return self.default_wallet.is_locked
|
||||||
|
|
||||||
def decrypt_account(self, account):
|
|
||||||
assert account.password is not None, "account is not unlocked"
|
|
||||||
assert not account.encrypted, "account is not unlocked"
|
|
||||||
account.serialize_encrypted = False
|
|
||||||
self.save()
|
|
||||||
return not account.encrypted and not account.serialize_encrypted
|
|
||||||
|
|
||||||
def encrypt_account(self, password, account):
|
|
||||||
assert not account.encrypted, "account is already encrypted"
|
|
||||||
account.encrypt(password)
|
|
||||||
account.serialize_encrypted = True
|
|
||||||
self.save()
|
|
||||||
self.unlock_account(password, account)
|
|
||||||
return account.serialize_encrypted
|
|
||||||
|
|
||||||
def unlock_account(self, password, account):
|
|
||||||
assert account.encrypted, "account is not locked"
|
|
||||||
account.decrypt(password)
|
|
||||||
return not account.encrypted
|
|
||||||
|
|
||||||
def lock_account(self, account):
|
|
||||||
assert account.password is not None, "account is already locked"
|
|
||||||
assert not account.encrypted and account.serialize_encrypted, "account is not encrypted"
|
|
||||||
account.encrypt(account.password)
|
|
||||||
return account.encrypted
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def migrate_lbryum_to_torba(path):
|
def migrate_lbryum_to_torba(path):
|
||||||
|
@ -210,7 +176,3 @@ class LbryWalletManager(BaseWalletManager):
|
||||||
tx = self.ledger.transaction_class(unhexlify(raw))
|
tx = self.ledger.transaction_class(unhexlify(raw))
|
||||||
await self.ledger.maybe_verify_transaction(tx, height)
|
await self.ledger.maybe_verify_transaction(tx, height)
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
def save(self):
|
|
||||||
for wallet in self.wallets:
|
|
||||||
wallet.save()
|
|
||||||
|
|
|
@ -170,6 +170,43 @@ class Wallet:
|
||||||
added_accounts.append(new_account)
|
added_accounts.append(new_account)
|
||||||
return added_accounts
|
return added_accounts
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_locked(self) -> bool:
|
||||||
|
for account in self.accounts:
|
||||||
|
if account.encrypted:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def unlock(self, password):
|
||||||
|
for account in self.accounts:
|
||||||
|
if account.encrypted:
|
||||||
|
account.decrypt(password)
|
||||||
|
|
||||||
|
def lock(self):
|
||||||
|
for account in self.accounts:
|
||||||
|
if not account.encrypted:
|
||||||
|
account.encrypt(account.password)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_encrypted(self) -> bool:
|
||||||
|
for account in self.accounts:
|
||||||
|
if account.serialize_encrypted:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def decrypt(self):
|
||||||
|
for account in self.accounts:
|
||||||
|
account.serialize_encrypted = False
|
||||||
|
self.save()
|
||||||
|
|
||||||
|
def encrypt(self, password):
|
||||||
|
for account in self.accounts:
|
||||||
|
if not self.encrypted:
|
||||||
|
account.encrypt(password)
|
||||||
|
account.serialize_encrypted = True
|
||||||
|
self.save()
|
||||||
|
self.unlock(password)
|
||||||
|
|
||||||
|
|
||||||
class WalletStorage:
|
class WalletStorage:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue