wownero-python/monero/numbers.py

72 lines
2.3 KiB
Python
Raw Normal View History

2017-11-25 22:59:32 +00:00
from decimal import Decimal
2017-12-27 00:49:59 +00:00
import sys
2017-11-25 22:59:32 +00:00
PICONERO = Decimal('0.000000000001')
2017-12-27 00:49:59 +00:00
if sys.version_info < (3,):
_integer_types = (int, long,)
2018-01-06 22:12:42 +00:00
_str_types = (str, bytes, unicode)
2017-12-27 00:49:59 +00:00
else:
_integer_types = (int,)
2018-01-06 22:12:42 +00:00
_str_types = (str, bytes)
2017-12-27 00:49:59 +00:00
2017-11-25 22:59:32 +00:00
def to_atomic(amount):
2017-11-29 03:38:29 +00:00
"""Convert Monero decimal to atomic integer of piconero."""
2017-11-25 22:59:32 +00:00
return int(amount * 10**12)
def from_atomic(amount):
2017-11-29 03:38:29 +00:00
"""Convert atomic integer of piconero to Monero decimal."""
2017-11-25 22:59:32 +00:00
return (Decimal(amount) * PICONERO).quantize(PICONERO)
2017-11-29 03:38:29 +00:00
def as_monero(amount):
"""Return the amount rounded to maximal Monero precision."""
return Decimal(amount).quantize(PICONERO)
2017-12-27 00:49:59 +00:00
2018-01-06 22:12:42 +00:00
class PaymentID(object):
"""
A class that validates Monero payment ID.
Payment IDs can be used as str or int across the module, however this class
offers validation as well as simple conversion and comparison to those two
primitive types.
:param payment_id: the payment ID as integer or hexadecimal string
"""
2018-01-06 22:12:42 +00:00
_payment_id = None
def __init__(self, payment_id):
if isinstance(payment_id, PaymentID):
payment_id = int(payment_id)
if isinstance(payment_id, _str_types):
payment_id = int(payment_id, 16)
elif not isinstance(payment_id, _integer_types):
raise TypeError("payment_id must be either int or hexadecimal str or bytes, "
2018-01-07 00:26:30 +00:00
"is {0}".format(type(payment_id)))
if payment_id.bit_length() > 256:
raise ValueError("payment_id {0} is more than 256 bits long".format(payment_id))
2018-01-06 22:12:42 +00:00
self._payment_id = payment_id
def is_short(self):
"""Returns True if payment ID is short enough to be included
in :class:`IntegratedAddress <monero.address.IntegratedAddress>`."""
2018-01-06 22:12:42 +00:00
return self._payment_id.bit_length() <= 64
def __repr__(self):
if self.is_short():
return "{:016x}".format(self._payment_id)
return "{:064x}".format(self._payment_id)
def __int__(self):
return self._payment_id
def __eq__(self, other):
if isinstance(other, PaymentID):
return int(self) == int(other)
elif isinstance(other, _integer_types):
return int(self) == other
elif isinstance(other, _str_types):
return str(self) == other
2018-01-30 08:43:08 +00:00
return super(PaymentID, self).__eq__(other)