Make storage a field of db
This comes from the jsonpatch_new branch. I rather have in master now, because it touches a lot of filese.
This commit is contained in:
@@ -680,12 +680,12 @@ class BaseWizard(Logger):
|
|||||||
storage = WalletStorage(path)
|
storage = WalletStorage(path)
|
||||||
if pw_args.encrypt_storage:
|
if pw_args.encrypt_storage:
|
||||||
storage.set_password(pw_args.password, enc_version=pw_args.storage_enc_version)
|
storage.set_password(pw_args.password, enc_version=pw_args.storage_enc_version)
|
||||||
db = WalletDB('', manual_upgrades=False)
|
db = WalletDB('', storage=storage, manual_upgrades=False)
|
||||||
db.set_keystore_encryption(bool(pw_args.password) and pw_args.encrypt_keystore)
|
db.set_keystore_encryption(bool(pw_args.password) and pw_args.encrypt_keystore)
|
||||||
for key, value in self.data.items():
|
for key, value in self.data.items():
|
||||||
db.put(key, value)
|
db.put(key, value)
|
||||||
db.load_plugins()
|
db.load_plugins()
|
||||||
db.write(storage)
|
db.write()
|
||||||
return storage, db
|
return storage, db
|
||||||
|
|
||||||
def terminate(self, *, storage: WalletStorage = None,
|
def terminate(self, *, storage: WalletStorage = None,
|
||||||
|
|||||||
+2
-2
@@ -511,14 +511,14 @@ class Daemon(Logger):
|
|||||||
return
|
return
|
||||||
storage.decrypt(password)
|
storage.decrypt(password)
|
||||||
# read data, pass it to db
|
# read data, pass it to db
|
||||||
db = WalletDB(storage.read(), manual_upgrades=manual_upgrades)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=manual_upgrades)
|
||||||
if db.requires_split():
|
if db.requires_split():
|
||||||
return
|
return
|
||||||
if db.requires_upgrade():
|
if db.requires_upgrade():
|
||||||
return
|
return
|
||||||
if db.get_action():
|
if db.get_action():
|
||||||
return
|
return
|
||||||
wallet = Wallet(db, storage, config=config)
|
wallet = Wallet(db, config=config)
|
||||||
return wallet
|
return wallet
|
||||||
|
|
||||||
@with_wallet_lock
|
@with_wallet_lock
|
||||||
|
|||||||
@@ -673,13 +673,13 @@ class ElectrumWindow(App, Logger, EventListener):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def on_wizard_success(self, storage, db, password):
|
def on_wizard_success(self, db, password):
|
||||||
self.password = password
|
self.password = password
|
||||||
if self.electrum_config.WALLET_USE_SINGLE_PASSWORD:
|
if self.electrum_config.WALLET_USE_SINGLE_PASSWORD:
|
||||||
self._use_single_password = self.daemon.update_password_for_directory(
|
self._use_single_password = self.daemon.update_password_for_directory(
|
||||||
old_password=password, new_password=password)
|
old_password=password, new_password=password)
|
||||||
self.logger.info(f'use single password: {self._use_single_password}')
|
self.logger.info(f'use single password: {self._use_single_password}')
|
||||||
wallet = Wallet(db, storage, config=self.electrum_config)
|
wallet = Wallet(db, config=self.electrum_config)
|
||||||
wallet.start_network(self.daemon.network)
|
wallet.start_network(self.daemon.network)
|
||||||
self.daemon.add_wallet(wallet)
|
self.daemon.add_wallet(wallet)
|
||||||
self.load_wallet(wallet)
|
self.load_wallet(wallet)
|
||||||
@@ -714,7 +714,7 @@ class ElectrumWindow(App, Logger, EventListener):
|
|||||||
wizard.run('new')
|
wizard.run('new')
|
||||||
else:
|
else:
|
||||||
assert storage.is_past_initial_decryption()
|
assert storage.is_past_initial_decryption()
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
assert not db.requires_upgrade()
|
assert not db.requires_upgrade()
|
||||||
self.on_wizard_success(storage, db, password)
|
self.on_wizard_success(storage, db, password)
|
||||||
|
|
||||||
|
|||||||
@@ -359,8 +359,8 @@ class OpenWalletDialog(PasswordDialog):
|
|||||||
else:
|
else:
|
||||||
# it is a bit wasteful load the wallet here and load it again in main_window,
|
# it is a bit wasteful load the wallet here and load it again in main_window,
|
||||||
# but that is fine, because we are progressively enforcing storage encryption.
|
# but that is fine, because we are progressively enforcing storage encryption.
|
||||||
db = WalletDB(self.storage.read(), manual_upgrades=False)
|
db = WalletDB(self.storage.read(), storage=self.storage, manual_upgrades=False)
|
||||||
wallet = Wallet(db, self.storage, config=self.app.electrum_config)
|
wallet = Wallet(db, config=self.app.electrum_config)
|
||||||
self.require_password = wallet.has_password()
|
self.require_password = wallet.has_password()
|
||||||
self.pw_check = wallet.check_password
|
self.pw_check = wallet.check_password
|
||||||
self.message = self.enter_pw_message if self.require_password else _('Wallet not encrypted')
|
self.message = self.enter_pw_message if self.require_password else _('Wallet not encrypted')
|
||||||
|
|||||||
@@ -162,8 +162,8 @@ class QEWalletDB(QObject):
|
|||||||
else: # storage not encrypted; but it might still have a keystore pw
|
else: # storage not encrypted; but it might still have a keystore pw
|
||||||
# FIXME hack... load both db and full wallet, just to tell if it has keystore pw.
|
# FIXME hack... load both db and full wallet, just to tell if it has keystore pw.
|
||||||
# this also completely ignores db.requires_split(), db.get_action(), etc
|
# this also completely ignores db.requires_split(), db.get_action(), etc
|
||||||
db = WalletDB(self._storage.read(), manual_upgrades=False)
|
db = WalletDB(self._storage.read(), storage=self._storage, manual_upgrades=False)
|
||||||
wallet = Wallet(db, self._storage, config=self._config)
|
wallet = Wallet(db, config=self._config)
|
||||||
self.needsPassword = wallet.has_password()
|
self.needsPassword = wallet.has_password()
|
||||||
if self.needsPassword:
|
if self.needsPassword:
|
||||||
try:
|
try:
|
||||||
@@ -181,7 +181,7 @@ class QEWalletDB(QObject):
|
|||||||
def _load_db(self):
|
def _load_db(self):
|
||||||
"""can raise WalletFileException"""
|
"""can raise WalletFileException"""
|
||||||
# needs storage accessible
|
# needs storage accessible
|
||||||
self._db = WalletDB(self._storage.read(), manual_upgrades=True)
|
self._db = WalletDB(self._storage.read(), storage=self._storage, manual_upgrades=True)
|
||||||
if self._db.requires_split():
|
if self._db.requires_split():
|
||||||
self._logger.warning('wallet requires split')
|
self._logger.warning('wallet requires split')
|
||||||
self._requiresSplit = True
|
self._requiresSplit = True
|
||||||
@@ -194,7 +194,7 @@ class QEWalletDB(QObject):
|
|||||||
if self._db.requires_upgrade():
|
if self._db.requires_upgrade():
|
||||||
self._logger.warning('wallet requires upgrade, upgrading')
|
self._logger.warning('wallet requires upgrade, upgrading')
|
||||||
self._db.upgrade()
|
self._db.upgrade()
|
||||||
self._db.write(self._storage)
|
self._db.write()
|
||||||
|
|
||||||
self._ready = True
|
self._ready = True
|
||||||
self.readyChanged.emit()
|
self.readyChanged.emit()
|
||||||
|
|||||||
@@ -407,7 +407,7 @@ class ElectrumGui(BaseElectrumGui, Logger):
|
|||||||
wizard.run('new')
|
wizard.run('new')
|
||||||
storage, db = wizard.create_storage(path)
|
storage, db = wizard.create_storage(path)
|
||||||
else:
|
else:
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
wizard.run_upgrades(storage, db)
|
wizard.run_upgrades(storage, db)
|
||||||
except (UserCancelled, GoBack):
|
except (UserCancelled, GoBack):
|
||||||
return
|
return
|
||||||
@@ -418,7 +418,7 @@ class ElectrumGui(BaseElectrumGui, Logger):
|
|||||||
# return if wallet creation is not complete
|
# return if wallet creation is not complete
|
||||||
if storage is None or db.get_action():
|
if storage is None or db.get_action():
|
||||||
return
|
return
|
||||||
wallet = Wallet(db, storage, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
wallet.start_network(self.daemon.network)
|
wallet.start_network(self.daemon.network)
|
||||||
self.daemon.add_wallet(wallet)
|
self.daemon.add_wallet(wallet)
|
||||||
return wallet
|
return wallet
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class ElectrumGui(BaseElectrumGui, EventListener):
|
|||||||
password = getpass.getpass('Password:', stream=None)
|
password = getpass.getpass('Password:', stream=None)
|
||||||
storage.decrypt(password)
|
storage.decrypt(password)
|
||||||
|
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
|
|
||||||
self.done = 0
|
self.done = 0
|
||||||
self.last_balance = ""
|
self.last_balance = ""
|
||||||
@@ -43,7 +43,7 @@ class ElectrumGui(BaseElectrumGui, EventListener):
|
|||||||
self.str_amount = ""
|
self.str_amount = ""
|
||||||
self.str_fee = ""
|
self.str_fee = ""
|
||||||
|
|
||||||
self.wallet = Wallet(db, storage, config=config) # type: Optional[Abstract_Wallet]
|
self.wallet = Wallet(db, config=config) # type: Optional[Abstract_Wallet]
|
||||||
self.wallet.start_network(self.network)
|
self.wallet.start_network(self.network)
|
||||||
self.contacts = self.wallet.contacts
|
self.contacts = self.wallet.contacts
|
||||||
|
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ class ElectrumGui(BaseElectrumGui, EventListener):
|
|||||||
if storage.is_encrypted():
|
if storage.is_encrypted():
|
||||||
password = getpass.getpass('Password:', stream=None)
|
password = getpass.getpass('Password:', stream=None)
|
||||||
storage.decrypt(password)
|
storage.decrypt(password)
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
self.wallet = Wallet(db, storage, config=config) # type: Optional[Abstract_Wallet]
|
self.wallet = Wallet(db, config=config) # type: Optional[Abstract_Wallet]
|
||||||
self.wallet.start_network(self.network)
|
self.wallet.start_network(self.network)
|
||||||
self.contacts = self.wallet.contacts
|
self.contacts = self.wallet.contacts
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -168,9 +168,10 @@ class StoredDict(dict):
|
|||||||
|
|
||||||
class JsonDB(Logger):
|
class JsonDB(Logger):
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data, storage=None):
|
||||||
Logger.__init__(self)
|
Logger.__init__(self)
|
||||||
self.lock = threading.RLock()
|
self.lock = threading.RLock()
|
||||||
|
self.storage = storage
|
||||||
self._modified = False
|
self._modified = False
|
||||||
# load data
|
# load data
|
||||||
if data:
|
if data:
|
||||||
@@ -268,18 +269,17 @@ class JsonDB(Logger):
|
|||||||
v = constructor(v)
|
v = constructor(v)
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def write(self, storage: 'WalletStorage'):
|
def write(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
self._write(storage)
|
self._write()
|
||||||
|
|
||||||
@profiler
|
@profiler
|
||||||
def _write(self, storage: 'WalletStorage'):
|
def _write(self):
|
||||||
if threading.current_thread().daemon:
|
if threading.current_thread().daemon:
|
||||||
self.logger.warning('daemon thread cannot write db')
|
self.logger.warning('daemon thread cannot write db')
|
||||||
return
|
return
|
||||||
if not self.modified():
|
if not self.modified():
|
||||||
return
|
return
|
||||||
json_str = self.dump(human_readable=not storage.is_encrypted())
|
json_str = self.dump(human_readable=not self.storage.is_encrypted())
|
||||||
storage.write(json_str)
|
self.storage.write(json_str)
|
||||||
self.set_modified(False)
|
self.set_modified(False)
|
||||||
|
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ class WatchTower(LNWatcher):
|
|||||||
LOGGING_SHORTCUT = 'W'
|
LOGGING_SHORTCUT = 'W'
|
||||||
|
|
||||||
def __init__(self, network: 'Network'):
|
def __init__(self, network: 'Network'):
|
||||||
adb = AddressSynchronizer(WalletDB({}, manual_upgrades=False), network.config, name=self.diagnostic_name())
|
adb = AddressSynchronizer(WalletDB({}, storage=None, manual_upgrades=False), network.config, name=self.diagnostic_name())
|
||||||
adb.start_network(network)
|
adb.start_network(network)
|
||||||
LNWatcher.__init__(self, adb, network)
|
LNWatcher.__init__(self, adb, network)
|
||||||
self.network = network
|
self.network = network
|
||||||
|
|||||||
@@ -265,9 +265,9 @@ class Wallet_2fa(Multisig_Wallet):
|
|||||||
|
|
||||||
wallet_type = '2fa'
|
wallet_type = '2fa'
|
||||||
|
|
||||||
def __init__(self, db, storage, *, config):
|
def __init__(self, db, *, config):
|
||||||
self.m, self.n = 2, 3
|
self.m, self.n = 2, 3
|
||||||
Deterministic_Wallet.__init__(self, db, storage, config=config)
|
Deterministic_Wallet.__init__(self, db, config=config)
|
||||||
self.is_billing = False
|
self.is_billing = False
|
||||||
self.billing_info = None
|
self.billing_info = None
|
||||||
self._load_billing_addresses()
|
self._load_billing_addresses()
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ class TestStorageUpgrade(WalletTestCase):
|
|||||||
# see #6066
|
# see #6066
|
||||||
wallet_str = '''{"addr_history":{"bc1q0k4hemnmw5czyq7yyka5mpc3hvz37lk0urhd34":[],"bc1q2tgeuhkr85pjkrys44zn2a7lfap0g8u7ny68p3":[],"bc1q2xm8slpsqlt47u0j7segcsfmaq6s4s2pvx2526":[],"bc1q4dhwcvnnm8a0umt4gvn2tatq66qf9d37rx5t8u":[],"bc1q4pqe6tcfyl8m35myj9trz7fn4w0kdpljnt3sxd":[],"bc1q5l345sqf8fhlurn4hgu8dxu0w76j5tf3kc2f7h":[],"bc1q5nd447vdf9gx0l8xmj500wr859pny29xurgcpn":[],"bc1qaa2xnanrpmttw35gc4xqvz9ldz5sggqvc2ed72":[],"bc1qav4zrnx5g4s5h2z5hzr9hncg8qwt96ezltepmp":[],"bc1qcxryu22d3k66k4l55dzupvx45e88lmvp3rcww3":[],"bc1qd4us67486cn5qy44z6v6ervv5cuzrykq0vlcw2":[],"bc1qdd773rd9p8t3eylv2gvs2tmn2n79pwcfz65uyp":[],"bc1qdwafv8hy0cx9utkkj4hs6ntafm3x95m9zgpgvn":[],"bc1qehqt2um35x0c49snyugf94hvh7jz3vcjt0ya6m":[],"bc1qex23ueucc9hxyxgk3jg8ahw7cgw954legfnrxg":[],"bc1qf4tx5eesmrcy478gk384s2jv4lfh9dwt9jws0e":[],"bc1qh9l2au0f6m2fl3l3qa6perw5xnpvjul8lyylkt":[],"bc1qkmprcg50zcsdd0p3w70w2rxs5hwmwwn2xd0ls9":[],"bc1qkztpz05djsatmxxafgjqqldp0yfs8knr6um3e4":[],"bc1qrgj0zygryl6edylgm6gzx5j9rghdufrn5fp6hw":[],"bc1qscxh3na5uqapjm006xmg4s0geurq7nw427ywca":[],"bc1qunqye3f6cw88wqsjkks7amskder0rvufu49l6e":[],"bc1qv077qy5udlr3q8ammxq9ecq57vh9lxjnwh0vy9":[],"bc1qw9nqstryl3e0e49jg6670u6mu8507takz66qgv":[],"bc1qx4neqay68lmvgrav3yslzuempv9xn7aqdks5r6":[],"bc1qzhwpu84e5ajet4mxxr9ylc0fwass3q5k32uj5u":[]},"addresses":{"change":["bc1qdd773rd9p8t3eylv2gvs2tmn2n79pwcfz65uyp","bc1qv077qy5udlr3q8ammxq9ecq57vh9lxjnwh0vy9","bc1qx4neqay68lmvgrav3yslzuempv9xn7aqdks5r6","bc1qh9l2au0f6m2fl3l3qa6perw5xnpvjul8lyylkt","bc1qw9nqstryl3e0e49jg6670u6mu8507takz66qgv","bc1qaa2xnanrpmttw35gc4xqvz9ldz5sggqvc2ed72"],"receiving":["bc1qav4zrnx5g4s5h2z5hzr9hncg8qwt96ezltepmp","bc1qzhwpu84e5ajet4mxxr9ylc0fwass3q5k32uj5u","bc1qehqt2um35x0c49snyugf94hvh7jz3vcjt0ya6m","bc1q0k4hemnmw5czyq7yyka5mpc3hvz37lk0urhd34","bc1qf4tx5eesmrcy478gk384s2jv4lfh9dwt9jws0e","bc1q2xm8slpsqlt47u0j7segcsfmaq6s4s2pvx2526","bc1q5nd447vdf9gx0l8xmj500wr859pny29xurgcpn","bc1qex23ueucc9hxyxgk3jg8ahw7cgw954legfnrxg","bc1qscxh3na5uqapjm006xmg4s0geurq7nw427ywca","bc1qdwafv8hy0cx9utkkj4hs6ntafm3x95m9zgpgvn","bc1qkmprcg50zcsdd0p3w70w2rxs5hwmwwn2xd0ls9","bc1qunqye3f6cw88wqsjkks7amskder0rvufu49l6e","bc1q5l345sqf8fhlurn4hgu8dxu0w76j5tf3kc2f7h","bc1q4pqe6tcfyl8m35myj9trz7fn4w0kdpljnt3sxd","bc1qkztpz05djsatmxxafgjqqldp0yfs8knr6um3e4","bc1q4dhwcvnnm8a0umt4gvn2tatq66qf9d37rx5t8u","bc1q2tgeuhkr85pjkrys44zn2a7lfap0g8u7ny68p3","bc1qrgj0zygryl6edylgm6gzx5j9rghdufrn5fp6hw","bc1qd4us67486cn5qy44z6v6ervv5cuzrykq0vlcw2","bc1qcxryu22d3k66k4l55dzupvx45e88lmvp3rcww3"]},"keystore":{"cfg":{"mode":0,"pair":""},"derivation":"m/84'/0'/0'","hw_type":"ledger","label":"","type":"hardware","xpub":"zpub6qmVsnBYWipPzoeuZwtVeVnC42achPEZpGopT7jsop5WgDuFqKT3aS3EuAAQ6G76wbwtvDMdzffwxyEtwa6iafXSgjW2RjraiXfsgxQHnz8"},"seed_version":18,"spent_outpoints":{},"stored_height":646576,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[168,276,840,400]}'''
|
wallet_str = '''{"addr_history":{"bc1q0k4hemnmw5czyq7yyka5mpc3hvz37lk0urhd34":[],"bc1q2tgeuhkr85pjkrys44zn2a7lfap0g8u7ny68p3":[],"bc1q2xm8slpsqlt47u0j7segcsfmaq6s4s2pvx2526":[],"bc1q4dhwcvnnm8a0umt4gvn2tatq66qf9d37rx5t8u":[],"bc1q4pqe6tcfyl8m35myj9trz7fn4w0kdpljnt3sxd":[],"bc1q5l345sqf8fhlurn4hgu8dxu0w76j5tf3kc2f7h":[],"bc1q5nd447vdf9gx0l8xmj500wr859pny29xurgcpn":[],"bc1qaa2xnanrpmttw35gc4xqvz9ldz5sggqvc2ed72":[],"bc1qav4zrnx5g4s5h2z5hzr9hncg8qwt96ezltepmp":[],"bc1qcxryu22d3k66k4l55dzupvx45e88lmvp3rcww3":[],"bc1qd4us67486cn5qy44z6v6ervv5cuzrykq0vlcw2":[],"bc1qdd773rd9p8t3eylv2gvs2tmn2n79pwcfz65uyp":[],"bc1qdwafv8hy0cx9utkkj4hs6ntafm3x95m9zgpgvn":[],"bc1qehqt2um35x0c49snyugf94hvh7jz3vcjt0ya6m":[],"bc1qex23ueucc9hxyxgk3jg8ahw7cgw954legfnrxg":[],"bc1qf4tx5eesmrcy478gk384s2jv4lfh9dwt9jws0e":[],"bc1qh9l2au0f6m2fl3l3qa6perw5xnpvjul8lyylkt":[],"bc1qkmprcg50zcsdd0p3w70w2rxs5hwmwwn2xd0ls9":[],"bc1qkztpz05djsatmxxafgjqqldp0yfs8knr6um3e4":[],"bc1qrgj0zygryl6edylgm6gzx5j9rghdufrn5fp6hw":[],"bc1qscxh3na5uqapjm006xmg4s0geurq7nw427ywca":[],"bc1qunqye3f6cw88wqsjkks7amskder0rvufu49l6e":[],"bc1qv077qy5udlr3q8ammxq9ecq57vh9lxjnwh0vy9":[],"bc1qw9nqstryl3e0e49jg6670u6mu8507takz66qgv":[],"bc1qx4neqay68lmvgrav3yslzuempv9xn7aqdks5r6":[],"bc1qzhwpu84e5ajet4mxxr9ylc0fwass3q5k32uj5u":[]},"addresses":{"change":["bc1qdd773rd9p8t3eylv2gvs2tmn2n79pwcfz65uyp","bc1qv077qy5udlr3q8ammxq9ecq57vh9lxjnwh0vy9","bc1qx4neqay68lmvgrav3yslzuempv9xn7aqdks5r6","bc1qh9l2au0f6m2fl3l3qa6perw5xnpvjul8lyylkt","bc1qw9nqstryl3e0e49jg6670u6mu8507takz66qgv","bc1qaa2xnanrpmttw35gc4xqvz9ldz5sggqvc2ed72"],"receiving":["bc1qav4zrnx5g4s5h2z5hzr9hncg8qwt96ezltepmp","bc1qzhwpu84e5ajet4mxxr9ylc0fwass3q5k32uj5u","bc1qehqt2um35x0c49snyugf94hvh7jz3vcjt0ya6m","bc1q0k4hemnmw5czyq7yyka5mpc3hvz37lk0urhd34","bc1qf4tx5eesmrcy478gk384s2jv4lfh9dwt9jws0e","bc1q2xm8slpsqlt47u0j7segcsfmaq6s4s2pvx2526","bc1q5nd447vdf9gx0l8xmj500wr859pny29xurgcpn","bc1qex23ueucc9hxyxgk3jg8ahw7cgw954legfnrxg","bc1qscxh3na5uqapjm006xmg4s0geurq7nw427ywca","bc1qdwafv8hy0cx9utkkj4hs6ntafm3x95m9zgpgvn","bc1qkmprcg50zcsdd0p3w70w2rxs5hwmwwn2xd0ls9","bc1qunqye3f6cw88wqsjkks7amskder0rvufu49l6e","bc1q5l345sqf8fhlurn4hgu8dxu0w76j5tf3kc2f7h","bc1q4pqe6tcfyl8m35myj9trz7fn4w0kdpljnt3sxd","bc1qkztpz05djsatmxxafgjqqldp0yfs8knr6um3e4","bc1q4dhwcvnnm8a0umt4gvn2tatq66qf9d37rx5t8u","bc1q2tgeuhkr85pjkrys44zn2a7lfap0g8u7ny68p3","bc1qrgj0zygryl6edylgm6gzx5j9rghdufrn5fp6hw","bc1qd4us67486cn5qy44z6v6ervv5cuzrykq0vlcw2","bc1qcxryu22d3k66k4l55dzupvx45e88lmvp3rcww3"]},"keystore":{"cfg":{"mode":0,"pair":""},"derivation":"m/84'/0'/0'","hw_type":"ledger","label":"","type":"hardware","xpub":"zpub6qmVsnBYWipPzoeuZwtVeVnC42achPEZpGopT7jsop5WgDuFqKT3aS3EuAAQ6G76wbwtvDMdzffwxyEtwa6iafXSgjW2RjraiXfsgxQHnz8"},"seed_version":18,"spent_outpoints":{},"stored_height":646576,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[168,276,840,400]}'''
|
||||||
db = await self._upgrade_storage(wallet_str)
|
db = await self._upgrade_storage(wallet_str)
|
||||||
wallet = Wallet(db, None, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
ks = wallet.keystore
|
ks = wallet.keystore
|
||||||
# to simulate ks.opportunistically_fill_in_missing_info_from_device():
|
# to simulate ks.opportunistically_fill_in_missing_info_from_device():
|
||||||
ks._root_fingerprint = "deadbeef"
|
ks._root_fingerprint = "deadbeef"
|
||||||
@@ -281,7 +281,7 @@ class TestStorageUpgrade(WalletTestCase):
|
|||||||
# see #6401
|
# see #6401
|
||||||
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
||||||
db = await self._upgrade_storage(wallet_str)
|
db = await self._upgrade_storage(wallet_str)
|
||||||
wallet = Wallet(db, None, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
wallet.import_private_keys(
|
wallet.import_private_keys(
|
||||||
["p2wpkh:L1cgMEnShp73r9iCukoPE3MogLeueNYRD9JVsfT1zVHyPBR3KqBY"],
|
["p2wpkh:L1cgMEnShp73r9iCukoPE3MogLeueNYRD9JVsfT1zVHyPBR3KqBY"],
|
||||||
password=None
|
password=None
|
||||||
@@ -339,16 +339,16 @@ class TestStorageUpgrade(WalletTestCase):
|
|||||||
self.assertEqual(accounts, len(split_data))
|
self.assertEqual(accounts, len(split_data))
|
||||||
for item in split_data:
|
for item in split_data:
|
||||||
data = json.dumps(item)
|
data = json.dumps(item)
|
||||||
new_db = WalletDB(data, manual_upgrades=False)
|
new_db = WalletDB(data, storage=None, manual_upgrades=False)
|
||||||
await self._sanity_check_upgraded_db(new_db)
|
await self._sanity_check_upgraded_db(new_db)
|
||||||
|
|
||||||
async def _sanity_check_upgraded_db(self, db):
|
async def _sanity_check_upgraded_db(self, db):
|
||||||
self.assertFalse(db.requires_split())
|
self.assertFalse(db.requires_split())
|
||||||
self.assertFalse(db.requires_upgrade())
|
self.assertFalse(db.requires_upgrade())
|
||||||
wallet = Wallet(db, None, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
await wallet.stop()
|
await wallet.stop()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _load_db_from_json_string(*, wallet_json, manual_upgrades):
|
def _load_db_from_json_string(*, wallet_json, manual_upgrades):
|
||||||
db = WalletDB(wallet_json, manual_upgrades=manual_upgrades)
|
db = WalletDB(wallet_json, storage=None, manual_upgrades=manual_upgrades)
|
||||||
return db
|
return db
|
||||||
|
|||||||
@@ -62,14 +62,14 @@ class TestWalletStorage(WalletTestCase):
|
|||||||
contents = f.write(contents)
|
contents = f.write(contents)
|
||||||
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
db = WalletDB(storage.read(), manual_upgrades=True)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=True)
|
||||||
self.assertEqual("b", db.get("a"))
|
self.assertEqual("b", db.get("a"))
|
||||||
self.assertEqual("d", db.get("c"))
|
self.assertEqual("d", db.get("c"))
|
||||||
|
|
||||||
def test_write_dictionary_to_file(self):
|
def test_write_dictionary_to_file(self):
|
||||||
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
db = WalletDB('', manual_upgrades=True)
|
db = WalletDB('', storage=storage, manual_upgrades=True)
|
||||||
|
|
||||||
some_dict = {
|
some_dict = {
|
||||||
u"a": u"b",
|
u"a": u"b",
|
||||||
@@ -78,7 +78,7 @@ class TestWalletStorage(WalletTestCase):
|
|||||||
|
|
||||||
for key, value in some_dict.items():
|
for key, value in some_dict.items():
|
||||||
db.put(key, value)
|
db.put(key, value)
|
||||||
db.write(storage)
|
db.write()
|
||||||
|
|
||||||
with open(self.wallet_path, "r") as f:
|
with open(self.wallet_path, "r") as f:
|
||||||
contents = f.read()
|
contents = f.read()
|
||||||
@@ -112,7 +112,7 @@ class FakeWallet:
|
|||||||
def __init__(self, fiat_value):
|
def __init__(self, fiat_value):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.fiat_value = fiat_value
|
self.fiat_value = fiat_value
|
||||||
self.db = WalletDB("{}", manual_upgrades=True)
|
self.db = WalletDB("{}", storage=None, manual_upgrades=True)
|
||||||
self.adb = FakeADB()
|
self.adb = FakeADB()
|
||||||
self.db.transactions = self.db.verified_tx = {'abc':'Tx'}
|
self.db.transactions = self.db.verified_tx = {'abc':'Tx'}
|
||||||
|
|
||||||
@@ -258,9 +258,9 @@ class TestWalletPassword(WalletTestCase):
|
|||||||
|
|
||||||
async def test_update_password_of_imported_wallet(self):
|
async def test_update_password_of_imported_wallet(self):
|
||||||
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
||||||
db = WalletDB(wallet_str, manual_upgrades=False)
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
wallet = Wallet(db, storage, config=self.config)
|
db = WalletDB(wallet_str, storage=storage, manual_upgrades=False)
|
||||||
|
wallet = Wallet(db, config=self.config)
|
||||||
|
|
||||||
wallet.check_password(None)
|
wallet.check_password(None)
|
||||||
|
|
||||||
@@ -274,9 +274,9 @@ class TestWalletPassword(WalletTestCase):
|
|||||||
|
|
||||||
async def test_update_password_of_standard_wallet(self):
|
async def test_update_password_of_standard_wallet(self):
|
||||||
wallet_str = '''{"addr_history":{"12ECgkzK6gHouKAZ7QiooYBuk1CgJLJxes":[],"12iR43FPb5M7sw4Mcrr5y1nHKepg9EtZP1":[],"13HT1pfWctsSXVFzF76uYuVdQvcAQ2MAgB":[],"13kG9WH9JqS7hyCcVL1ssLdNv4aXocQY9c":[],"14Tf3qiiHJXStSU4KmienAhHfHq7FHpBpz":[],"14gmBxYV97mzYwWdJSJ3MTLbTHVegaKrcA":[],"15FGuHvRssu1r8fCw98vrbpfc3M4xs5FAV":[],"17oJzweA2gn6SDjsKgA9vUD5ocT1sSnr2Z":[],"18hNcSjZzRcRP6J2bfFRxp9UfpMoC4hGTv":[],"18n9PFxBjmKCGhd4PCDEEqYsi2CsnEfn2B":[],"19a98ZfEezDNbCwidVigV5PAJwrR2kw4Jz":[],"19z3j2ELqbg2pR87byCCt3BCyKR7rc3q8G":[],"1A3XSmvLQvePmvm7yctsGkBMX9ZKKXLrVq":[],"1CmhFe2BN1h9jheFpJf4v39XNPj8F9U6d":[],"1DuphhHUayKzbkdvjVjf5dtjn2ACkz4zEs":[],"1E4ygSNJpWL2uPXZHBptmU2LqwZTqb1Ado":[],"1GTDSjkVc9vaaBBBGNVqTANHJBcoT5VW9z":[],"1GWqgpThAuSq3tDg6uCoLQxPXQNnU8jZ52":[],"1GhmpwqSF5cqNgdr9oJMZx8dKxPRo4pYPP":[],"1J5TTUQKhwehEACw6Jjte1E22FVrbeDmpv":[],"1JWySzjzJhsETUUcqVZHuvQLA7pfFfmesb":[],"1KQHxcy3QUHAWMHKUtJjqD9cMKXcY2RTwZ":[],"1KoxZfc2KsgovjGDxwqanbFEA76uxgYH4G":[],"1KqVEPXdpbYvEbwsZcEKkrA4A2jsgj9hYN":[],"1N16yDSYe76c5A3CoVoWAKxHeAUc8Jhf9J":[],"1Pm8JBhzUJDqeQQKrmnop1Frr4phe1jbTt":[]},"addresses":{"change":["1GhmpwqSF5cqNgdr9oJMZx8dKxPRo4pYPP","1GTDSjkVc9vaaBBBGNVqTANHJBcoT5VW9z","15FGuHvRssu1r8fCw98vrbpfc3M4xs5FAV","1A3XSmvLQvePmvm7yctsGkBMX9ZKKXLrVq","19z3j2ELqbg2pR87byCCt3BCyKR7rc3q8G","1JWySzjzJhsETUUcqVZHuvQLA7pfFfmesb"],"receiving":["14gmBxYV97mzYwWdJSJ3MTLbTHVegaKrcA","13HT1pfWctsSXVFzF76uYuVdQvcAQ2MAgB","19a98ZfEezDNbCwidVigV5PAJwrR2kw4Jz","1J5TTUQKhwehEACw6Jjte1E22FVrbeDmpv","1Pm8JBhzUJDqeQQKrmnop1Frr4phe1jbTt","13kG9WH9JqS7hyCcVL1ssLdNv4aXocQY9c","1KQHxcy3QUHAWMHKUtJjqD9cMKXcY2RTwZ","12ECgkzK6gHouKAZ7QiooYBuk1CgJLJxes","12iR43FPb5M7sw4Mcrr5y1nHKepg9EtZP1","14Tf3qiiHJXStSU4KmienAhHfHq7FHpBpz","1KqVEPXdpbYvEbwsZcEKkrA4A2jsgj9hYN","17oJzweA2gn6SDjsKgA9vUD5ocT1sSnr2Z","1E4ygSNJpWL2uPXZHBptmU2LqwZTqb1Ado","18hNcSjZzRcRP6J2bfFRxp9UfpMoC4hGTv","1KoxZfc2KsgovjGDxwqanbFEA76uxgYH4G","18n9PFxBjmKCGhd4PCDEEqYsi2CsnEfn2B","1CmhFe2BN1h9jheFpJf4v39XNPj8F9U6d","1DuphhHUayKzbkdvjVjf5dtjn2ACkz4zEs","1GWqgpThAuSq3tDg6uCoLQxPXQNnU8jZ52","1N16yDSYe76c5A3CoVoWAKxHeAUc8Jhf9J"]},"keystore":{"seed":"cereal wise two govern top pet frog nut rule sketch bundle logic","type":"bip32","xprv":"xprv9s21ZrQH143K29XjRjUs6MnDB9wXjXbJP2kG1fnRk8zjdDYWqVkQYUqaDtgZp5zPSrH5PZQJs8sU25HrUgT1WdgsPU8GbifKurtMYg37d4v","xpub":"xpub661MyMwAqRbcEdcCXm1sTViwjBn28zK9kFfrp4C3JUXiW1sfP34f6HA45B9yr7EH5XGzWuTfMTdqpt9XPrVQVUdgiYb5NW9m8ij1FSZgGBF"},"pruned_txo":{},"seed_type":"standard","seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[619,310,840,405]}'''
|
wallet_str = '''{"addr_history":{"12ECgkzK6gHouKAZ7QiooYBuk1CgJLJxes":[],"12iR43FPb5M7sw4Mcrr5y1nHKepg9EtZP1":[],"13HT1pfWctsSXVFzF76uYuVdQvcAQ2MAgB":[],"13kG9WH9JqS7hyCcVL1ssLdNv4aXocQY9c":[],"14Tf3qiiHJXStSU4KmienAhHfHq7FHpBpz":[],"14gmBxYV97mzYwWdJSJ3MTLbTHVegaKrcA":[],"15FGuHvRssu1r8fCw98vrbpfc3M4xs5FAV":[],"17oJzweA2gn6SDjsKgA9vUD5ocT1sSnr2Z":[],"18hNcSjZzRcRP6J2bfFRxp9UfpMoC4hGTv":[],"18n9PFxBjmKCGhd4PCDEEqYsi2CsnEfn2B":[],"19a98ZfEezDNbCwidVigV5PAJwrR2kw4Jz":[],"19z3j2ELqbg2pR87byCCt3BCyKR7rc3q8G":[],"1A3XSmvLQvePmvm7yctsGkBMX9ZKKXLrVq":[],"1CmhFe2BN1h9jheFpJf4v39XNPj8F9U6d":[],"1DuphhHUayKzbkdvjVjf5dtjn2ACkz4zEs":[],"1E4ygSNJpWL2uPXZHBptmU2LqwZTqb1Ado":[],"1GTDSjkVc9vaaBBBGNVqTANHJBcoT5VW9z":[],"1GWqgpThAuSq3tDg6uCoLQxPXQNnU8jZ52":[],"1GhmpwqSF5cqNgdr9oJMZx8dKxPRo4pYPP":[],"1J5TTUQKhwehEACw6Jjte1E22FVrbeDmpv":[],"1JWySzjzJhsETUUcqVZHuvQLA7pfFfmesb":[],"1KQHxcy3QUHAWMHKUtJjqD9cMKXcY2RTwZ":[],"1KoxZfc2KsgovjGDxwqanbFEA76uxgYH4G":[],"1KqVEPXdpbYvEbwsZcEKkrA4A2jsgj9hYN":[],"1N16yDSYe76c5A3CoVoWAKxHeAUc8Jhf9J":[],"1Pm8JBhzUJDqeQQKrmnop1Frr4phe1jbTt":[]},"addresses":{"change":["1GhmpwqSF5cqNgdr9oJMZx8dKxPRo4pYPP","1GTDSjkVc9vaaBBBGNVqTANHJBcoT5VW9z","15FGuHvRssu1r8fCw98vrbpfc3M4xs5FAV","1A3XSmvLQvePmvm7yctsGkBMX9ZKKXLrVq","19z3j2ELqbg2pR87byCCt3BCyKR7rc3q8G","1JWySzjzJhsETUUcqVZHuvQLA7pfFfmesb"],"receiving":["14gmBxYV97mzYwWdJSJ3MTLbTHVegaKrcA","13HT1pfWctsSXVFzF76uYuVdQvcAQ2MAgB","19a98ZfEezDNbCwidVigV5PAJwrR2kw4Jz","1J5TTUQKhwehEACw6Jjte1E22FVrbeDmpv","1Pm8JBhzUJDqeQQKrmnop1Frr4phe1jbTt","13kG9WH9JqS7hyCcVL1ssLdNv4aXocQY9c","1KQHxcy3QUHAWMHKUtJjqD9cMKXcY2RTwZ","12ECgkzK6gHouKAZ7QiooYBuk1CgJLJxes","12iR43FPb5M7sw4Mcrr5y1nHKepg9EtZP1","14Tf3qiiHJXStSU4KmienAhHfHq7FHpBpz","1KqVEPXdpbYvEbwsZcEKkrA4A2jsgj9hYN","17oJzweA2gn6SDjsKgA9vUD5ocT1sSnr2Z","1E4ygSNJpWL2uPXZHBptmU2LqwZTqb1Ado","18hNcSjZzRcRP6J2bfFRxp9UfpMoC4hGTv","1KoxZfc2KsgovjGDxwqanbFEA76uxgYH4G","18n9PFxBjmKCGhd4PCDEEqYsi2CsnEfn2B","1CmhFe2BN1h9jheFpJf4v39XNPj8F9U6d","1DuphhHUayKzbkdvjVjf5dtjn2ACkz4zEs","1GWqgpThAuSq3tDg6uCoLQxPXQNnU8jZ52","1N16yDSYe76c5A3CoVoWAKxHeAUc8Jhf9J"]},"keystore":{"seed":"cereal wise two govern top pet frog nut rule sketch bundle logic","type":"bip32","xprv":"xprv9s21ZrQH143K29XjRjUs6MnDB9wXjXbJP2kG1fnRk8zjdDYWqVkQYUqaDtgZp5zPSrH5PZQJs8sU25HrUgT1WdgsPU8GbifKurtMYg37d4v","xpub":"xpub661MyMwAqRbcEdcCXm1sTViwjBn28zK9kFfrp4C3JUXiW1sfP34f6HA45B9yr7EH5XGzWuTfMTdqpt9XPrVQVUdgiYb5NW9m8ij1FSZgGBF"},"pruned_txo":{},"seed_type":"standard","seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[619,310,840,405]}'''
|
||||||
db = WalletDB(wallet_str, manual_upgrades=False)
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
wallet = Wallet(db, storage, config=self.config)
|
db = WalletDB(wallet_str, storage=storage, manual_upgrades=False)
|
||||||
|
wallet = Wallet(db, config=self.config)
|
||||||
|
|
||||||
wallet.check_password(None)
|
wallet.check_password(None)
|
||||||
|
|
||||||
@@ -289,16 +289,16 @@ class TestWalletPassword(WalletTestCase):
|
|||||||
|
|
||||||
async def test_update_password_with_app_restarts(self):
|
async def test_update_password_with_app_restarts(self):
|
||||||
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
wallet_str = '{"addr_history":{"1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr":[],"15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA":[],"1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6":[]},"addresses":{"change":[],"receiving":["1364Js2VG66BwRdkaoxAaFtdPb1eQgn8Dr","1Exet2BhHsFxKTwhnfdsBMkPYLGvobxuW6","15CyDgLffJsJgQrhcyooFH4gnVDG82pUrA"]},"keystore":{"keypairs":{"0344b1588589958b0bcab03435061539e9bcf54677c104904044e4f8901f4ebdf5":"L2sED74axVXC4H8szBJ4rQJrkfem7UMc6usLCPUoEWxDCFGUaGUM","0389508c13999d08ffae0f434a085f4185922d64765c0bff2f66e36ad7f745cc5f":"L3Gi6EQLvYw8gEEUckmqawkevfj9s8hxoQDFveQJGZHTfyWnbk1U","04575f52b82f159fa649d2a4c353eb7435f30206f0a6cb9674fbd659f45082c37d559ffd19bea9c0d3b7dcc07a7b79f4cffb76026d5d4dff35341efe99056e22d2":"5JyVyXU1LiRXATvRTQvR9Kp8Rx1X84j2x49iGkjSsXipydtByUq"},"type":"imported"},"pruned_txo":{},"seed_version":13,"stored_height":-1,"transactions":{},"tx_fees":{},"txi":{},"txo":{},"use_encryption":false,"verified_tx3":{},"wallet_type":"standard","winpos-qt":[100,100,840,405]}'
|
||||||
db = WalletDB(wallet_str, manual_upgrades=False)
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
wallet = Wallet(db, storage, config=self.config)
|
db = WalletDB(wallet_str, storage=storage, manual_upgrades=False)
|
||||||
|
wallet = Wallet(db, config=self.config)
|
||||||
await wallet.stop()
|
await wallet.stop()
|
||||||
|
|
||||||
storage = WalletStorage(self.wallet_path)
|
storage = WalletStorage(self.wallet_path)
|
||||||
# if storage.is_encrypted():
|
# if storage.is_encrypted():
|
||||||
# storage.decrypt(password)
|
# storage.decrypt(password)
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
wallet = Wallet(db, storage, config=self.config)
|
wallet = Wallet(db, config=self.config)
|
||||||
|
|
||||||
wallet.check_password(None)
|
wallet.check_password(None)
|
||||||
|
|
||||||
|
|||||||
@@ -51,33 +51,33 @@ class WalletIntegrityHelper:
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_standard_wallet(cls, ks, *, config: SimpleConfig, gap_limit=None):
|
def create_standard_wallet(cls, ks, *, config: SimpleConfig, gap_limit=None):
|
||||||
db = storage.WalletDB('', manual_upgrades=False)
|
db = storage.WalletDB('', storage=None, manual_upgrades=False)
|
||||||
db.put('keystore', ks.dump())
|
db.put('keystore', ks.dump())
|
||||||
db.put('gap_limit', gap_limit or cls.gap_limit)
|
db.put('gap_limit', gap_limit or cls.gap_limit)
|
||||||
w = Standard_Wallet(db, None, config=config)
|
w = Standard_Wallet(db, config=config)
|
||||||
w.synchronize()
|
w.synchronize()
|
||||||
return w
|
return w
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_imported_wallet(cls, *, config: SimpleConfig, privkeys: bool):
|
def create_imported_wallet(cls, *, config: SimpleConfig, privkeys: bool):
|
||||||
db = storage.WalletDB('', manual_upgrades=False)
|
db = storage.WalletDB('', storage=None, manual_upgrades=False)
|
||||||
if privkeys:
|
if privkeys:
|
||||||
k = keystore.Imported_KeyStore({})
|
k = keystore.Imported_KeyStore({})
|
||||||
db.put('keystore', k.dump())
|
db.put('keystore', k.dump())
|
||||||
w = Imported_Wallet(db, None, config=config)
|
w = Imported_Wallet(db, config=config)
|
||||||
return w
|
return w
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, *,
|
def create_multisig_wallet(cls, keystores: Sequence, multisig_type: str, *,
|
||||||
config: SimpleConfig, gap_limit=None):
|
config: SimpleConfig, gap_limit=None):
|
||||||
"""Creates a multisig wallet."""
|
"""Creates a multisig wallet."""
|
||||||
db = storage.WalletDB('', manual_upgrades=True)
|
db = storage.WalletDB('', storage=None, manual_upgrades=True)
|
||||||
for i, ks in enumerate(keystores):
|
for i, ks in enumerate(keystores):
|
||||||
cosigner_index = i + 1
|
cosigner_index = i + 1
|
||||||
db.put('x%d/' % cosigner_index, ks.dump())
|
db.put('x%d/' % cosigner_index, ks.dump())
|
||||||
db.put('wallet_type', multisig_type)
|
db.put('wallet_type', multisig_type)
|
||||||
db.put('gap_limit', gap_limit or cls.gap_limit)
|
db.put('gap_limit', gap_limit or cls.gap_limit)
|
||||||
w = Multisig_Wallet(db, None, config=config)
|
w = Multisig_Wallet(db, config=config)
|
||||||
w.synchronize()
|
w.synchronize()
|
||||||
return w
|
return w
|
||||||
|
|
||||||
|
|||||||
+28
-29
@@ -306,7 +306,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
lnworker: Optional['LNWallet']
|
lnworker: Optional['LNWallet']
|
||||||
network: Optional['Network']
|
network: Optional['Network']
|
||||||
|
|
||||||
def __init__(self, db: WalletDB, storage: Optional[WalletStorage], *, config: SimpleConfig):
|
def __init__(self, db: WalletDB, *, config: SimpleConfig):
|
||||||
|
|
||||||
if not db.is_ready_to_be_used_by_wallet():
|
if not db.is_ready_to_be_used_by_wallet():
|
||||||
raise Exception("storage not ready to be used by Abstract_Wallet")
|
raise Exception("storage not ready to be used by Abstract_Wallet")
|
||||||
@@ -314,7 +314,7 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
self.config = config
|
self.config = config
|
||||||
assert self.config is not None, "config must not be None"
|
assert self.config is not None, "config must not be None"
|
||||||
self.db = db
|
self.db = db
|
||||||
self.storage = storage
|
self.storage = db.storage
|
||||||
# load addresses needs to be called before constructor for sanity checks
|
# load addresses needs to be called before constructor for sanity checks
|
||||||
db.load_addresses(self.wallet_type)
|
db.load_addresses(self.wallet_type)
|
||||||
self.keystore = None # type: Optional[KeyStore] # will be set by load_keystore
|
self.keystore = None # type: Optional[KeyStore] # will be set by load_keystore
|
||||||
@@ -393,25 +393,24 @@ class Abstract_Wallet(ABC, Logger, EventListener):
|
|||||||
await run_in_thread(self.synchronize)
|
await run_in_thread(self.synchronize)
|
||||||
|
|
||||||
def save_db(self):
|
def save_db(self):
|
||||||
if self.storage:
|
if self.db.storage:
|
||||||
self.db.write(self.storage)
|
self.db.write()
|
||||||
|
|
||||||
def save_backup(self, backup_dir):
|
def save_backup(self, backup_dir):
|
||||||
new_db = WalletDB(self.db.dump(), manual_upgrades=False)
|
new_path = os.path.join(backup_dir, self.basename() + '.backup')
|
||||||
|
new_storage = WalletStorage(new_path)
|
||||||
|
new_storage._encryption_version = self.storage._encryption_version
|
||||||
|
new_storage.pubkey = self.storage.pubkey
|
||||||
|
|
||||||
|
new_db = WalletDB(self.db.dump(), storage=new_storage, manual_upgrades=False)
|
||||||
if self.lnworker:
|
if self.lnworker:
|
||||||
channel_backups = new_db.get_dict('imported_channel_backups')
|
channel_backups = new_db.get_dict('imported_channel_backups')
|
||||||
for chan_id, chan in self.lnworker.channels.items():
|
for chan_id, chan in self.lnworker.channels.items():
|
||||||
channel_backups[chan_id.hex()] = self.lnworker.create_channel_backup(chan_id)
|
channel_backups[chan_id.hex()] = self.lnworker.create_channel_backup(chan_id)
|
||||||
new_db.put('channels', None)
|
new_db.put('channels', None)
|
||||||
new_db.put('lightning_privkey2', None)
|
new_db.put('lightning_privkey2', None)
|
||||||
|
|
||||||
new_path = os.path.join(backup_dir, self.basename() + '.backup')
|
|
||||||
new_storage = WalletStorage(new_path)
|
|
||||||
new_storage._encryption_version = self.storage._encryption_version
|
|
||||||
new_storage.pubkey = self.storage.pubkey
|
|
||||||
new_db.set_modified(True)
|
new_db.set_modified(True)
|
||||||
new_db.write(new_storage)
|
new_db.write()
|
||||||
return new_path
|
return new_path
|
||||||
|
|
||||||
def has_lightning(self) -> bool:
|
def has_lightning(self) -> bool:
|
||||||
@@ -3059,8 +3058,8 @@ class Imported_Wallet(Simple_Wallet):
|
|||||||
wallet_type = 'imported'
|
wallet_type = 'imported'
|
||||||
txin_type = 'address'
|
txin_type = 'address'
|
||||||
|
|
||||||
def __init__(self, db, storage, *, config):
|
def __init__(self, db, *, config):
|
||||||
Abstract_Wallet.__init__(self, db, storage, config=config)
|
Abstract_Wallet.__init__(self, db, config=config)
|
||||||
self.use_change = db.get('use_change', False)
|
self.use_change = db.get('use_change', False)
|
||||||
|
|
||||||
def is_watching_only(self):
|
def is_watching_only(self):
|
||||||
@@ -3277,9 +3276,9 @@ class Imported_Wallet(Simple_Wallet):
|
|||||||
|
|
||||||
class Deterministic_Wallet(Abstract_Wallet):
|
class Deterministic_Wallet(Abstract_Wallet):
|
||||||
|
|
||||||
def __init__(self, db, storage, *, config):
|
def __init__(self, db, *, config):
|
||||||
self._ephemeral_addr_to_addr_index = {} # type: Dict[str, Sequence[int]]
|
self._ephemeral_addr_to_addr_index = {} # type: Dict[str, Sequence[int]]
|
||||||
Abstract_Wallet.__init__(self, db, storage, config=config)
|
Abstract_Wallet.__init__(self, db, config=config)
|
||||||
self.gap_limit = db.get('gap_limit', 20)
|
self.gap_limit = db.get('gap_limit', 20)
|
||||||
# generate addresses now. note that without libsecp this might block
|
# generate addresses now. note that without libsecp this might block
|
||||||
# for a few seconds!
|
# for a few seconds!
|
||||||
@@ -3492,8 +3491,8 @@ class Simple_Deterministic_Wallet(Simple_Wallet, Deterministic_Wallet):
|
|||||||
|
|
||||||
""" Deterministic Wallet with a single pubkey per address """
|
""" Deterministic Wallet with a single pubkey per address """
|
||||||
|
|
||||||
def __init__(self, db, storage, *, config):
|
def __init__(self, db, *, config):
|
||||||
Deterministic_Wallet.__init__(self, db, storage, config=config)
|
Deterministic_Wallet.__init__(self, db, config=config)
|
||||||
|
|
||||||
def get_public_key(self, address):
|
def get_public_key(self, address):
|
||||||
sequence = self.get_address_index(address)
|
sequence = self.get_address_index(address)
|
||||||
@@ -3530,10 +3529,10 @@ class Standard_Wallet(Simple_Deterministic_Wallet):
|
|||||||
class Multisig_Wallet(Deterministic_Wallet):
|
class Multisig_Wallet(Deterministic_Wallet):
|
||||||
# generic m of n
|
# generic m of n
|
||||||
|
|
||||||
def __init__(self, db, storage, *, config):
|
def __init__(self, db, *, config):
|
||||||
self.wallet_type = db.get('wallet_type')
|
self.wallet_type = db.get('wallet_type')
|
||||||
self.m, self.n = multisig_type(self.wallet_type)
|
self.m, self.n = multisig_type(self.wallet_type)
|
||||||
Deterministic_Wallet.__init__(self, db, storage, config=config)
|
Deterministic_Wallet.__init__(self, db, config=config)
|
||||||
# sanity checks
|
# sanity checks
|
||||||
for ks in self.get_keystores():
|
for ks in self.get_keystores():
|
||||||
if not isinstance(ks, keystore.Xpub):
|
if not isinstance(ks, keystore.Xpub):
|
||||||
@@ -3630,10 +3629,10 @@ class Wallet(object):
|
|||||||
This class is actually a factory that will return a wallet of the correct
|
This class is actually a factory that will return a wallet of the correct
|
||||||
type when passed a WalletStorage instance."""
|
type when passed a WalletStorage instance."""
|
||||||
|
|
||||||
def __new__(self, db: 'WalletDB', storage: Optional[WalletStorage], *, config: SimpleConfig):
|
def __new__(self, db: 'WalletDB', *, config: SimpleConfig):
|
||||||
wallet_type = db.get('wallet_type')
|
wallet_type = db.get('wallet_type')
|
||||||
WalletClass = Wallet.wallet_class(wallet_type)
|
WalletClass = Wallet.wallet_class(wallet_type)
|
||||||
wallet = WalletClass(db, storage, config=config)
|
wallet = WalletClass(db, config=config)
|
||||||
return wallet
|
return wallet
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -3651,7 +3650,7 @@ def create_new_wallet(*, path, config: SimpleConfig, passphrase=None, password=N
|
|||||||
storage = WalletStorage(path)
|
storage = WalletStorage(path)
|
||||||
if storage.file_exists():
|
if storage.file_exists():
|
||||||
raise Exception("Remove the existing wallet first!")
|
raise Exception("Remove the existing wallet first!")
|
||||||
db = WalletDB('', manual_upgrades=False)
|
db = WalletDB('', storage=storage, manual_upgrades=False)
|
||||||
|
|
||||||
seed = Mnemonic('en').make_seed(seed_type=seed_type)
|
seed = Mnemonic('en').make_seed(seed_type=seed_type)
|
||||||
k = keystore.from_seed(seed, passphrase)
|
k = keystore.from_seed(seed, passphrase)
|
||||||
@@ -3661,7 +3660,7 @@ def create_new_wallet(*, path, config: SimpleConfig, passphrase=None, password=N
|
|||||||
db.put('lightning_xprv', k.get_lightning_xprv(None))
|
db.put('lightning_xprv', k.get_lightning_xprv(None))
|
||||||
if gap_limit is not None:
|
if gap_limit is not None:
|
||||||
db.put('gap_limit', gap_limit)
|
db.put('gap_limit', gap_limit)
|
||||||
wallet = Wallet(db, storage, config=config)
|
wallet = Wallet(db, config=config)
|
||||||
wallet.update_password(old_pw=None, new_pw=password, encrypt_storage=encrypt_file)
|
wallet.update_password(old_pw=None, new_pw=password, encrypt_storage=encrypt_file)
|
||||||
wallet.synchronize()
|
wallet.synchronize()
|
||||||
msg = "Please keep your seed in a safe place; if you lose it, you will not be able to restore your wallet."
|
msg = "Please keep your seed in a safe place; if you lose it, you will not be able to restore your wallet."
|
||||||
@@ -3690,10 +3689,10 @@ def restore_wallet_from_text(
|
|||||||
raise Exception("Remove the existing wallet first!")
|
raise Exception("Remove the existing wallet first!")
|
||||||
if encrypt_file is None:
|
if encrypt_file is None:
|
||||||
encrypt_file = True
|
encrypt_file = True
|
||||||
db = WalletDB('', manual_upgrades=False)
|
db = WalletDB('', storage=storage, manual_upgrades=False)
|
||||||
text = text.strip()
|
text = text.strip()
|
||||||
if keystore.is_address_list(text):
|
if keystore.is_address_list(text):
|
||||||
wallet = Imported_Wallet(db, storage, config=config)
|
wallet = Imported_Wallet(db, config=config)
|
||||||
addresses = text.split()
|
addresses = text.split()
|
||||||
good_inputs, bad_inputs = wallet.import_addresses(addresses, write_to_disk=False)
|
good_inputs, bad_inputs = wallet.import_addresses(addresses, write_to_disk=False)
|
||||||
# FIXME tell user about bad_inputs
|
# FIXME tell user about bad_inputs
|
||||||
@@ -3702,7 +3701,7 @@ def restore_wallet_from_text(
|
|||||||
elif keystore.is_private_key_list(text, allow_spaces_inside_key=False):
|
elif keystore.is_private_key_list(text, allow_spaces_inside_key=False):
|
||||||
k = keystore.Imported_KeyStore({})
|
k = keystore.Imported_KeyStore({})
|
||||||
db.put('keystore', k.dump())
|
db.put('keystore', k.dump())
|
||||||
wallet = Imported_Wallet(db, storage, config=config)
|
wallet = Imported_Wallet(db, config=config)
|
||||||
keys = keystore.get_private_keys(text, allow_spaces_inside_key=False)
|
keys = keystore.get_private_keys(text, allow_spaces_inside_key=False)
|
||||||
good_inputs, bad_inputs = wallet.import_private_keys(keys, None, write_to_disk=False)
|
good_inputs, bad_inputs = wallet.import_private_keys(keys, None, write_to_disk=False)
|
||||||
# FIXME tell user about bad_inputs
|
# FIXME tell user about bad_inputs
|
||||||
@@ -3721,9 +3720,9 @@ def restore_wallet_from_text(
|
|||||||
db.put('wallet_type', 'standard')
|
db.put('wallet_type', 'standard')
|
||||||
if gap_limit is not None:
|
if gap_limit is not None:
|
||||||
db.put('gap_limit', gap_limit)
|
db.put('gap_limit', gap_limit)
|
||||||
wallet = Wallet(db, storage, config=config)
|
wallet = Wallet(db, config=config)
|
||||||
if storage:
|
if db.storage:
|
||||||
assert not storage.file_exists(), "file was created too soon! plaintext keys might have been written to disk"
|
assert not db.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.update_password(old_pw=None, new_pw=password, encrypt_storage=encrypt_file)
|
||||||
wallet.synchronize()
|
wallet.synchronize()
|
||||||
msg = ("This wallet was restored offline. It may contain more addresses than displayed. "
|
msg = ("This wallet was restored offline. It may contain more addresses than displayed. "
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ for key in ['locked_in', 'fails', 'settles']:
|
|||||||
|
|
||||||
class WalletDB(JsonDB):
|
class WalletDB(JsonDB):
|
||||||
|
|
||||||
def __init__(self, data, *, manual_upgrades: bool):
|
def __init__(self, data, *, storage=None, manual_upgrades: bool):
|
||||||
JsonDB.__init__(self, data)
|
JsonDB.__init__(self, data, storage)
|
||||||
if not data:
|
if not data:
|
||||||
# create new DB
|
# create new DB
|
||||||
self.put('seed_version', FINAL_SEED_VERSION)
|
self.put('seed_version', FINAL_SEED_VERSION)
|
||||||
@@ -1599,10 +1599,10 @@ class WalletDB(JsonDB):
|
|||||||
for data in result:
|
for data in result:
|
||||||
path = root_path + '.' + data['suffix']
|
path = root_path + '.' + data['suffix']
|
||||||
storage = WalletStorage(path)
|
storage = WalletStorage(path)
|
||||||
db = WalletDB(json.dumps(data), manual_upgrades=False)
|
db = WalletDB(json.dumps(data), storage=storage, manual_upgrades=False)
|
||||||
db._called_after_upgrade_tasks = False
|
db._called_after_upgrade_tasks = False
|
||||||
db.upgrade()
|
db.upgrade()
|
||||||
db.write(storage)
|
db.write()
|
||||||
out.append(path)
|
out.append(path)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -425,7 +425,7 @@ class NewWalletWizard(AbstractWizard):
|
|||||||
k.update_password(None, data['password'])
|
k.update_password(None, data['password'])
|
||||||
storage.set_password(data['password'], enc_version=StorageEncryptionVersion.USER_PASSWORD)
|
storage.set_password(data['password'], enc_version=StorageEncryptionVersion.USER_PASSWORD)
|
||||||
|
|
||||||
db = WalletDB('', manual_upgrades=False)
|
db = WalletDB('', storage=storage, manual_upgrades=False)
|
||||||
db.set_keystore_encryption(bool(data['password']) and data['encrypt'])
|
db.set_keystore_encryption(bool(data['password']) and data['encrypt'])
|
||||||
|
|
||||||
db.put('wallet_type', data['wallet_type'])
|
db.put('wallet_type', data['wallet_type'])
|
||||||
|
|||||||
+2
-2
@@ -226,8 +226,8 @@ async def run_offline_command(config, config_options, plugins: 'Plugins'):
|
|||||||
password = get_password_for_hw_device_encrypted_storage(plugins)
|
password = get_password_for_hw_device_encrypted_storage(plugins)
|
||||||
config_options['password'] = password
|
config_options['password'] = password
|
||||||
storage.decrypt(password)
|
storage.decrypt(password)
|
||||||
db = WalletDB(storage.read(), manual_upgrades=False)
|
db = WalletDB(storage.read(), storage=storage, manual_upgrades=False)
|
||||||
wallet = Wallet(db, storage, config=config)
|
wallet = Wallet(db, config=config)
|
||||||
config_options['wallet'] = wallet
|
config_options['wallet'] = wallet
|
||||||
else:
|
else:
|
||||||
wallet = None
|
wallet = None
|
||||||
|
|||||||
Reference in New Issue
Block a user