Update checks and tests

This commit is contained in:
Michał Sałaban 2018-01-30 09:43:08 +01:00
parent a814197057
commit ed383d6040
12 changed files with 287 additions and 228 deletions

View file

@ -23,12 +23,12 @@ class Address(object):
_valid_netbytes = (18, 53)
# NOTE: _valid_netbytes order is (real, testnet)
def __init__(self, address, label=None):
address = str(address)
if not _ADDR_REGEX.match(address):
def __init__(self, addr, label=None):
addr = str(addr)
if not _ADDR_REGEX.match(addr):
raise ValueError("Address must be 95 characters long base58-encoded string, "
"is {addr} ({len} chars length)".format(addr=address, len=len(address)))
self._decode(address)
"is {addr} ({len} chars length)".format(addr=addr, len=len(addr)))
self._decode(addr)
self.label = label or self.label
def _decode(self, address):
@ -86,7 +86,7 @@ class Address(object):
return str(self) == str(other)
if isinstance(other, str):
return str(self) == other
return super()
return super(Address, self).__eq__(other)
class SubAddress(Address):
@ -148,12 +148,12 @@ def address(addr, label=None):
return Address(addr, label=label)
elif netbyte in SubAddress._valid_netbytes:
return SubAddress(addr, label=label)
raise ValueError("Invalid address netbyte {nb}. Allowed values are: {allowed}".format(
nb=hexlify(chr(netbyte)),
raise ValueError("Invalid address netbyte {nb:x}. Allowed values are: {allowed}".format(
nb=netbyte,
allowed=", ".join(map(
lambda b: '%02x' % b,
sorted(Address._valid_netbytes + SubAddress._valid_netbytes)))))
elif _IADDR_REGEX.match(addr):
return IntegratedAddress(addr)
raise ValueError("Address must be either 95 or 106 characters long base58-encoded string, "
"is {addr} ({len} chars length)".format(addr=address, len=len(address)))
"is {addr} ({len} chars length)".format(addr=addr, len=len(addr)))

View file

@ -212,27 +212,18 @@ class JSONRPCWallet(object):
pmts.extend(_pmts.get('pool', []))
return list(pmtfilter.filter(map(self._outpayment, pmts)))
def get_transaction(self, txhash):
_tx = self.raw_request('get_transfer_by_txid', {'txid': str(txhash)})['transfer']
if _tx['type'] == 'in':
return self._inpayment(tx)
elif _tx['type'] == 'out':
return self._outpayment(tx)
return Payment(**self._paymentdict(tx))
def _paymentdict(self, data):
pid = data.get('payment_id', None)
addr = data.get('address', None)
if addr:
addr = address(addr)
laddr = data.get('address', None)
if laddr:
laddr = address(laddr)
return {
'txhash': data.get('txid', data.get('tx_hash')),
'payment_id': None if pid is None else PaymentID(pid),
'amount': from_atomic(data['amount']),
'timestamp': datetime.fromtimestamp(data['timestamp']) if 'timestamp' in data else None,
'note': data.get('note', None),
'transaction': self._tx(data),
'address': addr,
'local_address': laddr,
}
def _inpayment(self, data):

View file

@ -59,4 +59,4 @@ class PaymentID(object):
return int(self) == other
elif isinstance(other, _str_types):
return str(self) == other
return super()
return super(PaymentID, self).__eq__(other)

View file

@ -7,14 +7,18 @@ class Payment(object):
amount = None
timestamp = None
transaction = None
address = None
local_address = None
note = ''
def __init__(self, **kwargs):
self.amount = kwargs.get('amount', self.amount)
self.timestamp = kwargs.get('timestamp', self.timestamp)
self.payment_id = kwargs.get('payment_id', self.payment_id)
self.transaction = kwargs.get('transaction', self.transaction)
self.address = kwargs.get('address', self.address)
self.amount = kwargs.pop('amount', self.amount)
self.timestamp = kwargs.pop('timestamp', self.timestamp)
self.payment_id = kwargs.pop('payment_id', self.payment_id)
self.transaction = kwargs.pop('transaction', self.transaction)
self.local_address = kwargs.pop('local_address', self.local_address)
self.note = kwargs.pop('note', self.note)
if len(kwargs):
raise ValueError("Excessive arguments for {}: {}".format(type(self), kwargs))
def __repr__(self):
return "{} {:.12f} id={}".format(self.transaction.hash, self.amount, self.payment_id)
@ -26,12 +30,6 @@ class IncomingPayment(Payment):
class OutgoingPayment(Payment):
note = ''
def __init__(self, **kwargs):
super(OutgoingPayment, self).__init__(**kwargs)
self.note = kwargs.get('note', self.note)
def __repr__(self):
return "out: {} {:.12f} id={}".format(self.transaction.hash, self.amount, self.payment_id)
@ -82,23 +80,23 @@ class PaymentFilter(object):
self.max_height = filterparams.pop('max_height', None)
self.unconfirmed = filterparams.pop('unconfirmed', False)
self.confirmed = filterparams.pop('confirmed', True)
_address = filterparams.pop('address', None)
_local_address = filterparams.pop('local_address', None)
_payment_id = filterparams.pop('payment_id', None)
if len(filterparams) > 0:
raise ValueError("Excessive arguments for payment query: {:r}".format(filterparams))
raise ValueError("Excessive arguments for payment query: {}".format(filterparams))
if _address is None:
self.addresses = []
if _local_address is None:
self.local_addresses = []
else:
if isinstance(_address, _str_types):
addresses = [_address]
if isinstance(_local_address, _str_types):
local_addresses = [_local_address]
else:
try:
iter(_address)
addresses = _address
iter(_local_address)
local_addresses = _local_address
except TypeError:
addresses = [_address]
self.addresses = list(map(address, addresses))
local_addresses = [_local_address]
self.local_addresses = list(map(address, local_addresses))
if _payment_id is None:
self.payment_ids = []
else:
@ -129,7 +127,7 @@ class PaymentFilter(object):
return False
if self.payment_ids and payment.payment_id not in self.payment_ids:
return False
if self.addresses and payment.address not in self.addresses:
if self.local_addresses and payment.local_address not in self.local_addresses:
return False
return True

View file

@ -1,7 +1,7 @@
from . import address
from . import prio
from . import account
from .transaction import PaymentManager
from .transaction import Payment, PaymentManager
class Wallet(object):
accounts = None
@ -54,14 +54,15 @@ class Wallet(object):
self.accounts.append(acc)
return acc
def get_transaction(self, hash):
return self._backend.get_transaction(hash)
def confirmations(self, txn):
txn = self._backend.get_transaction(txn)
if txn.height is None:
def confirmations(self, txn_or_pmt):
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:
return 0
return max(0, self.height() - txn.height)
# Following methods operate on default account (index=0)
def balances(self):
@ -79,15 +80,6 @@ class Wallet(object):
def new_address(self, label=None):
return self.accounts[0].new_address(label=label)
def payments(self, payment_id):
return self.accounts[0].payments(payment_id)
def transfers_in(self, confirmed=True, unconfirmed=False):
return self.accounts[0].transfers_in(confirmed=confirmed, unconfirmed=unconfirmed)
def transfers_out(self, confirmed=True, unconfirmed=True):
return self.accounts[0].transfers_out(confirmed=confirmed, unconfirmed=unconfirmed)
def transfer(self, address, amount,
priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0,
relay=True):