From 775e3bd7a4b5fea6a1e169affe7883fd8a39fc4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sa=C5=82aban?= Date: Thu, 15 Feb 2018 21:20:48 +0100 Subject: [PATCH] Add API docs for Account and Wallet --- monero/account.py | 65 +++++++++++++++++++++++++++++- monero/address.py | 18 ++++----- monero/wallet.py | 100 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 172 insertions(+), 11 deletions(-) diff --git a/monero/account.py b/monero/account.py index a4e3cc2..3f1210e 100644 --- a/monero/account.py +++ b/monero/account.py @@ -4,6 +4,17 @@ from .transaction import PaymentManager class Account(object): + """Monero account. + + Provides interface to operate on a wallet's account. + + Accounts belong to a :class:`Wallet ` and act like + separate sub-wallets. No funds can be moved between accounts off-chain + (without a transaction). + + :param backend: a wallet backend + :param index: the account's index within the wallet + """ index = None def __init__(self, backend, index): @@ -13,26 +24,65 @@ class Account(object): self.outgoing = PaymentManager(index, backend, 'out') def balances(self): + """ + Returns a tuple of balance and unlocked balance. + + :rtype: (Decimal, Decimal) + """ return self._backend.balances(account=self.index) def balance(self, unlocked=False): + """ + Returns specified balance. + + :param unlocked: if `True`, return the unlocked balance, otherwise return total balance + :rtype: Decimal + """ return self._backend.balances(account=self.index)[1 if unlocked else 0] def address(self): """ Return account's main address. + + :rtype: :class:`SubAddress ` """ return self._backend.addresses(account=self.index)[0] def addresses(self): + """ + Returns all addresses of the account. + + :rtype: list + """ return self._backend.addresses(account=self.index) def new_address(self, label=None): + """ + Creates a new address. + + :rtype: :class:`SubAddress ` + """ return self._backend.new_address(account=self.index, label=label) def transfer(self, address, amount, priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0, relay=True): + """ + Sends a transfer. Returns a list of resulting transactions. + + :param address: destination :class:`Address ` or subtype + :param amount: amount to send + :param priority: transaction priority (implies fee) + :param ringsize: the ring size (mixin + 1) + :param payment_id: ID for the payment (must be None if + :class:`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 ` + """ return self._backend.transfer( [(address, amount)], priority, @@ -46,7 +96,20 @@ class Account(object): priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0, relay=True): """ - destinations = [(address, amount), ...] + Sends a batch of transfers. Returns a list of resulting transactions. + + :param destinations: a list of destination and amount pairs: + [(:class:`Address `, `Decimal`), ...] + :param priority: transaction priority (implies fee) + :param ringsize: the ring size (mixin + 1) + :param payment_id: ID for the payment (must be None if + :class:`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 ` """ return self._backend.transfer( destinations, diff --git a/monero/address.py b/monero/address.py index a571901..86cf038 100644 --- a/monero/address.py +++ b/monero/address.py @@ -13,12 +13,11 @@ _IADDR_REGEX = re.compile(r'^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqr class Address(object): """Monero address. - Address of this class is the master address for a wallet. + Address of this class is the master address for a :class:`Wallet `. :param address: a Monero address as string-like object :param label: a label for the address (defaults to `None`) """ - label = None _valid_netbytes = (18, 53) # NOTE: _valid_netbytes order is (real, testnet) @@ -65,10 +64,11 @@ class Address(object): def with_payment_id(self, payment_id=0): """Integrates payment id into the address. - :param payment_id: int, hexadecimal string or PaymentID (max 64-bit long) + :param payment_id: int, hexadecimal string or :class:`PaymentID ` + (max 64-bit long) - :rtype: IntegratedAddress - :raises: TypeError if the payment id is too long + :rtype: `IntegratedAddress` + :raises: `TypeError` if the payment id is too long """ payment_id = numbers.PaymentID(payment_id) if not payment_id.is_short(): @@ -92,7 +92,7 @@ class Address(object): class SubAddress(Address): """Monero subaddress. - Any type of wallet address which is not the master one. + Any type of address which is not the master one for a wallet. """ _valid_netbytes = (42, 63) @@ -119,13 +119,13 @@ class IntegratedAddress(Address): def payment_id(self): """Returns the integrated payment id. - :rtype: PaymentID + :rtype: :class:`PaymentID ` """ return numbers.PaymentID(hexlify(self._decoded[65:-4]).decode()) def base_address(self): """Returns the base address without payment id. - :rtype: Address + :rtype: :class:`Address` """ prefix = 53 if self.is_testnet() else 18 data = bytearray([prefix]) + self._decoded[1:65] @@ -139,7 +139,7 @@ def address(addr, label=None): :param addr: the address as a string-like object :param label: a label for the address (defaults to `None`) - :rtype: Address, SubAddress or IntegratedAddress + :rtype: :class:`Address`, :class:`SubAddress` or :class:`IntegratedAddress` """ addr = str(addr) if _ADDR_REGEX.match(addr): diff --git a/monero/wallet.py b/monero/wallet.py index 6a343ae..6265124 100644 --- a/monero/wallet.py +++ b/monero/wallet.py @@ -3,7 +3,23 @@ from . import prio from . import account from .transaction import Payment, PaymentManager + class Wallet(object): + """ + Monero wallet. + + Provides interface to operate on a wallet. + + Wallet consists of :class:`accounts `. 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 + """ accounts = None def __init__(self, backend): @@ -13,6 +29,12 @@ class Wallet(object): self.refresh() def refresh(self): + """ + 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. + """ self.accounts = self.accounts or [] idx = 0 for _acc in self._backend.accounts(): @@ -27,34 +49,54 @@ class Wallet(object): def height(self): """ Returns the height of the wallet. + + :rtype: int """ return self._backend.height() def spend_key(self): """ Returns private spend key. + + :rtype: str """ return self._backend.spend_key() def view_key(self): """ Returns private view key. + + :rtype: str """ return self._backend.view_key() def seed(self): """ Returns word seed. + + :rtype: str """ return self._backend.seed() def new_account(self, label=None): + """ + Creates new account, appends it to the :class:`Wallet`'s account list and returns it. + + :rtype: :class:`Account` + """ acc, addr = self._backend.new_account(label=label) assert acc.index == len(self.accounts) self.accounts.append(acc) return acc def confirmations(self, txn_or_pmt): + """ + Returns the number of confirmations for given + :class:`Transaction ` or + :class:`Payment ` object. + + :rtype: int + """ if isinstance(txn_or_pmt, Payment): txn = txn_or_pmt.transaction else: @@ -66,23 +108,66 @@ class Wallet(object): # Following methods operate on default account (index=0) def balances(self): + """ + Returns a tuple of balance and unlocked balance. + + :rtype: (Decimal, Decimal) + """ return self.accounts[0].balances() def balance(self, unlocked=False): + """ + Returns specified balance. + + :param unlocked: if `True`, return the unlocked balance, otherwise return total balance + :rtype: Decimal + """ return self.accounts[0].balance(unlocked=unlocked) def address(self): + """ + Returns wallet's master address. + + :rtype: :class:`Address ` + """ return self.accounts[0].addresses()[0] def addresses(self): + """ + Returns all addresses of the default account. + + :rtype: list of :class:`Address ` and + :class:`SubAddress ` + """ return self.accounts[0].addresses() def new_address(self, label=None): + """ + Creates a new address in the default account. + + :rtype: :class:`SubAddress ` + """ return self.accounts[0].new_address(label=label) def transfer(self, address, amount, priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0, relay=True): + """ + Sends a transfer from the default account. Returns a list of resulting transactions. + + :param address: destination :class:`Address ` or subtype + :param amount: amount to send + :param priority: transaction priority (implies fee) + :param ringsize: the ring size (mixin + 1) + :param payment_id: ID for the payment (must be None if + :class:`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 ` + """ return self.accounts[0].transfer( address, amount, @@ -96,7 +181,20 @@ class Wallet(object): priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0, relay=True): """ - destinations = [(address, amount), ...] + 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), ...] + :param priority: transaction priority (implies fee) + :param ringsize: the ring size (mixin + 1) + :param payment_id: ID for the payment (must be None if + :class:`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 ` """ return self.accounts[0].transfer_multiple( destinations,