mirror of
https://git.wownero.com/lza_menace/wownero-python.git
synced 2024-08-15 03:25:25 +00:00
Introduce monero.const, simplify net check methods and deprecate old API
This commit is contained in:
parent
e7897f72bd
commit
6e410d9624
11 changed files with 130 additions and 72 deletions
|
@ -1,3 +1,3 @@
|
|||
from . import address, account, daemon, wallet, numbers, prio, wordlists, seed
|
||||
from . import address, account, const, daemon, wallet, numbers, wordlists, seed
|
||||
|
||||
__version__ = '0.7'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from . import prio
|
||||
from . import const
|
||||
from .transaction import PaymentManager
|
||||
|
||||
|
||||
|
@ -70,7 +70,7 @@ class Account(object):
|
|||
return self._backend.new_address(account=self.index, label=label)
|
||||
|
||||
def transfer(self, address, amount,
|
||||
priority=prio.NORMAL, payment_id=None, unlock_time=0,
|
||||
priority=const.PRIO_NORMAL, payment_id=None, unlock_time=0,
|
||||
relay=True):
|
||||
"""
|
||||
Sends a transfer. Returns a list of resulting transactions.
|
||||
|
@ -79,7 +79,7 @@ class Account(object):
|
|||
:param amount: amount to send
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as the destination)
|
||||
|
@ -98,7 +98,7 @@ class Account(object):
|
|||
relay=relay)
|
||||
|
||||
def transfer_multiple(self, destinations,
|
||||
priority=prio.NORMAL, payment_id=None, unlock_time=0,
|
||||
priority=const.PRIO_NORMAL, payment_id=None, unlock_time=0,
|
||||
relay=True):
|
||||
"""
|
||||
Sends a batch of transfers. Returns a list of resulting transactions.
|
||||
|
@ -107,7 +107,7 @@ class Account(object):
|
|||
[(:class:`Address <monero.address.Address>`, `Decimal`), ...]
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as the destination)
|
||||
|
@ -126,7 +126,7 @@ class Account(object):
|
|||
account=self.index,
|
||||
relay=relay)
|
||||
|
||||
def sweep_all(self, address, priority=prio.NORMAL, payment_id=None,
|
||||
def sweep_all(self, address, priority=const.PRIO_NORMAL, payment_id=None,
|
||||
subaddr_indices=None, unlock_time=0, relay=True):
|
||||
"""
|
||||
Sends all unlocked balance to an address. Returns a list of resulting transactions.
|
||||
|
@ -134,7 +134,7 @@ class Account(object):
|
|||
:param address: destination :class:`Address <monero.address.Address>` or subtype
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as the destination)
|
||||
|
|
|
@ -3,8 +3,10 @@ import re
|
|||
from sha3 import keccak_256
|
||||
import six
|
||||
import struct
|
||||
import warnings
|
||||
|
||||
from . import base58
|
||||
from . import const
|
||||
from . import ed25519
|
||||
from . import numbers
|
||||
|
||||
|
@ -36,26 +38,42 @@ class BaseAddress(object):
|
|||
"""
|
||||
return hexlify(self._decoded[1:33]).decode()
|
||||
|
||||
@property
|
||||
def net(self):
|
||||
return const.NETS[self._valid_netbytes.index(self._decoded[0])]
|
||||
|
||||
def is_mainnet(self):
|
||||
"""Returns `True` if the address belongs to mainnet.
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._decoded[0] == self._valid_netbytes[0]
|
||||
warnings.warn(".is_mainnet(), .is_testnet() and .is_stagenet() methods are deprecated "
|
||||
"and will be gone in 0.8; use Address.net property and constants form monero.const "
|
||||
"instead",
|
||||
DeprecationWarning)
|
||||
return self.net == const.NET_MAIN
|
||||
|
||||
def is_testnet(self):
|
||||
"""Returns `True` if the address belongs to testnet.
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._decoded[0] == self._valid_netbytes[1]
|
||||
warnings.warn(".is_mainnet(), .is_testnet() and .is_stagenet() methods are deprecated "
|
||||
"and will be gone in 0.8; use Address.net property and constants form monero.const "
|
||||
"instead",
|
||||
DeprecationWarning)
|
||||
return self.net == const.NET_TEST
|
||||
|
||||
def is_stagenet(self):
|
||||
"""Returns `True` if the address belongs to stagenet.
|
||||
|
||||
:rtype: bool
|
||||
"""
|
||||
return self._decoded[0] == self._valid_netbytes[2]
|
||||
warnings.warn(".is_mainnet(), .is_testnet() and .is_stagenet() methods are deprecated "
|
||||
"and will be gone in 0.8; use Address.net property and constants form monero.const "
|
||||
"instead",
|
||||
DeprecationWarning)
|
||||
return self.net == const.NET_STAGE
|
||||
|
||||
def _decode(self, address):
|
||||
self._decoded = bytearray(unhexlify(base58.decode(address)))
|
||||
|
@ -92,8 +110,7 @@ class Address(BaseAddress):
|
|||
:param address: a Monero address as string-like object
|
||||
:param label: a label for the address (defaults to `None`)
|
||||
"""
|
||||
_valid_netbytes = (18, 53, 24)
|
||||
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
|
||||
_valid_netbytes = const.MASTERADDR_NETBYTES
|
||||
|
||||
def check_private_view_key(self, key):
|
||||
"""Checks if private view key matches this address.
|
||||
|
@ -121,7 +138,7 @@ class Address(BaseAddress):
|
|||
payment_id = numbers.PaymentID(payment_id)
|
||||
if not payment_id.is_short():
|
||||
raise TypeError("Payment ID {0} has more than 64 bits and cannot be integrated".format(payment_id))
|
||||
prefix = 54 if self.is_testnet() else 25 if self.is_stagenet() else 19
|
||||
prefix = const.INTADDRR_NETBYTES[const.NETS.index(self.net)]
|
||||
data = bytearray([prefix]) + self._decoded[1:65] + struct.pack('>Q', int(payment_id))
|
||||
checksum = bytearray(keccak_256(data).digest()[:4])
|
||||
return IntegratedAddress(base58.encode(hexlify(data + checksum)))
|
||||
|
@ -133,8 +150,7 @@ class SubAddress(BaseAddress):
|
|||
Any type of address which is not the master one for a wallet.
|
||||
"""
|
||||
|
||||
_valid_netbytes = (42, 63, 36)
|
||||
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
|
||||
_valid_netbytes = const.SUBADDR_NETBYTES
|
||||
|
||||
def with_payment_id(self, _):
|
||||
raise TypeError("SubAddress cannot be integrated with payment ID")
|
||||
|
@ -146,8 +162,7 @@ class IntegratedAddress(Address):
|
|||
A master address integrated with payment id (short one, max 64 bit).
|
||||
"""
|
||||
|
||||
_valid_netbytes = (19, 54, 25)
|
||||
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
|
||||
_valid_netbytes = const.INTADDRR_NETBYTES
|
||||
|
||||
def __init__(self, address):
|
||||
address = address.decode() if isinstance(address, bytes) else str(address)
|
||||
|
@ -167,7 +182,7 @@ class IntegratedAddress(Address):
|
|||
"""Returns the base address without payment id.
|
||||
:rtype: :class:`Address`
|
||||
"""
|
||||
prefix = 53 if self.is_testnet() else 24 if self.is_stagenet() else 18
|
||||
prefix = const.MASTERADDR_NETBYTES[const.NETS.index(self.net)]
|
||||
data = bytearray([prefix]) + self._decoded[1:65]
|
||||
checksum = keccak_256(data).digest()[:4]
|
||||
return Address(base58.encode(hexlify(data + checksum)))
|
||||
|
|
13
monero/const.py
Normal file
13
monero/const.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
NET_MAIN = "main"
|
||||
NET_STAGE = "stage"
|
||||
NET_TEST = "test"
|
||||
|
||||
NETS = (NET_MAIN, NET_TEST, NET_STAGE)
|
||||
MASTERADDR_NETBYTES = (18, 53, 24)
|
||||
SUBADDR_NETBYTES = (42, 63, 36)
|
||||
INTADDRR_NETBYTES = (19, 54, 25)
|
||||
|
||||
PRIO_UNIMPORTANT = 1
|
||||
PRIO_NORMAL = 2
|
||||
PRIO_ELEVATED = 3
|
||||
PRIO_PRIORITY = 4
|
|
@ -1,3 +1,8 @@
|
|||
import warnings
|
||||
warnings.warn(
|
||||
"monero.prio is deprecated and will be gone in 0.8; use monero.const.PRIO_* consts instead",
|
||||
DeprecationWarning)
|
||||
|
||||
UNIMPORTANT=1
|
||||
NORMAL=2
|
||||
ELEVATED=3
|
||||
|
|
|
@ -35,13 +35,12 @@
|
|||
# + simplified interface, changed exceptions (assertions -> explicit raise)
|
||||
# + optimization
|
||||
|
||||
from monero import wordlists
|
||||
from monero import ed25519
|
||||
from monero import base58
|
||||
from monero.address import address
|
||||
from binascii import hexlify, unhexlify
|
||||
from os import urandom
|
||||
from sha3 import keccak_256
|
||||
import warnings
|
||||
from . import base58, const, ed25519, wordlists
|
||||
from .address import address
|
||||
|
||||
class Seed(object):
|
||||
"""Creates a seed object either from local system randomness or an imported phrase.
|
||||
|
@ -151,17 +150,25 @@ class Seed(object):
|
|||
self._ed_pub_view_key = ed25519.public_from_secret_hex(self.secret_view_key())
|
||||
return self._ed_pub_view_key
|
||||
|
||||
def public_address(self, net='mainnet'):
|
||||
def public_address(self, net=const.NET_MAIN):
|
||||
"""Returns the master :class:`Address <monero.address.Address>` represented by the seed.
|
||||
|
||||
:param net: the network, one of 'mainnet', 'testnet', 'stagenet'. Default is 'mainnet'.
|
||||
:param net: the network, one of `const.NET_*`; default is `const.NET_MAIN`
|
||||
|
||||
:rtype: :class:`Address <monero.address.Address>`
|
||||
"""
|
||||
if net not in ('mainnet', 'testnet', 'stagenet'):
|
||||
# backward compatibility
|
||||
_net = net[:-3] if net.endswith('net') else net
|
||||
if _net != net:
|
||||
warnings.warn(
|
||||
"Argument '{:s}' is deprecated and will not be accepted in 0.8, "
|
||||
"use one of monero.const.NET_*".format(net),
|
||||
DeprecationWarning)
|
||||
net = _net
|
||||
if net not in const.NETS:
|
||||
raise ValueError(
|
||||
"Invalid net argument. Must be one of ('mainnet', 'testnet', 'stagenet').")
|
||||
netbyte = 18 if net == 'mainnet' else 53 if net == 'testnet' else 24
|
||||
"Invalid net argument '{:s}'. Must be one of monero.const.NET_*".format(net))
|
||||
netbyte = (18, 53, 24)[const.NETS.index(net)]
|
||||
data = "{:x}{:s}{:s}".format(netbyte, self.public_spend_key(), self.public_view_key())
|
||||
h = keccak_256()
|
||||
h.update(unhexlify(data))
|
||||
|
|
|
@ -4,9 +4,9 @@ import struct
|
|||
|
||||
from . import address
|
||||
from . import base58
|
||||
from . import const
|
||||
from . import ed25519
|
||||
from . import numbers
|
||||
from . import prio
|
||||
from .transaction import Payment, PaymentManager
|
||||
|
||||
|
||||
|
@ -224,15 +224,13 @@ class Wallet(object):
|
|||
ed25519.scalarmult_B(ed25519.decodeint(m)))
|
||||
# C = master_svk * D
|
||||
C = ed25519.scalarmult(D, ed25519.decodeint(master_svk))
|
||||
netbyte = bytearray([
|
||||
42 if master_address.is_mainnet() else \
|
||||
63 if master_address.is_testnet() else 36])
|
||||
netbyte = bytearray([const.SUBADDR_NETBYTES[const.NETS.index(master_address.net)]])
|
||||
data = netbyte + ed25519.encodepoint(D) + ed25519.encodepoint(C)
|
||||
checksum = keccak_256(data).digest()[:4]
|
||||
return address.SubAddress(base58.encode(hexlify(data + checksum)))
|
||||
|
||||
def transfer(self, address, amount,
|
||||
priority=prio.NORMAL, payment_id=None, unlock_time=0,
|
||||
priority=const.PRIO_NORMAL, payment_id=None, unlock_time=0,
|
||||
relay=True):
|
||||
"""
|
||||
Sends a transfer from the default account. Returns a list of resulting transactions.
|
||||
|
@ -241,7 +239,7 @@ class Wallet(object):
|
|||
:param amount: amount to send
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as the destination)
|
||||
|
@ -260,7 +258,7 @@ class Wallet(object):
|
|||
relay=relay)
|
||||
|
||||
def transfer_multiple(self, destinations,
|
||||
priority=prio.NORMAL, payment_id=None, unlock_time=0,
|
||||
priority=const.PRIO_NORMAL, payment_id=None, unlock_time=0,
|
||||
relay=True):
|
||||
"""
|
||||
Sends a batch of transfers from the default account. Returns a list of resulting
|
||||
|
@ -269,7 +267,7 @@ class Wallet(object):
|
|||
:param destinations: a list of destination and amount pairs: [(address, amount), ...]
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as a destination)
|
||||
|
@ -287,7 +285,7 @@ class Wallet(object):
|
|||
unlock_time=unlock_time,
|
||||
relay=relay)
|
||||
|
||||
def sweep_all(self, address, priority=prio.NORMAL, payment_id=None,
|
||||
def sweep_all(self, address, priority=const.PRIO_NORMAL, payment_id=None,
|
||||
subaddr_indices=None, unlock_time=0, relay=True):
|
||||
"""
|
||||
Sends all unlocked balance from the default account to an address.
|
||||
|
@ -296,7 +294,7 @@ class Wallet(object):
|
|||
:param address: destination :class:`Address <monero.address.Address>` or subtype
|
||||
: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`.
|
||||
from `monero.const.PRIO_*`.
|
||||
:param payment_id: ID for the payment (must be None if
|
||||
:class:`IntegratedAddress <monero.address.IntegratedAddress>`
|
||||
is used as the destination)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue