minor refactor
This commit is contained in:
parent
94deaf55df
commit
734f0651a4
3 changed files with 30 additions and 38 deletions
|
@ -1330,9 +1330,9 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
@requires("wallet")
|
@requires("wallet")
|
||||||
async def jsonrpc_wallet_export(self, password=None, wallet_id=None):
|
async def jsonrpc_wallet_export(self, password=None, wallet_id=None):
|
||||||
"""
|
"""
|
||||||
Export wallet data
|
Exports encrypted wallet data if password is supplied; otherwise plain JSON.
|
||||||
|
|
||||||
Wallet must be unlocked to perform this operation. Exports JSON if password is not supplied.
|
Wallet must be unlocked to perform this operation.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wallet_export [--password=<password>] [--wallet_id=<wallet_id>]
|
wallet_export [--password=<password>] [--wallet_id=<wallet_id>]
|
||||||
|
@ -1342,21 +1342,21 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
--wallet_id=<wallet_id> : (str) wallet being exported
|
--wallet_id=<wallet_id> : (str) wallet being exported
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(str) data: Either base64-encoded encrypted wallet, or cleartext JSON
|
(str) data: base64-encoded encrypted wallet, or cleartext JSON
|
||||||
|
|
||||||
"""
|
"""
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||||
if password is None:
|
if password:
|
||||||
return wallet.pack()
|
return wallet.pack(password).decode()
|
||||||
encrypted = wallet.pack(password)
|
return wallet.to_json()
|
||||||
return encrypted.decode()
|
|
||||||
|
|
||||||
@requires("wallet")
|
@requires("wallet")
|
||||||
async def jsonrpc_wallet_import(self, data, password=None, wallet_id=None, blocking=False):
|
async def jsonrpc_wallet_import(self, data, password=None, wallet_id=None, blocking=False):
|
||||||
"""
|
"""
|
||||||
Import wallet data and merge accounts and preferences.
|
Import wallet data and merge accounts and preferences. Data is expected to be JSON if
|
||||||
|
password is not supplied.
|
||||||
|
|
||||||
Wallet must be unlocked to perform this operation. Data is expected to be JSON if password is not supplied.
|
Wallet must be unlocked to perform this operation.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
wallet_import (<data> | --data=<data>) [<password> | --password=<password>]
|
wallet_import (<data> | --data=<data>) [<password> | --password=<password>]
|
||||||
|
@ -1369,9 +1369,8 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
--blocking : (bool) wait until any new accounts have merged
|
--blocking : (bool) wait until any new accounts have merged
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(str) Either base64-encoded encrypted wallet, or cleartext JSON
|
(str) base64-encoded encrypted wallet, or cleartext JSON
|
||||||
"""
|
"""
|
||||||
|
|
||||||
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
wallet = self.wallet_manager.get_wallet_or_default(wallet_id)
|
||||||
added_accounts, merged_accounts = wallet.merge(self.wallet_manager, password, data)
|
added_accounts, merged_accounts = wallet.merge(self.wallet_manager, password, data)
|
||||||
for new_account in itertools.chain(added_accounts, merged_accounts):
|
for new_account in itertools.chain(added_accounts, merged_accounts):
|
||||||
|
@ -1385,8 +1384,7 @@ class Daemon(metaclass=JSONRPCServerType):
|
||||||
for new_account in added_accounts:
|
for new_account in added_accounts:
|
||||||
asyncio.create_task(self.ledger.subscribe_account(new_account))
|
asyncio.create_task(self.ledger.subscribe_account(new_account))
|
||||||
wallet.save()
|
wallet.save()
|
||||||
encrypted = wallet.pack(password)
|
return await self.jsonrpc_wallet_export(password=password, wallet_id=wallet_id)
|
||||||
return encrypted.decode()
|
|
||||||
|
|
||||||
@requires("wallet")
|
@requires("wallet")
|
||||||
async def jsonrpc_wallet_add(self, wallet_id):
|
async def jsonrpc_wallet_add(self, wallet_id):
|
||||||
|
|
|
@ -139,6 +139,10 @@ class Wallet:
|
||||||
'accounts': [a.to_dict(encrypt_password) for a in self.accounts]
|
'accounts': [a.to_dict(encrypt_password) for a in self.accounts]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
assert not self.is_locked, "Cannot serialize a wallet with locked/encrypted accounts."
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
if self.preferences.get(ENCRYPT_ON_DISK, False):
|
if self.preferences.get(ENCRYPT_ON_DISK, False):
|
||||||
if self.encryption_password is not None:
|
if self.encryption_password is not None:
|
||||||
|
@ -163,19 +167,14 @@ class Wallet:
|
||||||
h.update(account.hash)
|
h.update(account.hash)
|
||||||
return h.digest()
|
return h.digest()
|
||||||
|
|
||||||
def pack(self, password=None):
|
def pack(self, password):
|
||||||
assert not self.is_locked, "Cannot pack a wallet with locked/encrypted accounts."
|
assert not self.is_locked, "Cannot pack a wallet with locked/encrypted accounts."
|
||||||
new_data = json.dumps(self.to_dict())
|
new_data_compressed = zlib.compress(self.to_json().encode())
|
||||||
if password is None:
|
|
||||||
return new_data.encode()
|
|
||||||
new_data_compressed = zlib.compress(new_data.encode())
|
|
||||||
return better_aes_encrypt(password, new_data_compressed)
|
return better_aes_encrypt(password, new_data_compressed)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def unpack(cls, password, data):
|
def unpack(cls, password, encrypted):
|
||||||
if password is None:
|
decrypted = better_aes_decrypt(password, encrypted)
|
||||||
return json.loads(data)
|
|
||||||
decrypted = better_aes_decrypt(password, data)
|
|
||||||
try:
|
try:
|
||||||
decompressed = zlib.decompress(decrypted)
|
decompressed = zlib.decompress(decrypted)
|
||||||
except zlib.error as e:
|
except zlib.error as e:
|
||||||
|
@ -190,7 +189,10 @@ class Wallet:
|
||||||
password: str, data: str) -> (List['Account'], List['Account']):
|
password: str, data: str) -> (List['Account'], List['Account']):
|
||||||
assert not self.is_locked, "Cannot sync apply on a locked wallet."
|
assert not self.is_locked, "Cannot sync apply on a locked wallet."
|
||||||
added_accounts, merged_accounts = [], []
|
added_accounts, merged_accounts = [], []
|
||||||
|
if password:
|
||||||
decrypted_data = self.unpack(password, data)
|
decrypted_data = self.unpack(password, data)
|
||||||
|
else:
|
||||||
|
decrypted_data = json.loads(data)
|
||||||
self.preferences.merge(decrypted_data.get('preferences', {}))
|
self.preferences.merge(decrypted_data.get('preferences', {}))
|
||||||
for account_dict in decrypted_data['accounts']:
|
for account_dict in decrypted_data['accounts']:
|
||||||
ledger = manager.get_or_create_ledger(account_dict['ledger'])
|
ledger = manager.get_or_create_ledger(account_dict['ledger'])
|
||||||
|
|
|
@ -493,19 +493,11 @@ class WalletEncryptionAndSynchronization(CommandTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# test without passwords
|
# test without passwords
|
||||||
daemon2.jsonrpc_preference_set("three", "3")
|
data = await daemon2.jsonrpc_wallet_export()
|
||||||
jsondata = await daemon2.jsonrpc_wallet_export()
|
json_data = json.loads(data)
|
||||||
await daemon.jsonrpc_wallet_import(data=jsondata, blocking=True)
|
self.assertEqual(json_data["name"], "Wallet")
|
||||||
self.assertDictEqual(
|
self.assertNotIn("four", json_data["preferences"])
|
||||||
# "two" key added and "conflict" value changed to "2"
|
|
||||||
daemon.jsonrpc_preference_get(),
|
|
||||||
{
|
|
||||||
"one": "1",
|
|
||||||
"two": "2",
|
|
||||||
"three": "3",
|
|
||||||
"conflict": "2",
|
|
||||||
"another": "B",
|
|
||||||
"fruit": ["peach", "apricot"]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
json_data["preferences"]["four"] = {"value": 4, "ts": 0}
|
||||||
|
await daemon.jsonrpc_wallet_import(data=json.dumps(json_data), blocking=True)
|
||||||
|
self.assertEqual(daemon.jsonrpc_preference_get("four"), {"four": 4})
|
||||||
|
|
Loading…
Reference in a new issue