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.
299 lines
10 KiB
299 lines
10 KiB
from micropython import const
|
|
from ubinascii import hexlify
|
|
|
|
from trezor import ui
|
|
from trezor.messages import (
|
|
ButtonRequestType,
|
|
EosActionBuyRam,
|
|
EosActionBuyRamBytes,
|
|
EosActionDelegate,
|
|
EosActionDeleteAuth,
|
|
EosActionLinkAuth,
|
|
EosActionNewAccount,
|
|
EosActionRefund,
|
|
EosActionSellRam,
|
|
EosActionTransfer,
|
|
EosActionUndelegate,
|
|
EosActionUnlinkAuth,
|
|
EosActionUpdateAuth,
|
|
EosActionVoteProducer,
|
|
)
|
|
from trezor.ui.scroll import Paginated
|
|
from trezor.ui.text import Text
|
|
from trezor.utils import chunks
|
|
|
|
from apps.eos import helpers
|
|
from apps.eos.get_public_key import _public_key_to_wif
|
|
from apps.eos.layout import require_confirm
|
|
|
|
_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, header, fields, per_page):
|
|
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, msg: EosActionBuyRam):
|
|
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, msg: EosActionBuyRamBytes):
|
|
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, msg: EosActionDelegate):
|
|
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, msg: EosActionSellRam):
|
|
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, msg: EosActionUndelegate):
|
|
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, msg: EosActionRefund):
|
|
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, msg: EosActionVoteProducer):
|
|
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, msg: EosActionTransfer, account: str):
|
|
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, msg: EosActionUpdateAuth):
|
|
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, msg: EosActionDeleteAuth):
|
|
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, msg: EosActionLinkAuth):
|
|
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, msg: EosActionUnlinkAuth):
|
|
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, msg: EosActionNewAccount):
|
|
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, action, checksum):
|
|
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):
|
|
fields = []
|
|
|
|
fields.append("Threshold:")
|
|
fields.append(str(auth.threshold))
|
|
|
|
for i, key in enumerate(auth.keys):
|
|
_key = _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):
|
|
temp_list = []
|
|
len_left = len(data)
|
|
while len_left > 0:
|
|
temp_list.append("{} ".format(data[:_LINE_LENGTH]))
|
|
data = data[_LINE_LENGTH:]
|
|
len_left = len(data)
|
|
return temp_list
|