mirror of
https://git.wownero.com/lza_menace/wownero-python.git
synced 2024-08-15 03:25:25 +00:00
Merge branch 'mempool'
This commit is contained in:
commit
a59a8f737a
7 changed files with 94 additions and 33 deletions
|
@ -30,11 +30,13 @@ class Account(object):
|
||||||
def get_payments(self, payment_id=None):
|
def get_payments(self, payment_id=None):
|
||||||
return self._backend.get_payments(account=self.index, payment_id=payment_id)
|
return self._backend.get_payments(account=self.index, payment_id=payment_id)
|
||||||
|
|
||||||
def get_transactions_in(self):
|
def get_transactions_in(self, confirmed=True, unconfirmed=False):
|
||||||
return self._backend.get_transactions_in(account=self.index)
|
return self._backend.get_transactions_in(
|
||||||
|
account=self.index, confirmed=confirmed, unconfirmed=unconfirmed)
|
||||||
|
|
||||||
def get_transactions_out(self):
|
def get_transactions_out(self, confirmed=True, unconfirmed=True):
|
||||||
return self._backend.get_transactions_out(account=self.index)
|
return self._backend.get_transactions_out(
|
||||||
|
account=self.index, confirmed=confirmed, unconfirmed=unconfirmed)
|
||||||
|
|
||||||
def transfer(self, address, amount,
|
def transfer(self, address, amount,
|
||||||
priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0,
|
priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0,
|
||||||
|
|
|
@ -37,6 +37,16 @@ class JSONRPCDaemon(object):
|
||||||
"{status}: {reason}".format(**res),
|
"{status}: {reason}".format(**res),
|
||||||
details=res)
|
details=res)
|
||||||
|
|
||||||
|
def get_mempool(self):
|
||||||
|
res = self.raw_request('/get_transaction_pool', {})
|
||||||
|
txs = []
|
||||||
|
for tx in res.get('transactions', []):
|
||||||
|
txs.append(Transaction(
|
||||||
|
hash=tx['id_hash'],
|
||||||
|
fee=from_atomic(tx['fee']),
|
||||||
|
timestamp=datetime.fromtimestamp(tx['receive_time'])))
|
||||||
|
return txs
|
||||||
|
|
||||||
def raw_request(self, path, data):
|
def raw_request(self, path, data):
|
||||||
hdr = {'Content-Type': 'application/json'}
|
hdr = {'Content-Type': 'application/json'}
|
||||||
_log.debug(u"Request: {path}\nData: {data}".format(
|
_log.debug(u"Request: {path}\nData: {data}".format(
|
||||||
|
@ -103,6 +113,9 @@ class JSONRPCWallet(object):
|
||||||
_log.debug("JSONRPC wallet backend auth: '{user}'/'{stars}'".format(
|
_log.debug("JSONRPC wallet backend auth: '{user}'/'{stars}'".format(
|
||||||
user=user, stars=('*' * len(password)) if password else ''))
|
user=user, stars=('*' * len(password)) if password else ''))
|
||||||
|
|
||||||
|
def get_height(self):
|
||||||
|
return self.raw_request('getheight')['height']
|
||||||
|
|
||||||
def get_view_key(self):
|
def get_view_key(self):
|
||||||
return self.raw_request('query_key', {'key_type': 'view_key'})['key']
|
return self.raw_request('query_key', {'key_type': 'view_key'})['key']
|
||||||
|
|
||||||
|
@ -167,17 +180,31 @@ class JSONRPCWallet(object):
|
||||||
pmts.append(Payment(**data))
|
pmts.append(Payment(**data))
|
||||||
return pmts
|
return pmts
|
||||||
|
|
||||||
def get_transactions_in(self, account=0):
|
def get_transactions_in(self, account=0, confirmed=True, unconfirmed=False):
|
||||||
_transfers = self.raw_request('get_transfers',
|
_txns = self.raw_request('get_transfers',
|
||||||
{'account_index': account, 'in': True, 'out': False, 'pool': False})
|
{'account_index': account, 'in': confirmed, 'out': False, 'pool': unconfirmed})
|
||||||
|
txns = _txns.get('in', [])
|
||||||
|
if unconfirmed:
|
||||||
|
txns.extend(_txns.get('pool', []))
|
||||||
return [Payment(**self._tx2dict(tx)) for tx in
|
return [Payment(**self._tx2dict(tx)) for tx in
|
||||||
sorted(_transfers.get('in', []), key=operator.itemgetter('timestamp'))]
|
sorted(txns, key=operator.itemgetter('timestamp'))]
|
||||||
|
|
||||||
def get_transactions_out(self, account=0):
|
def get_transactions_out(self, account=0, confirmed=True, unconfirmed=True):
|
||||||
_transfers = self.raw_request('get_transfers',
|
_txns = self.raw_request('get_transfers',
|
||||||
{'account_index': account, 'in': False, 'out': True, 'pool': False})
|
{'account_index': account, 'in': False, 'out': confirmed, 'pool': unconfirmed})
|
||||||
|
txns = _txns.get('out', [])
|
||||||
|
if unconfirmed:
|
||||||
|
txns.extend(_txns.get('pool', []))
|
||||||
return [Transfer(**self._tx2dict(tx)) for tx in
|
return [Transfer(**self._tx2dict(tx)) for tx in
|
||||||
sorted(_transfers.get('out', []), key=operator.itemgetter('timestamp'))]
|
sorted(txns, key=operator.itemgetter('timestamp'))]
|
||||||
|
|
||||||
|
def get_transaction(self, txhash):
|
||||||
|
_tx = self.raw_request('get_transfer_by_txid', {'txid': str(txhash)})['transfer']
|
||||||
|
try:
|
||||||
|
_class = {'in': Payment, 'out': Transfer}[_tx['type']]
|
||||||
|
except KeyError:
|
||||||
|
_class = Transaction
|
||||||
|
return _class(**self._tx2dict(_tx))
|
||||||
|
|
||||||
def _tx2dict(self, tx):
|
def _tx2dict(self, tx):
|
||||||
pid = tx.get('payment_id', None)
|
pid = tx.get('payment_id', None)
|
||||||
|
@ -186,7 +213,7 @@ class JSONRPCWallet(object):
|
||||||
'timestamp': datetime.fromtimestamp(tx['timestamp']) if 'timestamp' in tx else None,
|
'timestamp': datetime.fromtimestamp(tx['timestamp']) if 'timestamp' in tx else None,
|
||||||
'amount': from_atomic(tx['amount']),
|
'amount': from_atomic(tx['amount']),
|
||||||
'fee': from_atomic(tx['fee']) if 'fee' in tx else None,
|
'fee': from_atomic(tx['fee']) if 'fee' in tx else None,
|
||||||
'height': tx.get('height', tx.get('block_height')),
|
'height': tx.get('height', tx.get('block_height')) or None,
|
||||||
'payment_id': None if pid is None else PaymentID(pid),
|
'payment_id': None if pid is None else PaymentID(pid),
|
||||||
'note': tx.get('note'),
|
'note': tx.get('note'),
|
||||||
# NOTE: address will be resolved only after PR#3010 has been merged to Monero
|
# NOTE: address will be resolved only after PR#3010 has been merged to Monero
|
||||||
|
@ -268,6 +295,7 @@ _err2exc = {
|
||||||
-2: exceptions.WrongAddress,
|
-2: exceptions.WrongAddress,
|
||||||
-4: exceptions.NotEnoughUnlockedMoney,
|
-4: exceptions.NotEnoughUnlockedMoney,
|
||||||
-5: exceptions.WrongPaymentId,
|
-5: exceptions.WrongPaymentId,
|
||||||
|
-8: exceptions.TransactionNotFound,
|
||||||
-16: exceptions.TransactionNotPossible,
|
-16: exceptions.TransactionNotPossible,
|
||||||
-17: exceptions.NotEnoughMoney,
|
-17: exceptions.NotEnoughMoney,
|
||||||
-20: exceptions.AmountIsZero,
|
-20: exceptions.AmountIsZero,
|
||||||
|
|
|
@ -5,5 +5,11 @@ class Daemon(object):
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
return self._backend.get_info()
|
return self._backend.get_info()
|
||||||
|
|
||||||
|
def get_height(self):
|
||||||
|
return self._backend.get_info()['height']
|
||||||
|
|
||||||
def send_transaction(self, blob):
|
def send_transaction(self, blob):
|
||||||
return self._backend.send_transaction(blob)
|
return self._backend.send_transaction(blob)
|
||||||
|
|
||||||
|
def get_mempool(self):
|
||||||
|
return self._backend.get_mempool()
|
||||||
|
|
|
@ -30,3 +30,5 @@ class TransactionBroadcastError(BackendException):
|
||||||
self.details = details
|
self.details = details
|
||||||
super(TransactionBroadcastError, self).__init__(message)
|
super(TransactionBroadcastError, self).__init__(message)
|
||||||
|
|
||||||
|
class TransactionNotFound(AccountException):
|
||||||
|
pass
|
||||||
|
|
|
@ -2,37 +2,44 @@ class Transaction(object):
|
||||||
hash = None
|
hash = None
|
||||||
height = None
|
height = None
|
||||||
timestamp = None
|
timestamp = None
|
||||||
payment_id = '0000000000000000'
|
|
||||||
amount = None
|
|
||||||
fee = None
|
fee = None
|
||||||
local_address = None
|
blob = None
|
||||||
|
|
||||||
def __init__(self, hash=None, **kwargs):
|
def __init__(self, hash=None, **kwargs):
|
||||||
self.hash = hash
|
self.hash = hash
|
||||||
self.height = kwargs.get('height', self.height)
|
self.height = kwargs.get('height', self.height)
|
||||||
self.timestamp = kwargs.get('timestamp', self.timestamp)
|
self.timestamp = kwargs.get('timestamp', self.timestamp)
|
||||||
self.payment_id = kwargs.get('payment_id', self.payment_id)
|
|
||||||
self.amount = kwargs.get('amount', self.amount)
|
|
||||||
self.fee = kwargs.get('fee', self.fee)
|
self.fee = kwargs.get('fee', self.fee)
|
||||||
self.local_address = kwargs.get('local_address', self.local_address)
|
self.blob = kwargs.get('blob', self.blob)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return self.hash
|
return self.hash
|
||||||
|
|
||||||
|
|
||||||
class Payment(Transaction):
|
class LocalTransaction(Transaction):
|
||||||
|
"""A transaction that concerns local wallet, either incoming or outgoing."""
|
||||||
|
payment_id = None
|
||||||
|
amount = None
|
||||||
|
local_address = None
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(LocalTransaction, self).__init__(**kwargs)
|
||||||
|
self.payment_id = kwargs.get('payment_id', self.payment_id)
|
||||||
|
self.amount = kwargs.get('amount', self.amount)
|
||||||
|
self.local_address = kwargs.get('local_address', self.local_address)
|
||||||
|
|
||||||
|
|
||||||
|
class Payment(LocalTransaction):
|
||||||
"""Incoming Transaction"""
|
"""Incoming Transaction"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Transfer(Transaction):
|
class Transfer(LocalTransaction):
|
||||||
"""Outgoing Transaction"""
|
"""Outgoing Transaction"""
|
||||||
key = None
|
key = None
|
||||||
blob = None
|
|
||||||
note = ''
|
note = ''
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(Transfer, self).__init__(**kwargs)
|
super(Transfer, self).__init__(**kwargs)
|
||||||
self.key = kwargs.get('key', self.key)
|
self.key = kwargs.get('key', self.key)
|
||||||
self.note = kwargs.get('note', self.note)
|
self.note = kwargs.get('note', self.note)
|
||||||
self.blob = kwargs.get('blob', self.blob)
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from . import address
|
from . import address
|
||||||
from . import prio
|
from . import prio
|
||||||
from . import account
|
from . import account
|
||||||
|
from . import transaction
|
||||||
|
|
||||||
class Wallet(object):
|
class Wallet(object):
|
||||||
accounts = None
|
accounts = None
|
||||||
|
@ -21,6 +22,12 @@ class Wallet(object):
|
||||||
self.accounts.append(_acc)
|
self.accounts.append(_acc)
|
||||||
idx += 1
|
idx += 1
|
||||||
|
|
||||||
|
def get_height(self):
|
||||||
|
"""
|
||||||
|
Returns the height of the wallet.
|
||||||
|
"""
|
||||||
|
return self._backend.get_height()
|
||||||
|
|
||||||
def get_view_key(self):
|
def get_view_key(self):
|
||||||
"""
|
"""
|
||||||
Returns private view key.
|
Returns private view key.
|
||||||
|
@ -39,6 +46,15 @@ class Wallet(object):
|
||||||
self.accounts.append(acc)
|
self.accounts.append(acc)
|
||||||
return 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:
|
||||||
|
return 0
|
||||||
|
return max(0, self.get_height() - txn.height)
|
||||||
|
|
||||||
# Following methods operate on default account (index=0)
|
# Following methods operate on default account (index=0)
|
||||||
def get_balances(self):
|
def get_balances(self):
|
||||||
return self.accounts[0].get_balances()
|
return self.accounts[0].get_balances()
|
||||||
|
@ -58,11 +74,11 @@ class Wallet(object):
|
||||||
def get_payments(self, payment_id=None):
|
def get_payments(self, payment_id=None):
|
||||||
return self.accounts[0].get_payments(payment_id=payment_id)
|
return self.accounts[0].get_payments(payment_id=payment_id)
|
||||||
|
|
||||||
def get_transactions_in(self):
|
def get_transactions_in(self, confirmed=True, unconfirmed=False):
|
||||||
return self.accounts[0].get_transactions_in()
|
return self.accounts[0].get_transactions_in(cofirmed=confirmed, unconfirmed=unconfirmed)
|
||||||
|
|
||||||
def get_transactions_out(self):
|
def get_transactions_out(self, confirmed=True, unconfirmed=True):
|
||||||
return self.accounts[0].get_transactions_out()
|
return self.accounts[0].get_transactions_out(confirmed=confirmed, unconfirmed=unconfirmed)
|
||||||
|
|
||||||
def transfer(self, address, amount,
|
def transfer(self, address, amount,
|
||||||
priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0,
|
priority=prio.NORMAL, ringsize=5, payment_id=None, unlock_time=0,
|
||||||
|
|
|
@ -36,9 +36,9 @@ _TXHDR = "timestamp height id/hash
|
||||||
" amount fee {dir:95s} payment_id"
|
" amount fee {dir:95s} payment_id"
|
||||||
|
|
||||||
def tx2str(tx):
|
def tx2str(tx):
|
||||||
return "{time} {height} {hash} {amount:17.12f} {fee:13.12f} {addr} {payment_id}".format(
|
return "{time} {height:7d} {hash} {amount:17.12f} {fee:13.12f} {addr} {payment_id}".format(
|
||||||
time=tx.timestamp.strftime("%d-%m-%y %H:%M:%S") if getattr(tx, 'timestamp', None) else None,
|
time=tx.timestamp.strftime("%d-%m-%y %H:%M:%S") if getattr(tx, 'timestamp', None) else None,
|
||||||
height=tx.height,
|
height=tx.height or 0,
|
||||||
hash=tx.hash,
|
hash=tx.hash,
|
||||||
amount=tx.amount,
|
amount=tx.amount,
|
||||||
fee=tx.fee or 0,
|
fee=tx.fee or 0,
|
||||||
|
@ -80,26 +80,26 @@ if len(w.accounts) > 1:
|
||||||
addresses = acc.get_addresses()
|
addresses = acc.get_addresses()
|
||||||
print("{num:2d} address(es):".format(num=len(addresses)))
|
print("{num:2d} address(es):".format(num=len(addresses)))
|
||||||
print("\n".join(map(a2str, addresses)))
|
print("\n".join(map(a2str, addresses)))
|
||||||
ins = acc.get_transactions_in()
|
ins = acc.get_transactions_in(unconfirmed=True)
|
||||||
if ins:
|
if ins:
|
||||||
print("\nIncoming transactions:")
|
print("\nIncoming transactions:")
|
||||||
print(_TXHDR.format(dir='received by'))
|
print(_TXHDR.format(dir='received by'))
|
||||||
for tx in ins:
|
for tx in ins:
|
||||||
print(tx2str(tx))
|
print(tx2str(tx))
|
||||||
outs = acc.get_transactions_out()
|
outs = acc.get_transactions_out(unconfirmed=True)
|
||||||
if outs:
|
if outs:
|
||||||
print("\nOutgoing transactions:")
|
print("\nOutgoing transactions:")
|
||||||
print(_TXHDR.format(dir='sent from'))
|
print(_TXHDR.format(dir='sent from'))
|
||||||
for tx in outs:
|
for tx in outs:
|
||||||
print(tx2str(tx))
|
print(tx2str(tx))
|
||||||
else:
|
else:
|
||||||
ins = w.get_transactions_in()
|
ins = w.get_transactions_in(unconfirmed=True)
|
||||||
if ins:
|
if ins:
|
||||||
print("\nIncoming transactions:")
|
print("\nIncoming transactions:")
|
||||||
print(_TXHDR.format(dir='received by'))
|
print(_TXHDR.format(dir='received by'))
|
||||||
for tx in ins:
|
for tx in ins:
|
||||||
print(tx2str(tx))
|
print(tx2str(tx))
|
||||||
outs = w.get_transactions_out()
|
outs = w.get_transactions_out(unconfirmed=True)
|
||||||
if outs:
|
if outs:
|
||||||
print("\nOutgoing transactions:")
|
print("\nOutgoing transactions:")
|
||||||
print(_TXHDR.format(dir='sent from'))
|
print(_TXHDR.format(dir='sent from'))
|
||||||
|
|
Loading…
Reference in a new issue