core/bitcoin: Implement AuthorizeCoinJoin message.

pull/1168/head
Andrew Kozlik 4 years ago committed by Andrew Kozlik
parent 48a331aa1d
commit 208283e13e

@ -3,6 +3,7 @@ from trezor.messages import MessageType
def boot() -> None:
wire.add(MessageType.AuthorizeCoinJoin, __name__, "authorize_coinjoin")
wire.add(MessageType.GetPublicKey, __name__, "get_public_key")
wire.add(MessageType.GetAddress, __name__, "get_address")
wire.add(MessageType.GetOwnershipId, __name__, "get_ownership_id")

@ -0,0 +1,78 @@
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 . import addresses
from .authorization import FEE_PER_ANONYMITY_DECIMALS, CoinJoinAuthorization
from .common import BIP32_WALLET_DEPTH
from .keychain import get_keychain_for_coin
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.")
await validate_path(
ctx,
addresses.validate_full_path,
keychain,
msg.address_n + [0] * BIP32_WALLET_DEPTH,
coin.curve_name,
coin=coin,
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(
format_amount(msg.max_total_fee, coin.decimals), coin.coin_shortcut
)
)
await require_hold_to_confirm(ctx, text)
set_authorization(CoinJoinAuthorization(msg, keychain, coin))
except BaseException:
keychain.__del__()
raise
return Success(message="CoinJoin authorized")
Loading…
Cancel
Save