diff --git a/torba/baseaccount.py b/torba/baseaccount.py index 406a52902..ce32e7df5 100644 --- a/torba/baseaccount.py +++ b/torba/baseaccount.py @@ -234,7 +234,10 @@ class BaseAccount: @classmethod def from_dict(cls, ledger: 'baseledger.BaseLedger', d: dict): - if not d['encrypted'] and d['private_key']: + if not d['private_key'] and not d['public_key'] and d['seed']: + private_key = cls.get_private_key_from_seed(ledger, d['seed'], '') + public_key = private_key.public_key + elif not d['encrypted'] and d['private_key']: private_key = from_extended_key_string(ledger, d['private_key']) public_key = private_key.public_key else: @@ -316,3 +319,41 @@ class BaseAccount: def get_unspent_outputs(self, **constraints): return self.ledger.db.get_utxos_for_account(self, **constraints) + + @defer.inlineCallbacks + def fund(self, to_account, amount=None, everything=False, + outputs=1, broadcast=False, **constraints): + assert self.ledger == to_account.ledger, 'Can only transfer between accounts of the same ledger.' + tx_class = self.ledger.transaction_class + if everything: + utxos = yield self.get_unspent_outputs(**constraints) + yield self.ledger.reserve_outputs(utxos) + tx = yield tx_class.create( + inputs=[tx_class.input_class.spend(txo) for txo in utxos], + outputs=[], + funding_accounts=[self], + change_account=to_account + ) + elif amount > 0: + to_address = yield to_account.change.get_or_create_usable_address() + to_hash160 = to_account.ledger.address_to_hash160(to_address) + tx = yield tx_class.create( + inputs=[], + outputs=[ + tx_class.output_class.pay_pubkey_hash(amount//outputs, to_hash160) + for _ in range(outputs) + ], + funding_accounts=[self], + change_account=self + ) + else: + raise ValueError('An amount is required.') + + if broadcast: + yield self.ledger.broadcast(tx) + else: + yield self.ledger.release_outputs( + [txi.txo_ref.txo for txi in tx.inputs] + ) + + defer.returnValue(tx) diff --git a/torba/basemanager.py b/torba/basemanager.py index 7c18a16ef..7ad728066 100644 --- a/torba/basemanager.py +++ b/torba/basemanager.py @@ -1,3 +1,4 @@ +import logging from typing import Type, MutableSequence, MutableMapping from twisted.internet import defer @@ -5,6 +6,8 @@ from torba.baseledger import BaseLedger, LedgerRegistry from torba.wallet import Wallet, WalletStorage from torba.constants import COIN +log = logging.getLogger(__name__) + class BaseWalletManager: @@ -22,6 +25,11 @@ class BaseWalletManager: for wallet_path in config.get('wallets', []): wallet_storage = WalletStorage(wallet_path) wallet = Wallet.from_storage(wallet_storage, manager) + if wallet.default_account is None: + ledger = manager.get_or_create_ledger('lbc_mainnet') + log.info('Wallet at %s is empty, generating a default account.', wallet_path) + wallet.generate_account(ledger) + wallet.save() manager.wallets.append(wallet) return manager diff --git a/torba/basetransaction.py b/torba/basetransaction.py index 5b5aadde6..7302cb3d9 100644 --- a/torba/basetransaction.py +++ b/torba/basetransaction.py @@ -197,6 +197,11 @@ class BaseOutput(InputOutput): def id(self): return self.ref.id + def get_address(self, ledger): + return ledger.hash160_to_address( + self.script.values['pubkey_hash'] + ) + def get_estimator(self, ledger): return self.estimator_class(ledger, self)