Introduce monero.const, simplify net check methods and deprecate old API

This commit is contained in:
Michał Sałaban 2020-01-13 11:37:53 +01:00
parent e7897f72bd
commit 6e410d9624
11 changed files with 130 additions and 72 deletions

View File

@ -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' __version__ = '0.7'

View File

@ -1,4 +1,4 @@
from . import prio from . import const
from .transaction import PaymentManager from .transaction import PaymentManager
@ -70,7 +70,7 @@ class Account(object):
return self._backend.new_address(account=self.index, label=label) return self._backend.new_address(account=self.index, label=label)
def transfer(self, address, amount, 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): relay=True):
""" """
Sends a transfer. Returns a list of resulting transactions. Sends a transfer. Returns a list of resulting transactions.
@ -79,7 +79,7 @@ class Account(object):
:param amount: amount to send :param amount: amount to send
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination) is used as the destination)
@ -98,7 +98,7 @@ class Account(object):
relay=relay) relay=relay)
def transfer_multiple(self, destinations, 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): relay=True):
""" """
Sends a batch of transfers. Returns a list of resulting transactions. Sends a batch of transfers. Returns a list of resulting transactions.
@ -107,7 +107,7 @@ class Account(object):
[(:class:`Address <monero.address.Address>`, `Decimal`), ...] [(:class:`Address <monero.address.Address>`, `Decimal`), ...]
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination) is used as the destination)
@ -126,7 +126,7 @@ class Account(object):
account=self.index, account=self.index,
relay=relay) 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): subaddr_indices=None, unlock_time=0, relay=True):
""" """
Sends all unlocked balance to an address. Returns a list of resulting transactions. 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 address: destination :class:`Address <monero.address.Address>` or subtype
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination) is used as the destination)

View File

