Move create_transaction logic from commands to wallet
This commit is contained in:
@@ -584,81 +584,57 @@ class Commands:
|
||||
message = util.to_bytes(message)
|
||||
return ecc.verify_message_with_address(address, sig, message)
|
||||
|
||||
def _mktx(self, wallet: Abstract_Wallet, outputs, *, fee=None, feerate=None, change_addr=None, domain_addr=None, domain_coins=None,
|
||||
nocheck=False, unsigned=False, rbf=None, password=None, locktime=None):
|
||||
if fee is not None and feerate is not None:
|
||||
raise Exception("Cannot specify both 'fee' and 'feerate' at the same time!")
|
||||
self.nocheck = nocheck
|
||||
change_addr = self._resolver(change_addr, wallet)
|
||||
domain_addr = None if domain_addr is None else map(self._resolver, domain_addr, repeat(wallet))
|
||||
final_outputs = []
|
||||
for address, amount in outputs:
|
||||
address = self._resolver(address, wallet)
|
||||
amount = satoshis(amount)
|
||||
final_outputs.append(PartialTxOutput.from_address_and_value(address, amount))
|
||||
|
||||
coins = wallet.get_spendable_coins(domain_addr)
|
||||
if domain_coins is not None:
|
||||
coins = [coin for coin in coins if (coin.prevout.to_str() in domain_coins)]
|
||||
if feerate is not None:
|
||||
fee_per_kb = 1000 * Decimal(feerate)
|
||||
fee_estimator = partial(SimpleConfig.estimate_fee_for_feerate, fee_per_kb)
|
||||
else:
|
||||
fee_estimator = fee
|
||||
tx = wallet.make_unsigned_transaction(coins=coins,
|
||||
outputs=final_outputs,
|
||||
fee=fee_estimator,
|
||||
change_addr=change_addr)
|
||||
if locktime is not None:
|
||||
tx.locktime = locktime
|
||||
if rbf is None:
|
||||
rbf = self.config.get('use_rbf', True)
|
||||
if rbf:
|
||||
tx.set_rbf(True)
|
||||
if not unsigned:
|
||||
wallet.sign_transaction(tx, password)
|
||||
return tx
|
||||
|
||||
@command('wp')
|
||||
async def payto(self, destination, amount, fee=None, feerate=None, from_addr=None, from_coins=None, change_addr=None,
|
||||
nocheck=False, unsigned=False, rbf=None, password=None, locktime=None, wallet: Abstract_Wallet = None):
|
||||
"""Create a transaction. """
|
||||
self.nocheck = nocheck
|
||||
tx_fee = satoshis(fee)
|
||||
domain_addr = from_addr.split(',') if from_addr else None
|
||||
domain_coins = from_coins.split(',') if from_coins else None
|
||||
tx = self._mktx(wallet,
|
||||
[(destination, amount)],
|
||||
fee=tx_fee,
|
||||
feerate=feerate,
|
||||
change_addr=change_addr,
|
||||
domain_addr=domain_addr,
|
||||
domain_coins=domain_coins,
|
||||
nocheck=nocheck,
|
||||
unsigned=unsigned,
|
||||
rbf=rbf,
|
||||
password=password,
|
||||
locktime=locktime)
|
||||
change_addr = self._resolver(change_addr, wallet)
|
||||
domain_addr = None if domain_addr is None else map(self._resolver, domain_addr, repeat(wallet))
|
||||
amount_sat = satoshis(amount)
|
||||
outputs = [PartialTxOutput.from_address_and_value(destination, amount_sat)]
|
||||
tx = wallet.create_transaction(
|
||||
outputs,
|
||||
fee=tx_fee,
|
||||
feerate=feerate,
|
||||
change_addr=change_addr,
|
||||
domain_addr=domain_addr,
|
||||
domain_coins=domain_coins,
|
||||
unsigned=unsigned,
|
||||
rbf=rbf,
|
||||
password=password,
|
||||
locktime=locktime)
|
||||
return tx.serialize()
|
||||
|
||||
@command('wp')
|
||||
async def paytomany(self, outputs, fee=None, feerate=None, from_addr=None, from_coins=None, change_addr=None,
|
||||
nocheck=False, unsigned=False, rbf=None, password=None, locktime=None, wallet: Abstract_Wallet = None):
|
||||
"""Create a multi-output transaction. """
|
||||
self.nocheck = nocheck
|
||||
tx_fee = satoshis(fee)
|
||||
domain_addr = from_addr.split(',') if from_addr else None
|
||||
domain_coins = from_coins.split(',') if from_coins else None
|
||||
tx = self._mktx(wallet,
|
||||
outputs,
|
||||
fee=tx_fee,
|
||||
feerate=feerate,
|
||||
change_addr=change_addr,
|
||||
domain_addr=domain_addr,
|
||||
domain_coins=domain_coins,
|
||||
nocheck=nocheck,
|
||||
unsigned=unsigned,
|
||||
rbf=rbf,
|
||||
password=password,
|
||||
locktime=locktime)
|
||||
change_addr = self._resolver(change_addr, wallet)
|
||||
domain_addr = None if domain_addr is None else map(self._resolver, domain_addr, repeat(wallet))
|
||||
final_outputs = []
|
||||
for address, amount in outputs:
|
||||
address = self._resolver(address, wallet)
|
||||
amount_sat = satoshis(amount)
|
||||
final_outputs.append(PartialTxOutput.from_address_and_value(address, amount_sat))
|
||||
tx = wallet.create_transaction(
|
||||
final_outputs,
|
||||
fee=tx_fee,
|
||||
feerate=feerate,
|
||||
change_addr=change_addr,
|
||||
domain_addr=domain_addr,
|
||||
domain_coins=domain_coins,
|
||||
unsigned=unsigned,
|
||||
rbf=rbf,
|
||||
password=password,
|
||||
locktime=locktime)
|
||||
return tx.serialize()
|
||||
|
||||
@command('w')
|
||||
|
||||
@@ -1876,6 +1876,33 @@ class Abstract_Wallet(AddressSynchronizer, ABC):
|
||||
def get_all_known_addresses_beyond_gap_limit(self) -> Set[str]:
|
||||
pass
|
||||
|
||||
def create_transaction(self, outputs, *, fee=None, feerate=None, change_addr=None, domain_addr=None, domain_coins=None,
|
||||
unsigned=False, rbf=None, password=None, locktime=None):
|
||||
if fee is not None and feerate is not None:
|
||||
raise Exception("Cannot specify both 'fee' and 'feerate' at the same time!")
|
||||
coins = self.get_spendable_coins(domain_addr)
|
||||
if domain_coins is not None:
|
||||
coins = [coin for coin in coins if (coin.prevout.to_str() in domain_coins)]
|
||||
if feerate is not None:
|
||||
fee_per_kb = 1000 * Decimal(feerate)
|
||||
fee_estimator = partial(SimpleConfig.estimate_fee_for_feerate, fee_per_kb)
|
||||
else:
|
||||
fee_estimator = fee
|
||||
tx = self.make_unsigned_transaction(
|
||||
coins=coins,
|
||||
outputs=outputs,
|
||||
fee=fee_estimator,
|
||||
change_addr=change_addr)
|
||||
if locktime is not None:
|
||||
tx.locktime = locktime
|
||||
if rbf is None:
|
||||
rbf = self.config.get('use_rbf', True)
|
||||
if rbf:
|
||||
tx.set_rbf(True)
|
||||
if not unsigned:
|
||||
self.sign_transaction(tx, password)
|
||||
return tx
|
||||
|
||||
|
||||
class Simple_Wallet(Abstract_Wallet):
|
||||
# wallet with a single keystore
|
||||
|
||||
Reference in New Issue
Block a user