Add support for stagenet addresses
This commit is contained in:
parent
0bfdb8f7be
commit
a037f121b7
|
@ -19,8 +19,8 @@ class Address(object):
|
||||||
:param label: a label for the address (defaults to `None`)
|
:param label: a label for the address (defaults to `None`)
|
||||||
"""
|
"""
|
||||||
label = None
|
label = None
|
||||||
_valid_netbytes = (18, 53)
|
_valid_netbytes = (18, 53, 24)
|
||||||
# NOTE: _valid_netbytes order is (real, testnet)
|
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
|
||||||
|
|
||||||
def __init__(self, addr, label=None):
|
def __init__(self, addr, label=None):
|
||||||
addr = str(addr)
|
addr = str(addr)
|
||||||
|
@ -40,6 +40,13 @@ class Address(object):
|
||||||
nb=self._decoded[0],
|
nb=self._decoded[0],
|
||||||
allowed=", ".join(map(lambda b: '%02x' % b, self._valid_netbytes))))
|
allowed=", ".join(map(lambda b: '%02x' % b, self._valid_netbytes))))
|
||||||
|
|
||||||
|
def is_mainnet(self):
|
||||||
|
"""Returns `True` if the address belongs to mainnet.
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return self._decoded[0] == self._valid_netbytes[0]
|
||||||
|
|
||||||
def is_testnet(self):
|
def is_testnet(self):
|
||||||
"""Returns `True` if the address belongs to testnet.
|
"""Returns `True` if the address belongs to testnet.
|
||||||
|
|
||||||
|
@ -47,6 +54,13 @@ class Address(object):
|
||||||
"""
|
"""
|
||||||
return self._decoded[0] == self._valid_netbytes[1]
|
return self._decoded[0] == self._valid_netbytes[1]
|
||||||
|
|
||||||
|
def is_stagenet(self):
|
||||||
|
"""Returns `True` if the address belongs to stagenet.
|
||||||
|
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
|
return self._decoded[0] == self._valid_netbytes[2]
|
||||||
|
|
||||||
def view_key(self):
|
def view_key(self):
|
||||||
"""Returns public view key.
|
"""Returns public view key.
|
||||||
|
|
||||||
|
@ -73,7 +87,7 @@ class Address(object):
|
||||||
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 19
|
prefix = 54 if self.is_testnet() else 25 if self.is_stagenet() else 19
|
||||||
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)))
|
||||||
|
@ -95,7 +109,8 @@ class SubAddress(Address):
|
||||||
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)
|
_valid_netbytes = (42, 63, 36)
|
||||||
|
# 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")
|
||||||
|
@ -107,7 +122,8 @@ 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)
|
_valid_netbytes = (19, 54, 25)
|
||||||
|
# NOTE: _valid_netbytes order is (mainnet, testnet, stagenet)
|
||||||
|
|
||||||
def __init__(self, address):
|
def __init__(self, address):
|
||||||
address = str(address)
|
address = str(address)
|
||||||
|
@ -127,7 +143,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 18
|
prefix = 53 if self.is_testnet() else 24 if self.is_stagenet() else 18
|
||||||
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)))
|
||||||
|
|
|
@ -33,8 +33,12 @@ class Tests(object):
|
||||||
self.assertEqual(a, a2)
|
self.assertEqual(a, a2)
|
||||||
self.assertEqual(a, self.addr)
|
self.assertEqual(a, self.addr)
|
||||||
self.assertEqual(self.addr, a)
|
self.assertEqual(self.addr, a)
|
||||||
|
self.assertEqual(a.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(a.is_testnet(), self.testnet)
|
self.assertEqual(a.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(a.is_stagenet(), self.stagenet)
|
||||||
|
self.assertEqual(a2.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(a2.is_testnet(), self.testnet)
|
self.assertEqual(a2.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(a2.is_stagenet(), self.stagenet)
|
||||||
|
|
||||||
ia = IntegratedAddress(self.iaddr)
|
ia = IntegratedAddress(self.iaddr)
|
||||||
ia2 = address(self.iaddr)
|
ia2 = address(self.iaddr)
|
||||||
|
@ -42,8 +46,12 @@ class Tests(object):
|
||||||
self.assertEqual(ia, ia2)
|
self.assertEqual(ia, ia2)
|
||||||
self.assertEqual(ia, self.iaddr)
|
self.assertEqual(ia, self.iaddr)
|
||||||
self.assertEqual(self.iaddr, ia)
|
self.assertEqual(self.iaddr, ia)
|
||||||
|
self.assertEqual(ia.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(ia.is_testnet(), self.testnet)
|
self.assertEqual(ia.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(ia.is_stagenet(), self.stagenet)
|
||||||
|
self.assertEqual(ia2.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(ia2.is_testnet(), self.testnet)
|
self.assertEqual(ia2.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(ia2.is_stagenet(), self.stagenet)
|
||||||
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())
|
||||||
|
@ -55,8 +63,12 @@ class Tests(object):
|
||||||
self.assertEqual(sa, sa2)
|
self.assertEqual(sa, sa2)
|
||||||
self.assertEqual(sa, self.subaddr)
|
self.assertEqual(sa, self.subaddr)
|
||||||
self.assertEqual(self.subaddr, sa)
|
self.assertEqual(self.subaddr, sa)
|
||||||
|
self.assertEqual(sa.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(sa.is_testnet(), self.testnet)
|
self.assertEqual(sa.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(sa.is_stagenet(), self.stagenet)
|
||||||
|
self.assertEqual(sa2.is_mainnet(), self.mainnet)
|
||||||
self.assertEqual(sa2.is_testnet(), self.testnet)
|
self.assertEqual(sa2.is_testnet(), self.testnet)
|
||||||
|
self.assertEqual(sa2.is_stagenet(), self.stagenet)
|
||||||
|
|
||||||
self.assertNotEqual(a, 0)
|
self.assertNotEqual(a, 0)
|
||||||
|
|
||||||
|
@ -120,7 +132,9 @@ class AddressTestCase(unittest.TestCase, Tests):
|
||||||
pid = '4a6f686e47616c74'
|
pid = '4a6f686e47616c74'
|
||||||
subaddr = '83bK2pMxCQXdRyd6W1haNWYRsF6Qb3iGa8gxKEynm9U7cYoXrMHFwRrFFuxRSgnLtGe7LM8SmrPY6L3TVBa3UV3YLuVJ7Rw'
|
subaddr = '83bK2pMxCQXdRyd6W1haNWYRsF6Qb3iGa8gxKEynm9U7cYoXrMHFwRrFFuxRSgnLtGe7LM8SmrPY6L3TVBa3UV3YLuVJ7Rw'
|
||||||
iaddr = '4DHKLPmWW8aBoEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuhAR6GpL18QNwE8h3TuF'
|
iaddr = '4DHKLPmWW8aBoEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuhAR6GpL18QNwE8h3TuF'
|
||||||
|
mainnet = True
|
||||||
testnet = False
|
testnet = False
|
||||||
|
stagenet = False
|
||||||
addr_invalid = '43aeKax1ts4boEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuh7PFUAmd'
|
addr_invalid = '43aeKax1ts4boEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuh7PFUAmd'
|
||||||
iaddr_invalid = '4DHKLpmWW8aBoEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuhAR6GpL18QNwE8h3TuF'
|
iaddr_invalid = '4DHKLpmWW8aBoEbSyzKVbbDRmc8nsnpZLUpQBYvhUxs3KVrodnaFaBEQMDp69u4VaiEG3LSQXA6M61mXPrztCLuhAR6GpL18QNwE8h3TuF'
|
||||||
|
|
||||||
|
@ -132,6 +146,22 @@ class TestnetAddressTestCase(AddressTestCase, Tests):
|
||||||
pid = '4a6f686e47616c74'
|
pid = '4a6f686e47616c74'
|
||||||
iaddr = 'A6PA4wkzmeyWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YbfyqvDecDn3E7cvp9b'
|
iaddr = 'A6PA4wkzmeyWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YbfyqvDecDn3E7cvp9b'
|
||||||
subaddr = 'BbBjyYoYNNwFfL8RRVRTMiZUofBLpjRxdNnd5E4LyGcAK5CEsnL3gmE5QkrDRta7RPficGHcFdR6rUwWcjnwZVvCE3tLxhJ'
|
subaddr = 'BbBjyYoYNNwFfL8RRVRTMiZUofBLpjRxdNnd5E4LyGcAK5CEsnL3gmE5QkrDRta7RPficGHcFdR6rUwWcjnwZVvCE3tLxhJ'
|
||||||
|
mainnet = False
|
||||||
testnet = True
|
testnet = True
|
||||||
|
stagenet = False
|
||||||
addr_invalid = '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUbbV6YQN2Q9ag'
|
addr_invalid = '9vgV48wWAPTWik5QSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUbbV6YQN2Q9ag'
|
||||||
iaddr_invalid = 'A6PA4wkzmeyWik5qSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YbfyqvDecDn3E7cvp9b'
|
iaddr_invalid = 'A6PA4wkzmeyWik5qSUSoGYicdvvsbSNHrT9Arsx1XBTz6VrWPSgfmnUKSPZDMyX4Ms8R9TkhB4uFqK9s5LUBbV6YbfyqvDecDn3E7cvp9b'
|
||||||
|
|
||||||
|
|
||||||
|
class StagenetAddressTestCase(AddressTestCase, Tests):
|
||||||
|
addr = '56cXYWG13YKaT9z1aEy2hb9TZNnxrW3zE9S4nTQVDux5Qq7UYsmjuux3Zstxkorj9HAufyWLU3FwHW4uERQF6tkeUVogGN3'
|
||||||
|
psk = '7e33891fe6ea30c7fd79d48e250906329104dc77407cf732699f41564df8ca8e'
|
||||||
|
pvk = '77a3720428f91f0f58a196bb374f703b3ca45fa55f0764adc81ff241c4c797f3'
|
||||||
|
pid = '4a6f686e47616c74'
|
||||||
|
iaddr = '5GKCZK5VeoqaT9z1aEy2hb9TZNnxrW3zE9S4nTQVDux5Qq7UYsmjuux3Zstxkorj9HAufyWLU3FwHW4uERQF6tkehhE4RH8N7QfEAC8jMy'
|
||||||
|
subaddr = '7417qYoKBoYXCugU2KvJBZExmyjav4n1MVME74AeWNwxQ39wKtbWdyP6YGuMK6C7HkAjBuVcbUYmCWbxDLwk9GAX4qyb48U'
|
||||||
|
mainnet = False
|
||||||
|
testnet = False
|
||||||
|
stagenet = True
|
||||||
|
addr_invalid ='7417qYoKBoYXCugU2KvJBZExmyjav4n1MVME74AeWNwxQ39wKtbWdyP6YGuMK6C7HkAjBuVcbUYmCWbyDLwk9GAX4qyb48U'
|
||||||
|
iaddr_invalid = '5GKCZK5VeuqaT9z1aEy2hb9TZNnxrW3zE9S4nTQVDux5Qq7UYsmjuux3Zstxkorj9HAufyWLU3FwHW4uERQF6tkehhE4RH8N7QfEAC8jMy'
|
||||||
|
|
Loading…
Reference in New Issue