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.
321 lines
10 KiB
321 lines
10 KiB
from micropython import const
|
|
from ubinascii import hexlify
|
|
|
|
from trezor import ui
|
|
from trezor.enums import ButtonRequestType
|
|
from trezor.ui.components.tt.scroll import Paginated
|
|
from trezor.ui.components.tt.text import Text
|
|
from trezor.utils import chunks
|
|
|
|
from .. import helpers
|
|
from ..layout import require_confirm
|
|
|
|
if False:
|
|
from trezor import wire
|
|
from trezor.messages import (
|
|
EosActionBuyRam,
|
|
EosActionBuyRamBytes,
|
|
EosActionCommon,
|
|
EosActionDelegate,
|
|
EosActionDeleteAuth,
|
|
EosActionLinkAuth,
|
|
EosActionNewAccount,
|
|
EosActionRefund,
|
|
EosActionSellRam,
|
|
EosActionTransfer,
|
|
EosActionUndelegate,
|
|
EosActionUnlinkAuth,
|
|
EosActionUpdateAuth,
|
|
EosActionVoteProducer,
|
|
EosAuthorization,
|
|
)
|
|
|
|
_LINE_LENGTH = const(17)
|
|
_LINE_PLACEHOLDER = "{:<" + str(_LINE_LENGTH) + "}"
|
|
_FIRST_PAGE = const(0)
|
|
_TWO_FIELDS_PER_PAGE = const(2)
|
|
_THREE_FIELDS_PER_PAGE = const(3)
|
|
_FOUR_FIELDS_PER_PAGE = const(4)
|
|
_FIVE_FIELDS_PER_PAGE = const(5)
|
|
|
|
|
|
async def _require_confirm_paginated(
|
|
ctx: wire.Context, header: str, fields: list[str], per_page: int
|
|
) -> None:
|
|
pages = []
|
|
for page in chunks(fields, per_page):
|
|
if header == "Arbitrary data":
|
|
text = Text(header, ui.ICON_WIPE, ui.RED)
|
|
else:
|
|
text = Text(header, ui.ICON_CONFIRM, ui.GREEN)
|
|
text.mono(*page)
|
|
pages.append(text)
|
|
await require_confirm(ctx, Paginated(pages), ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
async def confirm_action_buyram(ctx: wire.Context, msg: EosActionBuyRam) -> None:
|
|
text = "Buy RAM"
|
|
fields = []
|
|
fields.append("Payer:")
|
|
fields.append(helpers.eos_name_to_string(msg.payer))
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
fields.append("Amount:")
|
|
fields.append(helpers.eos_asset_to_string(msg.quantity))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_buyrambytes(
|
|
ctx: wire.Context, msg: EosActionBuyRamBytes
|
|
) -> None:
|
|
text = "Buy RAM"
|
|
fields = []
|
|
fields.append("Payer:")
|
|
fields.append(helpers.eos_name_to_string(msg.payer))
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
fields.append("Bytes:")
|
|
fields.append(str(msg.bytes))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_delegate(ctx: wire.Context, msg: EosActionDelegate) -> None:
|
|
text = "Delegate"
|
|
fields = []
|
|
fields.append("Sender:")
|
|
fields.append(helpers.eos_name_to_string(msg.sender))
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
fields.append("CPU:")
|
|
fields.append(helpers.eos_asset_to_string(msg.cpu_quantity))
|
|
fields.append("NET:")
|
|
fields.append(helpers.eos_asset_to_string(msg.net_quantity))
|
|
|
|
if msg.transfer:
|
|
fields.append("Transfer: Yes")
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
else:
|
|
fields.append("Transfer: No")
|
|
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_sellram(ctx: wire.Context, msg: EosActionSellRam) -> None:
|
|
text = "Sell RAM"
|
|
fields = []
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.account))
|
|
fields.append("Bytes:")
|
|
fields.append(str(msg.bytes))
|
|
await _require_confirm_paginated(ctx, text, fields, _TWO_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_undelegate(
|
|
ctx: wire.Context, msg: EosActionUndelegate
|
|
) -> None:
|
|
text = "Undelegate"
|
|
fields = []
|
|
fields.append("Sender:")
|
|
fields.append(helpers.eos_name_to_string(msg.sender))
|
|
fields.append("Receiver:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
fields.append("CPU:")
|
|
fields.append(helpers.eos_asset_to_string(msg.cpu_quantity))
|
|
fields.append("NET:")
|
|
fields.append(helpers.eos_asset_to_string(msg.net_quantity))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_refund(ctx: wire.Context, msg: EosActionRefund) -> None:
|
|
text = Text("Refund", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
|
text.normal("Owner:")
|
|
text.normal(helpers.eos_name_to_string(msg.owner))
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
async def confirm_action_voteproducer(
|
|
ctx: wire.Context, msg: EosActionVoteProducer
|
|
) -> None:
|
|
if msg.proxy and not msg.producers:
|
|
# PROXY
|
|
text = Text("Vote for proxy", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
|
text.normal("Voter:")
|
|
text.normal(helpers.eos_name_to_string(msg.voter))
|
|
text.normal("Proxy:")
|
|
text.normal(helpers.eos_name_to_string(msg.proxy))
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
|
|
|
elif msg.producers:
|
|
# PRODUCERS
|
|
text = "Vote for producers"
|
|
fields = [
|
|
"{:2d}. {}".format(wi + 1, helpers.eos_name_to_string(producer))
|
|
for wi, producer in enumerate(msg.producers)
|
|
]
|
|
await _require_confirm_paginated(ctx, text, fields, _FIVE_FIELDS_PER_PAGE)
|
|
|
|
else:
|
|
# Cancel vote
|
|
text = Text("Cancel vote", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
|
text.normal("Voter:")
|
|
text.normal(helpers.eos_name_to_string(msg.voter))
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
async def confirm_action_transfer(
|
|
ctx: wire.Context, msg: EosActionTransfer, account: str
|
|
) -> None:
|
|
text = "Transfer"
|
|
fields = []
|
|
fields.append("From:")
|
|
fields.append(helpers.eos_name_to_string(msg.sender))
|
|
fields.append("To:")
|
|
fields.append(helpers.eos_name_to_string(msg.receiver))
|
|
fields.append("Amount:")
|
|
fields.append(helpers.eos_asset_to_string(msg.quantity))
|
|
fields.append("Contract:")
|
|
fields.append(account)
|
|
|
|
if msg.memo is not None:
|
|
fields.append("Memo:")
|
|
fields.extend(split_data(msg.memo[:512]))
|
|
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_updateauth(
|
|
ctx: wire.Context, msg: EosActionUpdateAuth
|
|
) -> None:
|
|
text = "Update Auth"
|
|
fields = []
|
|
fields.append("Account:")
|
|
fields.append(helpers.eos_name_to_string(msg.account))
|
|
fields.append("Permission:")
|
|
fields.append(helpers.eos_name_to_string(msg.permission))
|
|
fields.append("Parent:")
|
|
fields.append(helpers.eos_name_to_string(msg.parent))
|
|
fields.extend(authorization_fields(msg.auth))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_deleteauth(
|
|
ctx: wire.Context, msg: EosActionDeleteAuth
|
|
) -> None:
|
|
text = Text("Delete auth", ui.ICON_CONFIRM, icon_color=ui.GREEN)
|
|
text.normal("Account:")
|
|
text.normal(helpers.eos_name_to_string(msg.account))
|
|
text.normal("Permission:")
|
|
text.normal(helpers.eos_name_to_string(msg.permission))
|
|
await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput)
|
|
|
|
|
|
async def confirm_action_linkauth(ctx: wire.Context, msg: EosActionLinkAuth) -> None:
|
|
text = "Link Auth"
|
|
fields = []
|
|
fields.append("Account:")
|
|
fields.append(helpers.eos_name_to_string(msg.account))
|
|
fields.append("Code:")
|
|
fields.append(helpers.eos_name_to_string(msg.code))
|
|
fields.append("Type:")
|
|
fields.append(helpers.eos_name_to_string(msg.type))
|
|
fields.append("Requirement:")
|
|
fields.append(helpers.eos_name_to_string(msg.requirement))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_unlinkauth(
|
|
ctx: wire.Context, msg: EosActionUnlinkAuth
|
|
) -> None:
|
|
text = "Unlink Auth"
|
|
fields = []
|
|
fields.append("Account:")
|
|
fields.append(helpers.eos_name_to_string(msg.account))
|
|
fields.append("Code:")
|
|
fields.append(helpers.eos_name_to_string(msg.code))
|
|
fields.append("Type:")
|
|
fields.append(helpers.eos_name_to_string(msg.type))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_newaccount(
|
|
ctx: wire.Context, msg: EosActionNewAccount
|
|
) -> None:
|
|
text = "New Account"
|
|
fields = []
|
|
fields.append("Creator:")
|
|
fields.append(helpers.eos_name_to_string(msg.creator))
|
|
fields.append("Name:")
|
|
fields.append(helpers.eos_name_to_string(msg.name))
|
|
fields.extend(authorization_fields(msg.owner))
|
|
fields.extend(authorization_fields(msg.active))
|
|
await _require_confirm_paginated(ctx, text, fields, _FOUR_FIELDS_PER_PAGE)
|
|
|
|
|
|
async def confirm_action_unknown(
|
|
ctx: wire.Context, action: EosActionCommon, checksum: bytes
|
|
) -> None:
|
|
text = "Arbitrary data"
|
|
fields = []
|
|
fields.append("Contract:")
|
|
fields.append(helpers.eos_name_to_string(action.account))
|
|
fields.append("Action Name:")
|
|
fields.append(helpers.eos_name_to_string(action.name))
|
|
fields.append("Checksum: ")
|
|
fields.extend(split_data(hexlify(checksum).decode("ascii")))
|
|
await _require_confirm_paginated(ctx, text, fields, _FIVE_FIELDS_PER_PAGE)
|
|
|
|
|
|
def authorization_fields(auth: EosAuthorization) -> list[str]:
|
|
fields = []
|
|
|
|
fields.append("Threshold:")
|
|
fields.append(str(auth.threshold))
|
|
|
|
for i, key in enumerate(auth.keys):
|
|
_key = helpers.public_key_to_wif(bytes(key.key))
|
|
_weight = str(key.weight)
|
|
|
|
header = "Key #{}:".format(i + 1)
|
|
w_header = "Key #{} Weight:".format(i + 1)
|
|
fields.append(header)
|
|
fields += split_data(_key)
|
|
fields.append(w_header)
|
|
fields.append(_weight)
|
|
|
|
for i, account in enumerate(auth.accounts):
|
|
_account = helpers.eos_name_to_string(account.account.actor)
|
|
_permission = helpers.eos_name_to_string(account.account.permission)
|
|
|
|
a_header = "Account #{}:".format(i + 1)
|
|
p_header = "Acc Permission #{}:".format(i + 1)
|
|
w_header = "Account #{} weight:".format(i + 1)
|
|
|
|
fields.append(a_header)
|
|
fields.append(_account)
|
|
fields.append(p_header)
|
|
fields.append(_permission)
|
|
fields.append(w_header)
|
|
fields.append(str(account.weight))
|
|
|
|
for i, wait in enumerate(auth.waits):
|
|
_wait = str(wait.wait_sec)
|
|
_weight = str(wait.weight)
|
|
|
|
header = "Delay #{}".format(i + 1)
|
|
w_header = "Delay #{} weight:".format(i + 1)
|
|
fields.append(header)
|
|
fields.append("{} sec".format(_wait))
|
|
fields.append(w_header)
|
|
fields.append(_weight)
|
|
|
|
return fields
|
|
|
|
|
|
def split_data(data: str) -> list[str]:
|
|
lines = []
|
|
while data:
|
|
lines.append("{} ".format(data[:_LINE_LENGTH]))
|
|
data = data[_LINE_LENGTH:]
|
|
return lines
|