from trezor import utils, wire from trezor.messages.RequestType import TXFINISHED from trezor.messages.SignTx import SignTx from trezor.messages.TxAck import TxAck from trezor.messages.TxRequest import TxRequest from apps.common import coininfo from ..common import BITCOIN_NAMES from ..keychain import with_keychain from . import approvers, bitcoin, helpers, progress if not utils.BITCOIN_ONLY: from . import bitcoinlike, decred, zcash if False: from typing import Optional, Union from apps.common.seed import Keychain from ..authorization import CoinJoinAuthorization @with_keychain async def sign_tx( ctx: wire.Context, msg: SignTx, keychain: Keychain, coin: coininfo.CoinInfo, authorization: Optional[CoinJoinAuthorization] = None, ) -> TxRequest: if authorization: approver = approvers.CoinJoinApprover(msg, coin, authorization) else: approver = approvers.BasicApprover(msg, coin) if utils.BITCOIN_ONLY or coin.coin_name in BITCOIN_NAMES: signer_class = bitcoin.Bitcoin else: if coin.decred: signer_class = decred.Decred elif coin.overwintered: signer_class = zcash.Zcashlike else: signer_class = bitcoinlike.Bitcoinlike signer = signer_class(msg, keychain, coin, approver).signer() res = None # type: Union[TxAck, bool, None] field_cache = {} while True: req = signer.send(res) if isinstance(req, TxRequest): if req.request_type == TXFINISHED: break res = await ctx.call(req, TxAck, field_cache) elif isinstance(req, helpers.UiConfirm): res = await req.confirm_dialog(ctx) progress.report_init() else: raise TypeError("Invalid signing instruction") return req