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.
143 lines
5.0 KiB
143 lines
5.0 KiB
from trezor import ui
|
|
from trezor.messages import (
|
|
ButtonRequestType,
|
|
NEMImportanceTransfer,
|
|
NEMImportanceTransferMode,
|
|
NEMMosaic,
|
|
NEMMosaicLevy,
|
|
NEMTransactionCommon,
|
|
NEMTransfer,
|
|
)
|
|
from trezor.strings import format_amount
|
|
from trezor.ui.text import Text
|
|
|
|
from apps.common.confirm import require_confirm
|
|
from apps.common.layout import split_address
|
|
|
|
from ..helpers import (
|
|
NEM_LEVY_PERCENTILE_DIVISOR_ABSOLUTE,
|
|
NEM_MAX_DIVISIBILITY,
|
|
NEM_MOSAIC_AMOUNT_DIVISOR,
|
|
)
|
|
from ..layout import require_confirm_final, require_confirm_text
|
|
from ..mosaic.helpers import get_mosaic_definition, is_nem_xem_mosaic
|
|
|
|
|
|
async def ask_transfer(
|
|
ctx,
|
|
common: NEMTransactionCommon,
|
|
transfer: NEMTransfer,
|
|
payload: bytes,
|
|
encrypted: bool,
|
|
):
|
|
if payload:
|
|
await _require_confirm_payload(ctx, transfer.payload, encrypted)
|
|
for mosaic in transfer.mosaics:
|
|
await ask_transfer_mosaic(ctx, common, transfer, mosaic)
|
|
await _require_confirm_transfer(ctx, transfer.recipient, _get_xem_amount(transfer))
|
|
await require_confirm_final(ctx, common.fee)
|
|
|
|
|
|
async def ask_transfer_mosaic(
|
|
ctx, common: NEMTransactionCommon, transfer: NEMTransfer, mosaic: NEMMosaic
|
|
):
|
|
if is_nem_xem_mosaic(mosaic.namespace, mosaic.mosaic):
|
|
return
|
|
|
|
definition = get_mosaic_definition(mosaic.namespace, mosaic.mosaic, common.network)
|
|
mosaic_quantity = mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR
|
|
|
|
if definition:
|
|
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN)
|
|
msg.normal("Confirm transfer of")
|
|
msg.bold(
|
|
format_amount(mosaic_quantity, definition["divisibility"])
|
|
+ definition["ticker"]
|
|
)
|
|
msg.normal("of")
|
|
msg.bold(definition["name"])
|
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
|
|
|
if "levy" in definition and "fee" in definition:
|
|
levy_msg = _get_levy_msg(definition, mosaic_quantity, common.network)
|
|
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN)
|
|
msg.normal("Confirm mosaic", "levy fee of")
|
|
msg.bold(levy_msg)
|
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
|
|
|
else:
|
|
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.RED)
|
|
msg.bold("Unknown mosaic!")
|
|
msg.normal("Divisibility and levy")
|
|
msg.normal("cannot be shown for")
|
|
msg.normal("unknown mosaics")
|
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
|
|
|
msg = Text("Confirm mosaic", ui.ICON_SEND, ui.GREEN)
|
|
msg.normal("Confirm transfer of")
|
|
msg.bold("%s raw units" % mosaic_quantity)
|
|
msg.normal("of")
|
|
msg.bold("%s.%s" % (mosaic.namespace, mosaic.mosaic))
|
|
await require_confirm(ctx, msg, ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
def _get_xem_amount(transfer: NEMTransfer):
|
|
# if mosaics are empty the transfer.amount denotes the xem amount
|
|
if not transfer.mosaics:
|
|
return transfer.amount
|
|
# otherwise xem amount is taken from the nem xem mosaic if present
|
|
for mosaic in transfer.mosaics:
|
|
if is_nem_xem_mosaic(mosaic.namespace, mosaic.mosaic):
|
|
return mosaic.quantity * transfer.amount / NEM_MOSAIC_AMOUNT_DIVISOR
|
|
# if there are mosaics but do not include xem, 0 xem is sent
|
|
return 0
|
|
|
|
|
|
def _get_levy_msg(mosaic_definition, quantity: int, network: int) -> str:
|
|
levy_definition = get_mosaic_definition(
|
|
mosaic_definition["levy_namespace"], mosaic_definition["levy_mosaic"], network
|
|
)
|
|
if mosaic_definition["levy"] == NEMMosaicLevy.MosaicLevy_Absolute:
|
|
levy_fee = mosaic_definition["fee"]
|
|
else:
|
|
levy_fee = (
|
|
quantity * mosaic_definition["fee"] / NEM_LEVY_PERCENTILE_DIVISOR_ABSOLUTE
|
|
)
|
|
return (
|
|
format_amount(levy_fee, levy_definition["divisibility"])
|
|
+ levy_definition["ticker"]
|
|
)
|
|
|
|
|
|
async def ask_importance_transfer(
|
|
ctx, common: NEMTransactionCommon, imp: NEMImportanceTransfer
|
|
):
|
|
if imp.mode == NEMImportanceTransferMode.ImportanceTransfer_Activate:
|
|
m = "Activate"
|
|
else:
|
|
m = "Deactivate"
|
|
await require_confirm_text(ctx, m + " remote harvesting?")
|
|
await require_confirm_final(ctx, common.fee)
|
|
|
|
|
|
async def _require_confirm_transfer(ctx, recipient, value):
|
|
text = Text("Confirm transfer", ui.ICON_SEND, ui.GREEN)
|
|
text.bold("Send %s XEM" % format_amount(value, NEM_MAX_DIVISIBILITY))
|
|
text.normal("to")
|
|
text.mono(*split_address(recipient))
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
async def _require_confirm_payload(ctx, payload: bytearray, encrypt=False):
|
|
payload = bytes(payload).decode()
|
|
|
|
if encrypt:
|
|
text = Text("Confirm payload", ui.ICON_SEND, ui.GREEN)
|
|
text.bold("Encrypted:")
|
|
text.normal(payload)
|
|
else:
|
|
text = Text("Confirm payload", ui.ICON_SEND, ui.RED)
|
|
text.bold("Unencrypted:")
|
|
text.normal(payload)
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|