@ -3,8 +3,10 @@ import re
from sha3 import keccak_256 from sha3 import keccak_256
import six import six
import struct import struct
import warnings
from . import base58 from . import base58
from . import const
from . import ed25519 from . import ed25519
from . import numbers from . import numbers
@ -36,26 +38,42 @@ class BaseAddress(object):
""" """
return hexlify(self._decoded[1:33]).decode() 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): def is_mainnet(self):
"""Returns `True` if the address belongs to mainnet. """Returns `True` if the address belongs to mainnet.
:rtype: bool :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): def is_testnet(self):
"""Returns `True` if the address belongs to testnet. """Returns `True` if the address belongs to testnet.
:rtype: bool :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): def is_stagenet(self):
"""Returns `True` if the address belongs to stagenet. """Returns `True` if the address belongs to stagenet.
:rtype: bool :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): def _decode(self, address):
self._decoded = bytearray(unhexlify(base58.decode(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 address: a Monero address as string-like object
:param label: a label for the address (defaults to `None`) :param label: a label for the address (defaults to `None`)
""" """
_valid_netbytes = (18, 53, 24) _valid_netbytes = const.MASTERADDR_NETBYTES
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
def check_private_view_key(self, key): def check_private_view_key(self, key):
"""Checks if private view key matches this address. """Checks if private view key matches this address.
@ -121,7 +138,7 @@ class Address(BaseAddress):
payment_id = numbers.PaymentID(payment_id) payment_id = numbers.PaymentID(payment_id)
if not payment_id.is_short(): if not payment_id.is_short():
raise TypeError("Payment ID {0} has more than 64 bits and cannot be integrated".format(payment_id)) 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)) data = bytearray([prefix]) + self._decoded[1:65] + struct.pack('>Q', int(payment_id))
checksum = bytearray(keccak_256(data).digest()[:4]) checksum = bytearray(keccak_256(data).digest()[:4])
return IntegratedAddress(base58.encode(hexlify(data + checksum))) 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. Any type of address which is not the master one for a wallet.
""" """
_valid_netbytes = (42, 63, 36) _valid_netbytes = const.SUBADDR_NETBYTES
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
def with_payment_id(self, _): def with_payment_id(self, _):
raise TypeError("SubAddress cannot be integrated with payment ID") 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). A master address integrated with payment id (short one, max 64 bit).
""" """
_valid_netbytes = (19, 54, 25) _valid_netbytes = const.INTADDRR_NETBYTES
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
def __init__(self, address): def __init__(self, address):
address = address.decode() if isinstance(address, bytes) else str(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. """Returns the base address without payment id.
:rtype: :class:`Address` :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] data = bytearray([prefix]) + self._decoded[1:65]
checksum = keccak_256(data).digest()[:4] checksum = keccak_256(data).digest()[:4]
return Address(base58.encode(hexlify(data + checksum))) return Address(base58.encode(hexlify(data + checksum)))

13
monero/const.py Normal file
View 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

View File

@ -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 UNIMPORTANT=1
NORMAL=2 NORMAL=2
ELEVATED=3 ELEVATED=3

View File

@ -35,13 +35,12 @@
# + simplified interface, changed exceptions (assertions -> explicit raise) # + simplified interface, changed exceptions (assertions -> explicit raise)
# + optimization # + optimization
from monero import wordlists
from monero import ed25519
from monero import base58
from monero.address import address
from binascii import hexlify, unhexlify from binascii import hexlify, unhexlify
from os import urandom from os import urandom
from sha3 import keccak_256 from sha3 import keccak_256
import warnings
from . import base58, const, ed25519, wordlists
from .address import address
class Seed(object): class Seed(object):
"""Creates a seed object either from local system randomness or an imported phrase. """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()) self._ed_pub_view_key = ed25519.public_from_secret_hex(self.secret_view_key())
return self._ed_pub_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. """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>` :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( raise ValueError(
"Invalid net argument. Must be one of ('mainnet', 'testnet', 'stagenet').") "Invalid net argument '{:s}'. Must be one of monero.const.NET_*".format(net))
netbyte = 18 if net == 'mainnet' else 53 if net == 'testnet' else 24 netbyte = (18, 53, 24)[const.NETS.index(net)]
data = "{:x}{:s}{:s}".format(netbyte, self.public_spend_key(), self.public_view_key()) data = "{:x}{:s}{:s}".format(netbyte, self.public_spend_key(), self.public_view_key())
h = keccak_256() h = keccak_256()
h.update(unhexlify(data)) h.update(unhexlify(data))

View File

@ -4,9 +4,9 @@ import struct
from . import address from . import address
from . import base58 from . import base58
from . import const
from . import ed25519 from . import ed25519
from . import numbers from . import numbers
from . import prio
from .transaction import Payment, PaymentManager from .transaction import Payment, PaymentManager
@ -224,15 +224,13 @@ class Wallet(object):
ed25519.scalarmult_B(ed25519.decodeint(m))) ed25519.scalarmult_B(ed25519.decodeint(m)))
# C = master_svk * D # C = master_svk * D
C = ed25519.scalarmult(D, ed25519.decodeint(master_svk)) C = ed25519.scalarmult(D, ed25519.decodeint(master_svk))
netbyte = bytearray([ netbyte = bytearray([const.SUBADDR_NETBYTES[const.NETS.index(master_address.net)]])
42 if master_address.is_mainnet() else \
63 if master_address.is_testnet() else 36])
data = netbyte + ed25519.encodepoint(D) + ed25519.encodepoint(C) data = netbyte + ed25519.encodepoint(D) + ed25519.encodepoint(C)
checksum = keccak_256(data).digest()[:4] checksum = keccak_256(data).digest()[:4]
return address.SubAddress(base58.encode(hexlify(data + checksum))) return address.SubAddress(base58.encode(hexlify(data + checksum)))
def transfer(self, address, amount, 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): relay=True):
""" """
Sends a transfer from the default account. Returns a list of resulting transactions. 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 amount: amount to send
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination) is used as the destination)
@ -260,7 +258,7 @@ class Wallet(object):
relay=relay) relay=relay)
def transfer_multiple(self, destinations, 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): relay=True):
""" """
Sends a batch of transfers from the default account. Returns a list of resulting 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 destinations: a list of destination and amount pairs: [(address, amount), ...]
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as a destination) is used as a destination)
@ -287,7 +285,7 @@ class Wallet(object):
unlock_time=unlock_time, unlock_time=unlock_time,
relay=relay) 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): subaddr_indices=None, unlock_time=0, relay=True):
""" """
Sends all unlocked balance from the default account to an address. 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 address: destination :class:`Address <monero.address.Address>` or subtype
:param priority: transaction priority, implies fee. The priority can be a number :param priority: transaction priority, implies fee. The priority can be a number
from 1 to 4 (unimportant, normal, elevated, priority) or a constant 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 :param payment_id: ID for the payment (must be None if
:class:`IntegratedAddress <monero.address.IntegratedAddress>` :class:`IntegratedAddress <monero.address.IntegratedAddress>`
is used as the destination) is used as the destination)

View File

@ -1,7 +1,7 @@
import json import pytest
import os
import unittest import unittest
from monero import const
from monero.address import Address, SubAddress, IntegratedAddress, address from monero.address import Address, SubAddress, IntegratedAddress, address
from tests.utils import classproperty from tests.utils import classproperty
@ -50,6 +50,7 @@ class Tests(object):
self.assertEqual(ia.payment_id(), self.pid) self.assertEqual(ia.payment_id(), self.pid)
self.assertEqual(str(ia), self.iaddr) self.assertEqual(str(ia), self.iaddr)
@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_recognition_and_comparisons(self): def test_recognition_and_comparisons(self):
a = Address(self.addr) a = Address(self.addr)
a2 = address(self.addr) a2 = address(self.addr)
@ -58,12 +59,20 @@ class Tests(object):
self.assertEqual(a, self.addr) self.assertEqual(a, self.addr)
self.assertEqual(self.addr, a) self.assertEqual(self.addr, a)
self.assertEqual(hash(a), hash(self.addr)) self.assertEqual(hash(a), hash(self.addr))
self.assertEqual(a.is_mainnet(), self.mainnet) self.assertEqual(a.net, self.net)
self.assertEqual(a.is_testnet(), self.testnet) with pytest.deprecated_call():
self.assertEqual(a.is_stagenet(), self.stagenet) self.assertEqual(a.is_mainnet(), self.net == const.NET_MAIN)
self.assertEqual(a2.is_mainnet(), self.mainnet) with pytest.deprecated_call():
self.assertEqual(a2.is_testnet(), self.testnet) self.assertEqual(a.is_testnet(), self.net == const.NET_TEST)
self.assertEqual(a2.is_stagenet(), self.stagenet) with pytest.deprecated_call():
self.assertEqual(a.is_stagenet(), self.net == const.NET_STAGE)
self.assertEqual(a2.net, self.net)
with pytest.deprecated_call():
self.assertEqual(a2.is_mainnet(), self.net == const.NET_MAIN)
with pytest.deprecated_call():
self.assertEqual(a2.is_testnet(), self.net == const.NET_TEST)
with pytest.deprecated_call():
self.assertEqual(a2.is_stagenet(), self.net == const.NET_STAGE)
ia = IntegratedAddress(self.iaddr) ia = IntegratedAddress(self.iaddr)
ia2 = address(self.iaddr) ia2 = address(self.iaddr)
@ -72,12 +81,20 @@ class Tests(object):
self.assertEqual(ia, self.iaddr) self.assertEqual(ia, self.iaddr)
self.assertEqual(self.iaddr, ia) self.assertEqual(self.iaddr, ia)
self.assertEqual(hash(ia), hash(self.iaddr)) self.assertEqual(hash(ia), hash(self.iaddr))
self.assertEqual(ia.is_mainnet(), self.mainnet) self.assertEqual(ia.net, self.net)
self.assertEqual(ia.is_testnet(), self.testnet) with pytest.deprecated_call():
self.assertEqual(ia.is_stagenet(), self.stagenet) self.assertEqual(ia.is_mainnet(), self.net == const.NET_MAIN)
self.assertEqual(ia2.is_mainnet(), self.mainnet) with pytest.deprecated_call():
self.assertEqual(ia2.is_testnet(), self.testnet) self.assertEqual(ia.is_testnet(), self.net == const.NET_TEST)
self.assertEqual(ia2.is_stagenet(), self.stagenet) with pytest.deprecated_call():
self.assertEqual(ia.is_stagenet(), self.net == const.NET_STAGE)
self.assertEqual(ia2.net, self.net)
with pytest.deprecated_call():
self.assertEqual(ia2.is_mainnet(), self.net == const.NET_MAIN)
with pytest.deprecated_call():
self.assertEqual(ia2.is_testnet(), self.net == const.NET_TEST)
with pytest.deprecated_call():
self.assertEqual(ia2.is_stagenet(), self.net == const.NET_STAGE)
self.assertEqual(ia2.base_address(), a) self.assertEqual(ia2.base_address(), a)
self.assertEqual(ia.view_key(), a.view_key()) self.assertEqual(ia.view_key(), a.view_key())
@ -90,12 +107,20 @@ class Tests(object):
self.assertEqual(sa, self.subaddr) self.assertEqual(sa, self.subaddr)
self.assertEqual(self.subaddr, sa) self.assertEqual(self.subaddr, sa)
self.assertEqual(hash(sa), hash(self.subaddr)) self.assertEqual(hash(sa), hash(self.subaddr))
self.assertEqual(sa.is_mainnet(), self.mainnet) self.assertEqual(sa.net, self.net)
self.assertEqual(sa.is_testnet(), self.testnet) with pytest.deprecated_call():
self.assertEqual(sa.is_stagenet(), self.stagenet) self.assertEqual(sa.is_mainnet(), self.net == const.NET_MAIN)
self.assertEqual(sa2.is_mainnet(), self.mainnet) with pytest.deprecated_call():
self.assertEqual(sa2.is_testnet(), self.testnet) self.assertEqual(sa.is_testnet(), self.net == const.NET_TEST)
self.assertEqual(sa2.is_stagenet(), self.stagenet) with pytest.deprecated_call():
self.assertEqual(sa.is_stagenet(), self.net == const.NET_STAGE)
self.assertEqual(sa2.net, self.net)
with pytest.deprecated_call():
self.assertEqual(sa2.is_mainnet(), self.net == const.NET_MAIN)
with pytest.deprecated_call():
self.assertEqual(sa2.is_testnet(), self.net == const.NET_TEST)
with pytest.deprecated_call():
self.assertEqual(sa2.is_stagenet(), self.net == const.NET_STAGE)
self.assertNotEqual(a, 0) self.assertNotEqual(a, 0)
@ -177,9 +202,7 @@ class AddressTestCase(Tests, unittest.TestCase):
pid = '4a6f686e47616c74' pid = '4a6f686e47616c74'
iaddr = '4HMcpBpe4ddJEEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8M7yKhzQhKW3ECCLWQw' iaddr = '4HMcpBpe4ddJEEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8M7yKhzQhKW3ECCLWQw'
subaddr = '84LooD7i35SFppgf4tQ453Vi3q5WexSUXaVgut69ro8MFnmHwuezAArEZTZyLr9fS6QotjqkSAxSF6d1aDgsPoX849izJ7m' subaddr = '84LooD7i35SFppgf4tQ453Vi3q5WexSUXaVgut69ro8MFnmHwuezAArEZTZyLr9fS6QotjqkSAxSF6d1aDgsPoX849izJ7m'
mainnet = True net = const.NET_MAIN
testnet = False
stagenet = False
addr_invalid = '47ewoP19TN7JCEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8Ebsmgef' addr_invalid = '47ewoP19TN7JCEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8Ebsmgef'
iaddr_invalid = '4HMcpBpe4ddJEEnFKUJHAYhGxkyTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8M7yKhzQhKW3ECCLWQw' iaddr_invalid = '4HMcpBpe4ddJEEnFKUJHAYhGxkyTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8M7yKhzQhKW3ECCLWQw'
@ -193,9 +216,7 @@ class TestnetAddressTestCase(Tests, unittest.TestCase):
pid = '4a6f686e47616c74' pid = '4a6f686e47616c74'
subaddr = 'BaU3yLuDqdcETYzeF7vFSVEKNR4sSGxBV1Evrw5yNBf2VMiuAwfDmiF3RHqLHkaA5A6RGiNNRUqvtaqhMtdjA1SQ1tnQV8D' subaddr = 'BaU3yLuDqdcETYzeF7vFSVEKNR4sSGxBV1Evrw5yNBf2VMiuAwfDmiF3RHqLHkaA5A6RGiNNRUqvtaqhMtdjA1SQ1tnQV8D'
iaddr = 'A7bzU6hSszTEsMp2fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwZqGSmLeBXqMEBnZVkh' iaddr = 'A7bzU6hSszTEsMp2fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwZqGSmLeBXqMEBnZVkh'
mainnet = False net = const.NET_TEST
testnet = True
stagenet = False
addr_invalid = '9wuKTHsxGiwEsMp3fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwP7hMs5N' addr_invalid = '9wuKTHsxGiwEsMp3fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwP7hMs5N'
iaddr_invalid = 'A7bzU6hSszTEsMp2fYzJiVahyhU2aZi2oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwZqGSmLeBXqMEBnZVkh' iaddr_invalid = 'A7bzU6hSszTEsMp2fYzJiVahyhU2aZi2oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwZqGSmLeBXqMEBnZVkh'
@ -209,9 +230,7 @@ class StagenetAddressTestCase(Tests, unittest.TestCase):
pid = '4a6f686e47616c74' pid = '4a6f686e47616c74'
subaddr = '7AeQwvrLtPeYoXVPRkEu8oEL7N9wnqHjYKwSvTf6YKbHgYmw6AJMsjggzVLo21egMK9qcoV1mxCTfP4FbaGb7JEMDfpLetk' subaddr = '7AeQwvrLtPeYoXVPRkEu8oEL7N9wnqHjYKwSvTf6YKbHgYmw6AJMsjggzVLo21egMK9qcoV1mxCTfP4FbaGb7JEMDfpLetk'
iaddr = '5CSfuyzxyAV3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8Vz8ySmoqYgTE8dR1yS' iaddr = '5CSfuyzxyAV3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8Vz8ySmoqYgTE8dR1yS'
mainnet = False net = const.NET_STAGE
testnet = False
stagenet = True
addr_invalid = '52jzuBBUMty3xPL3JsQxGP74LDuV6H1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8LdAqbp6' addr_invalid = '52jzuBBUMty3xPL3JsQxGP74LDuV6H1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8LdAqbp6'
iaddr_invalid = '5CSfuyzxyAV3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKppEgC5VPhfoAiVj8Vz8ySmoqYgTE8dR1yS' iaddr_invalid = '5CSfuyzxyAV3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKppEgC5VPhfoAiVj8Vz8ySmoqYgTE8dR1yS'

View File

@ -1,6 +1,8 @@
import pytest
import unittest
from monero.backends.offline import OfflineWallet, WalletIsOffline from monero.backends.offline import OfflineWallet, WalletIsOffline
from monero.wallet import Wallet from monero.wallet import Wallet
import unittest
from .base import JSONTestCase from .base import JSONTestCase

View File

@ -78,9 +78,9 @@ class SeedTestCase(unittest.TestCase):
'44cWztNFdAqNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH4YtKdH') '44cWztNFdAqNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH4YtKdH')
self.assertIsInstance(seed.public_address(), Address) self.assertIsInstance(seed.public_address(), Address)
self.assertEqual( self.assertEqual(
seed.public_address(net='stagenet'), seed.public_address(net='stage'),
'54pZ5jHDGmwNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH6cuARW') '54pZ5jHDGmwNnycvZbUoj44vsbAEmKnx9aNgkjHdjtMsBrSeKiY8J4s2raH7EMawA2Fwo9utaRTV7Aw8EcTMNMxhH6cuARW')
self.assertIsInstance(seed.public_address(net='stagenet'), Address) self.assertIsInstance(seed.public_address(net='stage'), Address)
seed = Seed("dwelt idols lopped blender haggled rabbits piloted value swagger taunts toolbox upgrade swagger") seed = Seed("dwelt idols lopped blender haggled rabbits piloted value swagger taunts toolbox upgrade swagger")
self.assertTrue(seed.is_mymonero()) self.assertTrue(seed.is_mymonero())
@ -100,7 +100,6 @@ class SeedTestCase(unittest.TestCase):
def test_languages(self): def test_languages(self):
for wordlist in list_wordlists(): for wordlist in list_wordlists():
print("Language: {}".format(wordlist))
# Generate random seed # Generate random seed
seed = Seed(wordlist=wordlist) seed = Seed(wordlist=wordlist)

View File

@ -42,7 +42,7 @@ argsparser.add_argument('--save', dest='outdir', nargs='?', default=None, const=
argsparser.add_argument('destinations', metavar='address:amount', nargs='+', type=destpair, argsparser.add_argument('destinations', metavar='address:amount', nargs='+', type=destpair,
help="Destination address and amount (one or more pairs)") help="Destination address and amount (one or more pairs)")
args = argsparser.parse_args() args = argsparser.parse_args()
prio = getattr(monero.prio, args.prio.upper()) prio = getattr(monero.const, "PRIO_{:s}".format(args.prio.upper()))
level = logging.WARNING level = logging.WARNING
if args.verbosity == 1: if args.verbosity == 1: