mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-16 11:38:12 +00:00
81 lines
2.7 KiB
Python
81 lines
2.7 KiB
Python
from micropython import const
|
|
|
|
from trezor import ui
|
|
from trezor.messages.AuthorizeCoinJoin import AuthorizeCoinJoin
|
|
from trezor.messages.Success import Success
|
|
from trezor.strings import format_amount
|
|
from trezor.ui.text import Text
|
|
|
|
from apps.base import set_authorization
|
|
from apps.common.confirm import require_confirm, require_hold_to_confirm
|
|
from apps.common.paths import validate_path
|
|
|
|
from .authorization import FEE_PER_ANONYMITY_DECIMALS, CoinJoinAuthorization
|
|
from .common import BIP32_WALLET_DEPTH
|
|
from .keychain import get_keychain_for_coin, validate_path_against_script_type
|
|
from .sign_tx.layout import format_coin_amount
|
|
|
|
if False:
|
|
from trezor import wire
|
|
|
|
_MAX_COORDINATOR_LEN = const(18)
|
|
|
|
|
|
async def authorize_coinjoin(ctx: wire.Context, msg: AuthorizeCoinJoin) -> Success:
|
|
# We cannot use the @with_keychain decorator here, because we need the keychain
|
|
# to survive the function exit. The ownership of the keychain is transferred to
|
|
# the CoinJoinAuthorization object, which takes care of its destruction.
|
|
keychain, coin = await get_keychain_for_coin(ctx, msg.coin_name)
|
|
|
|
try:
|
|
if len(msg.coordinator) > _MAX_COORDINATOR_LEN or not all(
|
|
32 <= ord(x) <= 126 for x in msg.coordinator
|
|
):
|
|
raise wire.DataError("Invalid coordinator name.")
|
|
|
|
if not msg.address_n:
|
|
raise wire.DataError("Empty path not allowed.")
|
|
|
|
validation_path = msg.address_n + [0] * BIP32_WALLET_DEPTH
|
|
await validate_path(
|
|
ctx,
|
|
keychain,
|
|
validation_path,
|
|
validate_path_against_script_type(
|
|
coin, address_n=validation_path, script_type=msg.script_type
|
|
),
|
|
)
|
|
|
|
text = Text("Authorize CoinJoin", ui.ICON_RECOVERY)
|
|
text.normal("Do you really want to")
|
|
text.normal("take part in a CoinJoin")
|
|
text.normal("transaction at:")
|
|
text.mono(msg.coordinator)
|
|
await require_confirm(ctx, text)
|
|
|
|
text = Text("Authorize CoinJoin", ui.ICON_RECOVERY)
|
|
if msg.fee_per_anonymity is not None:
|
|
text.normal("Fee per anonymity set:")
|
|
text.bold(
|
|
"{} %".format(
|
|
format_amount(msg.fee_per_anonymity, FEE_PER_ANONYMITY_DECIMALS)
|
|
)
|
|
)
|
|
text.normal("Maximum total fees:")
|
|
text.bold(
|
|
format_coin_amount(
|
|
msg.max_total_fee,
|
|
coin,
|
|
msg.amount_unit,
|
|
)
|
|
)
|
|
await require_hold_to_confirm(ctx, text)
|
|
|
|
set_authorization(CoinJoinAuthorization(msg, keychain, coin))
|
|
|
|
except BaseException:
|
|
keychain.__del__()
|
|
raise
|
|
|
|
return Success(message="CoinJoin authorized")
|