2017-11-26 22:22:48 +00:00
|
|
|
from . import prio
|
2018-01-30 08:43:08 +00:00
|
|
|
from .transaction import Payment, PaymentManager
|
2017-11-26 22:22:48 +00:00
|
|
|
|
2018-02-15 20:20:48 +00:00
|
|
|
|
2017-11-26 22:22:48 +00:00
|
|
|
class Wallet(object):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Monero wallet.
|
|
|
|
|
|
|
|
Provides interface to operate on a wallet.
|
|
|
|
|
|
|
|
Wallet consists of :class:`accounts <monero.account.Account>`. In Monero 0.11 and earlier the wallet has only a single account
|
|
|
|
with index 0. In later versions there might be multiple accounts, but a fresh wallet starts
|
|
|
|
with only one.
|
|
|
|
|
|
|
|
The list of accounts will be initialized under the `accounts` attribute.
|
|
|
|
|
|
|
|
The wallet exposes a number of methods that operate on the default account (of index 0).
|
|
|
|
|
|
|
|
:param backend: a wallet backend
|
|
|
|
"""
|
2017-11-26 22:22:48 +00:00
|
|
|
accounts = None
|
|
|
|
|
|
|
|
def __init__(self, backend):
|
|
|
|
self._backend = backend
|
2018-01-29 14:11:53 +00:00
|
|
|
self.incoming = PaymentManager(0, backend, 'in')
|
|
|
|
self.outgoing = PaymentManager(0, backend, 'out')
|
2017-11-26 22:22:48 +00:00
|
|
|
self.refresh()
|
|
|
|
|
|
|
|
def refresh(self):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Reloads the wallet and its accounts. By default, this method is called only once,
|
|
|
|
on :class:`Wallet` initialization. When the wallet is accessed by multiple clients or
|
|
|
|
exists in multiple instances, calling `refresh()` will be necessary to update
|
|
|
|
the list of accounts.
|
|
|
|
"""
|
2017-11-26 22:22:48 +00:00
|
|
|
self.accounts = self.accounts or []
|
|
|
|
idx = 0
|
2018-01-28 15:11:27 +00:00
|
|
|
for _acc in self._backend.accounts():
|
2017-11-26 22:22:48 +00:00
|
|
|
try:
|
|
|
|
if self.accounts[idx]:
|
|
|
|
continue
|
|
|
|
except IndexError:
|
|
|
|
pass
|
|
|
|
self.accounts.append(_acc)
|
|
|
|
idx += 1
|
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def height(self):
|
2018-01-22 02:55:08 +00:00
|
|
|
"""
|
|
|
|
Returns the height of the wallet.
|
2018-02-15 20:20:48 +00:00
|
|
|
|
|
|
|
:rtype: int
|
2018-01-22 02:55:08 +00:00
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self._backend.height()
|
2018-01-22 02:55:08 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def spend_key(self):
|
2018-01-28 12:04:47 +00:00
|
|
|
"""
|
|
|
|
Returns private spend key.
|
2018-02-15 20:20:48 +00:00
|
|
|
|
|
|
|
:rtype: str
|
2018-01-28 12:04:47 +00:00
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self._backend.spend_key()
|
2018-01-28 12:04:47 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def view_key(self):
|
2018-01-14 05:28:28 +00:00
|
|
|
"""
|
|
|
|
Returns private view key.
|
2018-02-15 20:20:48 +00:00
|
|
|
|
|
|
|
:rtype: str
|
2018-01-14 05:28:28 +00:00
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self._backend.view_key()
|
2018-01-14 05:28:28 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def seed(self):
|
2018-01-14 05:28:28 +00:00
|
|
|
"""
|
|
|
|
Returns word seed.
|
2018-02-15 20:20:48 +00:00
|
|
|
|
|
|
|
:rtype: str
|
2018-01-14 05:28:28 +00:00
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self._backend.seed()
|
2018-01-14 05:28:28 +00:00
|
|
|
|
2018-01-11 22:17:34 +00:00
|
|
|
def new_account(self, label=None):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Creates new account, appends it to the :class:`Wallet`'s account list and returns it.
|
|
|
|
|
|
|
|
:rtype: :class:`Account`
|
|
|
|
"""
|
2018-01-11 22:17:34 +00:00
|
|
|
acc, addr = self._backend.new_account(label=label)
|
|
|
|
assert acc.index == len(self.accounts)
|
|
|
|
self.accounts.append(acc)
|
|
|
|
return acc
|
|
|
|
|
2018-01-30 08:43:08 +00:00
|
|
|
def confirmations(self, txn_or_pmt):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Returns the number of confirmations for given
|
|
|
|
:class:`Transaction <monero.transaction.Transaction>` or
|
|
|
|
:class:`Payment <monero.transaction.Payment>` object.
|
|
|
|
|
|
|
|
:rtype: int
|
|
|
|
"""
|
2018-01-30 08:43:08 +00:00
|
|
|
if isinstance(txn_or_pmt, Payment):
|
|
|
|
txn = txn_or_pmt.transaction
|
|
|
|
else:
|
|
|
|
txn = txn_or_pmt
|
|
|
|
try:
|
|
|
|
return max(0, self.height() - txn.height)
|
|
|
|
except TypeError:
|
2018-01-22 02:55:08 +00:00
|
|
|
return 0
|
|
|
|
|
2017-11-26 22:22:48 +00:00
|
|
|
# Following methods operate on default account (index=0)
|
2018-01-28 15:11:27 +00:00
|
|
|
def balances(self):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Returns a tuple of balance and unlocked balance.
|
|
|
|
|
|
|
|
:rtype: (Decimal, Decimal)
|
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self.accounts[0].balances()
|
2017-12-01 05:06:15 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def balance(self, unlocked=False):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Returns specified balance.
|
|
|
|
|
|
|
|
:param unlocked: if `True`, return the unlocked balance, otherwise return total balance
|
|
|
|
:rtype: Decimal
|
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self.accounts[0].balance(unlocked=unlocked)
|
2017-11-26 22:22:48 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def address(self):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Returns wallet's master address.
|
|
|
|
|
|
|
|
:rtype: :class:`Address <monero.address.Address>`
|
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self.accounts[0].addresses()[0]
|
2017-11-26 22:22:48 +00:00
|
|
|
|
2018-01-28 15:11:27 +00:00
|
|
|
def addresses(self):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Returns all addresses of the default account.
|
|
|
|
|
|
|
|
:rtype: list of :class:`Address <monero.address.Address>` and
|
|
|
|
:class:`SubAddress <monero.address.SubAddress>`
|
|
|
|
"""
|
2018-01-28 15:11:27 +00:00
|
|
|
return self.accounts[0].addresses()
|
2018-01-13 21:24:17 +00:00
|
|
|
|
2018-01-11 22:17:34 +00:00
|
|
|
def new_address(self, label=None):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Creates a new address in the default account.
|
|
|
|
|
|
|
|
:rtype: :class:`SubAddress <monero.address.SubAddress>`
|
|
|
|
"""
|
2018-01-11 22:17:34 +00:00
|
|
|
return self.accounts[0].new_address(label=label)
|
|
|
|
|
2018-01-14 02:40:46 +00:00
|
|
|
def transfer(self, address, amount,
|
2018-03-15 23:21:09 +00:00
|
|
|
priority=prio.NORMAL, ringsize=7, payment_id=None, unlock_time=0,
|
2018-01-14 02:40:46 +00:00
|
|
|
relay=True):
|
2018-02-15 20:20:48 +00:00
|
|
|
"""
|
|
|
|
Sends a transfer from the default account. Returns a list of resulting transactions.
|
|
|
|
|
|
|
|
:param address: destination :class:`Address <monero.address.Address>` or subtype
|
|
|
|
:param amount: amount to send
|
2018-02-15 20:32:26 +00:00
|
|
|
: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`.
|
2018-02-15 20:20:48 +00:00
|
|
|
:param ringsize: the ring size (mixin + 1)
|
|
|
|
:param payment_id: ID for the payment (must be None if
|
|
|
|
: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>`
|
|
|
|
"""
|
2017-11-29 03:38:29 +00:00
|
|
|
return self.accounts[0].transfer(
|
|
|
|
address,
|
|
|
|
amount,
|
|
|
|
priority=priority,
|
2018-01-13 21:24:17 +00:00
|
|
|
ringsize=ringsize,
|
2018-07-06 06:19:00 +00:00
|
|
|
payment_id=payment_id,
|
2018-01-14 02:40:46 +00:00
|
|
|
unlock_time=unlock_time,
|
|
|
|
relay=relay)
|
2017-11-29 03:38:29 +00:00
|
|
|
|
2018-01-14 02:40:46 +00:00
|
|
|
def transfer_multiple(self, destinations,
|
2018-03-15 23:21:09 +00:00
|
|
|
priority=prio.NORMAL, ringsize=7, payment_id=None, unlock_time=0,
|
2018-01-14 02:40:46 +00:00
|
|
|
relay=True):
|
2017-11-26 22:22:48 +00:00
|
|
|
"""
|
2018-02-15 20:20:48 +00:00
|
|
|
Sends a batch of transfers from the default account. Returns a list of resulting
|
|
|
|
transactions.
|
|
|
|
|
|
|
|
:param destinations: a list of destination and amount pairs: [(address, amount), ...]
|
2018-02-15 20:32:26 +00:00
|
|
|
: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`.
|
2018-02-15 20:20:48 +00:00
|
|
|
:param ringsize: the ring size (mixin + 1)
|
|
|
|
:param payment_id: ID for the payment (must be None if
|
|
|
|
: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>`
|
2017-11-26 22:22:48 +00:00
|
|
|
"""
|
2017-11-29 03:38:29 +00:00
|
|
|
return self.accounts[0].transfer_multiple(
|
|
|
|
destinations,
|
|
|
|
priority=priority,
|
2018-01-13 21:24:17 +00:00
|
|
|
ringsize=ringsize,
|
2018-07-06 06:19:00 +00:00
|
|
|
payment_id=payment_id,
|
2018-01-14 02:40:46 +00:00
|
|
|
unlock_time=unlock_time,
|
|
|
|
relay=relay)
|