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.
trezor-firmware/core/src/apps/bitcoin/sign_tx/__init__.py

91 lines
2.4 KiB

from trezor import utils, wire
from trezor.enums import RequestType
from trezor.messages import TxRequest
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 Protocol, Union
from trezor.messages import (
SignTx,
TxAckInput,
TxAckOutput,
TxAckPrevMeta,
TxAckPrevInput,
TxAckPrevOutput,
TxAckPrevExtraData,
)
from apps.common.coininfo import CoinInfo
from apps.common.keychain import Keychain
from ..authorization import CoinJoinAuthorization
TxAckType = Union[
TxAckInput,
TxAckOutput,
TxAckPrevMeta,
TxAckPrevInput,
TxAckPrevOutput,
TxAckPrevExtraData,
]
class SignerClass(Protocol):
def __init__( # pylint: disable=super-init-not-called
self,
tx: SignTx,
keychain: Keychain,
coin: CoinInfo,
approver: approvers.Approver | None,
) -> None:
...
async def signer(self) -> None:
...
@with_keychain
async def sign_tx(
ctx: wire.Context,
msg: SignTx,
keychain: Keychain,
coin: CoinInfo,
authorization: CoinJoinAuthorization | None = None,
) -> TxRequest:
approver: approvers.Approver | None = None
if authorization:
approver = approvers.CoinJoinApprover(msg, coin, authorization)
if utils.BITCOIN_ONLY or coin.coin_name in BITCOIN_NAMES:
signer_class: type[SignerClass] = 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: TxAckType | bool | None = None
while True:
req = signer.send(res)
if isinstance(req, tuple):
request_class, req = req
assert TxRequest.is_type_of(req)
if req.request_type == RequestType.TXFINISHED:
return req
res = await ctx.call(req, request_class)
elif isinstance(req, helpers.UiConfirm):
res = await req.confirm_dialog(ctx)
progress.report_init()
else:
raise TypeError("Invalid signing instruction")