create default account when missing and new new account.fund() to support transfer of funds between accounts

This commit is contained in:
Lex Berezhny 2018-08-06 00:15:19 -04:00
parent f5515e5e77
commit 75ddf209e2
3 changed files with 55 additions and 1 deletions

View file

@ -234,7 +234,10 @@ class BaseAccount:
@classmethod @classmethod
def from_dict(cls, ledger: 'baseledger.BaseLedger', d: dict): 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']) private_key = from_extended_key_string(ledger, d['private_key'])
public_key = private_key.public_key public_key = private_key.public_key
else: else:
@ -316,3 +319,41 @@ class BaseAccount:
def get_unspent_outputs(self, **constraints): def get_unspent_outputs(self, **constraints):
return self.ledger.db.get_utxos_for_account(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)

View file

@ -1,3 +1,4 @@
import logging
from typing import Type, MutableSequence, MutableMapping from typing import Type, MutableSequence, MutableMapping
from twisted.internet import defer from twisted.internet import defer
@ -5,6 +6,8 @@ from torba.baseledger import BaseLedger, LedgerRegistry
from torba.wallet import Wallet, WalletStorage from torba.wallet import Wallet, WalletStorage
from torba.constants import COIN from torba.constants import COIN
log = logging.getLogger(__name__)
class BaseWalletManager: class BaseWalletManager:
@ -22,6 +25,11 @@ class BaseWalletManager:
for wallet_path in config.get('wallets', []): for wallet_path in config.get('wallets', []):
wallet_storage = WalletStorage(wallet_path) wallet_storage = WalletStorage(wallet_path)
wallet = Wallet.from_storage(wallet_storage, manager) 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) manager.wallets.append(wallet)
return manager return manager

View file

@ -197,6 +197,11 @@ class BaseOutput(InputOutput):
def id(self): def id(self):
return self.ref.id return self.ref.id
def get_address(self, ledger):
return ledger.hash160_to_address(
self.script.values['pubkey_hash']
)
def get_estimator(self, ledger): def get_estimator(self, ledger):
return self.estimator_class(ledger, self) return self.estimator_class(ledger, self)