You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trezor-firmware/src/apps/monero/xmr/addresses.py

87 lines
2.3 KiB

from trezor.crypto import monero as tcry
from apps.monero.xmr.networks import NetworkTypes, net_version
def addr_to_hash(addr):
"""
Creates hashable address representation
"""
return bytes(addr.spend_public_key + addr.view_public_key)
def encode_addr(version, spend_pub, view_pub, payment_id=None):
"""
Encodes public keys as versions
"""
buf = spend_pub + view_pub
if payment_id:
buf += bytes(payment_id)
return tcry.xmr_base58_addr_encode_check(ord(version), bytes(buf))
def decode_addr(addr):
"""
Given address, get version and public spend and view keys.
"""
d, version = tcry.xmr_base58_addr_decode_check(bytes(addr))
pub_spend_key = d[0:32]
pub_view_key = d[32:64]
return version, pub_spend_key, pub_view_key
def public_addr_encode(pub_addr, is_sub=False, net=NetworkTypes.MAINNET):
"""
Encodes public address to Monero address
"""
net_ver = net_version(net, is_sub)
return encode_addr(net_ver, pub_addr.spend_public_key, pub_addr.view_public_key)
def classify_subaddresses(tx_dests, change_addr):
"""
Classify destination subaddresses
"""
num_stdaddresses = 0
num_subaddresses = 0
single_dest_subaddress = None
addr_set = set()
for tx in tx_dests:
if change_addr and addr_eq(change_addr, tx.addr):
continue
addr_hashed = addr_to_hash(tx.addr)
if addr_hashed in addr_set:
continue
addr_set.add(addr_hashed)
if tx.is_subaddress:
num_subaddresses += 1
single_dest_subaddress = tx.addr
else:
num_stdaddresses += 1
return num_stdaddresses, num_subaddresses, single_dest_subaddress
def addr_eq(a, b):
return (
a.spend_public_key == b.spend_public_key
and a.view_public_key == b.view_public_key
)
def get_change_addr_idx(outputs, change_dts):
"""
Returns ID of the change output from the change_dts and outputs
"""
if change_dts is None:
return None
change_idx = None
for idx, dst in enumerate(outputs):
if (
change_dts.amount
and change_dts.amount == dst.amount
and addr_eq(change_dts.addr, dst.addr)
):
change_idx = idx
return change_idx