Add sweep_all() method, close #20

This commit is contained in:
Michał Sałaban 2019-06-26 20:01:43 +02:00
parent 010408dcf9
commit 48cad4007a
7 changed files with 1346 additions and 20 deletions

View file

@ -108,13 +108,14 @@ class Account(object):
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
:param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:param unlock_time: the extra unlock delay
:param relay: if `True`, the wallet will relay the transaction(s) to the network
immediately; when `False`, it will only return the transaction(s)
so they might be broadcasted later
:rtype: list of :class:`Transaction <monero.transaction.Transaction>`
immediately; when `False`, it will only return the transaction(s)
so they might be broadcast later
:rtype: list of transaction and amount pairs:
[(:class:`Transaction <monero.transaction.Transaction>`, `Decimal`), ...]
"""
return self._backend.transfer(
destinations,
@ -123,3 +124,32 @@ class Account(object):
unlock_time,
account=self.index,
relay=relay)
def sweep_all(self, address, priority=prio.NORMAL, payment_id=None,
subaddr_indices=None, unlock_time=0, relay=True):
"""
Sends all unlocked balance to an address. Returns a list of resulting transactions.
:param address: destination :class:`Address <monero.address.Address>` or subtype
:param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
:param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:param subaddr_indices: a sequence of subaddress indices to sweep from. Empty sequence
or `None` means sweep all positive balances.
:param unlock_time: the extra unlock delay
:param relay: if `True`, the wallet will relay the transaction(s) to the network
immediately; when `False`, it will only return the transaction(s)
so they might be broadcast later
:rtype: list of :class:`Transaction <monero.transaction.Transaction>`
"""
return self._backend.sweep_all(
address,
priority,
payment_id,
subaddr_indices,
unlock_time,
account=self.index,
relay=relay)

View file

@ -106,8 +106,6 @@ class JSONRPCDaemon(object):
return result['result']
class JSONRPCWallet(object):
"""
JSON RPC backend for Monero wallet (``monero-wallet-rpc``)
@ -121,7 +119,6 @@ class JSONRPCWallet(object):
:param timeout: request timeout
"""
_master_address = None
_addresses = None
def __init__(self, protocol='http', host='127.0.0.1', port=18088, path='/json_rpc',
user='', password='', timeout=30):
@ -313,6 +310,38 @@ class JSONRPCWallet(object):
d['payment_id'] = payment_id
return [self._tx(data) for data in _pertx]
def sweep_all(self, destination, priority, payment_id=None, subaddr_indices=None,
unlock_time=0, account=0, relay=True):
if not subaddr_indices:
# retrieve indices of all subaddresses with positive unlocked balance
bals = self.raw_request('get_balance', {'account_index': account})
subaddr_indices = []
for subaddr in bals['per_subaddress']:
if subaddr.get('unlocked_balance', 0):
subaddr_indices.append(subaddr['address_index'])
data = {
'account_index': account,
'address': str(address(destination)),
'subaddr_indices': list(subaddr_indices),
'priority': priority,
'unlock_time': 0,
'get_tx_keys': True,
'get_tx_hex': True,
'do_not_relay': not relay,
}
if payment_id is not None:
data['payment_id'] = str(PaymentID(payment_id))
_transfers = self.raw_request('sweep_all', data)
_pertx = [dict(_tx) for _tx in map(
lambda vs: zip(('txid', 'amount', 'fee', 'key', 'blob', 'payment_id'), vs),
zip(*[_transfers[k] for k in (
'tx_hash_list', 'amount_list', 'fee_list', 'tx_key_list', 'tx_blob_list')]))]
for d in _pertx:
d['payment_id'] = payment_id
return list(zip(
[self._tx(data) for data in _pertx],
map(from_atomic, _transfers['amount_list'])))
def raw_request(self, method, params=None, squelch_error_logging=False):
hdr = {'Content-Type': 'application/json'}
data = {'jsonrpc': '2.0', 'id': 0, 'method': method, 'params': params or {}}

View file

@ -242,12 +242,12 @@ class Wallet(object):
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
:param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:param unlock_time: the extra unlock delay
:param relay: if `True`, the wallet will relay the transaction(s) to the network
immediately; when `False`, it will only return the transaction(s)
so they might be broadcasted later
immediately; when `False`, it will only return the transaction(s)
so they might be broadcast later
:rtype: list of :class:`Transaction <monero.transaction.Transaction>`
"""
return self.accounts[0].transfer(
@ -263,20 +263,21 @@ class Wallet(object):
relay=True):
"""
Sends a batch of transfers from the default account. Returns a list of resulting
transactions.
transactions and amounts.
:param destinations: a list of destination and amount pairs: [(address, amount), ...]
:param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
:param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as a destination)
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as a destination)
:param unlock_time: the extra unlock delay
:param relay: if `True`, the wallet will relay the transaction(s) to the network
immediately; when `False`, it will only return the transaction(s)
so they might be broadcasted later
:rtype: list of :class:`Transaction <monero.transaction.Transaction>`
immediately; when `False`, it will only return the transaction(s)
so they might be broadcast later
:rtype: list of transaction and amount pairs:
[(:class:`Transaction <monero.transaction.Transaction>`, `Decimal`), ...]
"""
return self.accounts[0].transfer_multiple(
destinations,
@ -284,3 +285,32 @@ class Wallet(object):
payment_id=payment_id,
unlock_time=unlock_time,
relay=relay)
def sweep_all(self, address, priority=prio.NORMAL, payment_id=None,
subaddr_indices=None, unlock_time=0, relay=True):
"""
Sends all unlocked balance from the default account to an address.
Returns a list of resulting transactions.
:param address: destination :class:`Address <monero.address.Address>` or subtype
:param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant
from `monero.prio`.
:param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination)
:param subaddr_indices: a sequence of subaddress indices to sweep from. Empty sequence
or `None` means sweep all positive balances.
:param unlock_time: the extra unlock delay
:param relay: if `True`, the wallet will relay the transaction(s) to the network
immediately; when `False`, it will only return the transaction(s)
so they might be broadcast later
:rtype: list of :class:`Transaction <monero.transaction.Transaction>`
"""
return self.accounts[0].sweep_all(
address,
priority=priority,
payment_id=payment_id,
subaddr_indices=subaddr_indices,
unlock_time=unlock_time,
relay=relay)