mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-08-01 03:18:12 +00:00
refactor(core/bitcoin): make use of Context omission to simplify bitcoin app
This commit is contained in:
parent
8538f3a65f
commit
5a4aaa79fc
@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
||||
) -> None:
|
||||
...
|
||||
|
||||
async def signer(self) -> None:
|
||||
async def signer(self) -> TxRequest:
|
||||
...
|
||||
|
||||
|
||||
@ -54,12 +54,8 @@ async def sign_tx(
|
||||
coin: CoinInfo,
|
||||
authorization: CoinJoinAuthorization | None = None,
|
||||
) -> TxRequest:
|
||||
from trezor.enums import RequestType
|
||||
from trezor.messages import TxRequest
|
||||
from trezor.wire.context import call
|
||||
|
||||
from ..common import BITCOIN_NAMES
|
||||
from . import approvers, bitcoin, helpers, progress
|
||||
from . import approvers, bitcoin
|
||||
|
||||
approver: approvers.Approver | None = None
|
||||
if authorization:
|
||||
@ -86,19 +82,4 @@ async def sign_tx(
|
||||
|
||||
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 call(req, request_class)
|
||||
elif isinstance(req, helpers.UiConfirm):
|
||||
res = await req.confirm_dialog()
|
||||
progress.progress.report_init()
|
||||
else:
|
||||
raise TypeError("Invalid signing instruction")
|
||||
return await signer_class(msg, keychain, coin, approver).signer()
|
||||
|
@ -11,7 +11,7 @@ from apps.common import safety_checks
|
||||
from .. import writers
|
||||
from ..common import input_is_external_unverified
|
||||
from ..keychain import SLIP44_TESTNET, validate_path_against_script_type
|
||||
from . import helpers, tx_weight
|
||||
from . import layout, tx_weight
|
||||
from .sig_hasher import BitcoinSigHasher
|
||||
from .tx_info import OriginalTxInfo
|
||||
|
||||
@ -147,8 +147,10 @@ class BasicApprover(Approver):
|
||||
self.chunkify = bool(tx.chunkify)
|
||||
|
||||
async def add_internal_input(self, txi: TxInput, node: bip32.HDNode) -> None:
|
||||
from apps.common.paths import show_path_warning
|
||||
|
||||
if not validate_path_against_script_type(self.coin, txi):
|
||||
await helpers.confirm_foreign_address(txi.address_n)
|
||||
await show_path_warning(txi.address_n)
|
||||
self.foreign_address_confirmed = True
|
||||
|
||||
await super().add_internal_input(txi, node)
|
||||
@ -165,6 +167,8 @@ class BasicApprover(Approver):
|
||||
raise ProcessError("Transaction has changed during signing")
|
||||
|
||||
async def _add_output(self, txo: TxOutput, script_pubkey: bytes) -> None:
|
||||
from apps.common.paths import show_path_warning
|
||||
|
||||
from ..common import CHANGE_OUTPUT_TO_INPUT_SCRIPT_TYPES
|
||||
|
||||
if txo.address_n and not validate_path_against_script_type(
|
||||
@ -173,7 +177,7 @@ class BasicApprover(Approver):
|
||||
script_type=CHANGE_OUTPUT_TO_INPUT_SCRIPT_TYPES[txo.script_type],
|
||||
multisig=bool(txo.multisig),
|
||||
):
|
||||
await helpers.confirm_foreign_address(txo.address_n)
|
||||
await show_path_warning(txo.address_n)
|
||||
|
||||
await super()._add_output(txo, script_pubkey)
|
||||
|
||||
@ -202,7 +206,7 @@ class BasicApprover(Approver):
|
||||
raise ProcessError(
|
||||
"Reducing original output amounts is not supported."
|
||||
)
|
||||
await helpers.confirm_modify_output(
|
||||
await layout.confirm_modify_output(
|
||||
txo, orig_txo, self.coin, self.amount_unit
|
||||
)
|
||||
elif txo.amount > orig_txo.amount:
|
||||
@ -224,7 +228,7 @@ class BasicApprover(Approver):
|
||||
elif txo.payment_req_index is None or self.show_payment_req_details:
|
||||
# Ask user to confirm output, unless it is part of a payment
|
||||
# request, which gets confirmed separately.
|
||||
await helpers.confirm_output(
|
||||
await layout.confirm_output(
|
||||
txo,
|
||||
self.coin,
|
||||
self.amount_unit,
|
||||
@ -240,7 +244,7 @@ class BasicApprover(Approver):
|
||||
if msg.amount is None:
|
||||
raise DataError("Missing payment request amount.")
|
||||
|
||||
result = await helpers.confirm_payment_request(msg, self.coin, self.amount_unit)
|
||||
result = await layout.confirm_payment_request(msg, self.coin, self.amount_unit)
|
||||
# When user wants to see more info, the result will be False.
|
||||
self.show_payment_req_details = result is False
|
||||
|
||||
@ -252,7 +256,7 @@ class BasicApprover(Approver):
|
||||
|
||||
title = self._replacement_title(tx_info, orig_txs)
|
||||
for orig in orig_txs:
|
||||
await helpers.confirm_replacement(title, orig.orig_hash)
|
||||
await layout.confirm_replacement(title, orig.orig_hash)
|
||||
|
||||
def _replacement_title(
|
||||
self, tx_info: TxInfo, orig_txs: list[OriginalTxInfo]
|
||||
@ -277,10 +281,10 @@ class BasicApprover(Approver):
|
||||
await super().approve_tx(tx_info, orig_txs)
|
||||
|
||||
if self.has_unverified_external_input:
|
||||
await helpers.confirm_unverified_external_input()
|
||||
await layout.confirm_unverified_external_input()
|
||||
|
||||
if tx_info.wallet_path.get_path() is None:
|
||||
await helpers.confirm_multiple_accounts()
|
||||
await layout.confirm_multiple_accounts()
|
||||
|
||||
fee = self.total_in - self.total_out
|
||||
|
||||
@ -299,10 +303,10 @@ class BasicApprover(Approver):
|
||||
if fee > fee_threshold:
|
||||
if fee > 10 * fee_threshold and safety_checks.is_strict():
|
||||
raise DataError("The fee is unexpectedly large")
|
||||
await helpers.confirm_feeoverthreshold(fee, coin, amount_unit)
|
||||
await layout.confirm_feeoverthreshold(fee, coin, amount_unit)
|
||||
|
||||
if self.change_count > self.MAX_SILENT_CHANGE_COUNT:
|
||||
await helpers.confirm_change_count_over_threshold(self.change_count)
|
||||
await layout.confirm_change_count_over_threshold(self.change_count)
|
||||
|
||||
if orig_txs:
|
||||
# Replacement transaction.
|
||||
@ -338,7 +342,7 @@ class BasicApprover(Approver):
|
||||
# Not a PayJoin: Show the actual fee difference, since any difference in the fee is
|
||||
# coming entirely from the user's own funds and from decreases of external outputs.
|
||||
# We consider the decreases as belonging to the user.
|
||||
await helpers.confirm_modify_fee(
|
||||
await layout.confirm_modify_fee(
|
||||
title, fee - orig_fee, fee, fee_rate, coin, amount_unit
|
||||
)
|
||||
elif spending > orig_spending:
|
||||
@ -346,7 +350,7 @@ class BasicApprover(Approver):
|
||||
# PayJoin and user is spending more: Show the increase in the user's contribution
|
||||
# to the fee, ignoring any contribution from external inputs. Decreasing of
|
||||
# external outputs is not allowed in PayJoin, so there is no need to handle those.
|
||||
await helpers.confirm_modify_fee(
|
||||
await layout.confirm_modify_fee(
|
||||
title, spending - orig_spending, fee, fee_rate, coin, amount_unit
|
||||
)
|
||||
else:
|
||||
@ -357,12 +361,12 @@ class BasicApprover(Approver):
|
||||
else:
|
||||
# Standard transaction.
|
||||
if tx_info.tx.lock_time > 0:
|
||||
await helpers.confirm_nondefault_locktime(
|
||||
await layout.confirm_nondefault_locktime(
|
||||
tx_info.tx.lock_time, tx_info.lock_time_disabled()
|
||||
)
|
||||
|
||||
if not self.external_in:
|
||||
await helpers.confirm_total(
|
||||
await layout.confirm_total(
|
||||
total,
|
||||
fee,
|
||||
fee_rate,
|
||||
@ -371,7 +375,7 @@ class BasicApprover(Approver):
|
||||
tx_info.wallet_path.get_path(),
|
||||
)
|
||||
else:
|
||||
await helpers.confirm_joint_total(spending, total, coin, amount_unit)
|
||||
await layout.confirm_joint_total(spending, total, coin, amount_unit)
|
||||
|
||||
|
||||
class CoinJoinApprover(Approver):
|
||||
|
@ -23,7 +23,15 @@ if TYPE_CHECKING:
|
||||
from typing import Sequence
|
||||
|
||||
from trezor.crypto import bip32
|
||||
from trezor.messages import PrevInput, PrevOutput, PrevTx, SignTx, TxInput, TxOutput
|
||||
from trezor.messages import (
|
||||
PrevInput,
|
||||
PrevOutput,
|
||||
PrevTx,
|
||||
SignTx,
|
||||
TxInput,
|
||||
TxOutput,
|
||||
TxRequest,
|
||||
)
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.keychain import Keychain
|
||||
@ -40,7 +48,7 @@ _SERIALIZED_TX_BUFFER = empty_bytearray(_MAX_SERIALIZED_CHUNK_SIZE)
|
||||
|
||||
|
||||
class Bitcoin:
|
||||
async def signer(self) -> None:
|
||||
async def signer(self) -> TxRequest:
|
||||
progress.init(
|
||||
self.tx_info.tx, is_coinjoin=isinstance(self.approver, CoinJoinApprover)
|
||||
)
|
||||
@ -87,9 +95,12 @@ class Bitcoin:
|
||||
# Sign segwit inputs and serialize witness data.
|
||||
await self.step6_sign_segwit_inputs()
|
||||
|
||||
# Write footer and send remaining data.
|
||||
# Write footer and remaining data.
|
||||
await self.step7_finish()
|
||||
|
||||
# Return the finishing message.
|
||||
return helpers.finished_request(self.tx_req)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
tx: SignTx,
|
||||
@ -333,7 +344,6 @@ class Bitcoin:
|
||||
self.write_tx_footer(self.serialized_tx, self.tx_info.tx)
|
||||
if __debug__:
|
||||
progress.assert_finished()
|
||||
await helpers.request_tx_finish(self.tx_req)
|
||||
|
||||
async def process_internal_input(self, txi: TxInput, node: bip32.HDNode) -> None:
|
||||
if txi.script_type not in common.INTERNAL_INPUT_SCRIPT_TYPES:
|
||||
|
@ -90,10 +90,12 @@ class DecredApprover(BasicApprover):
|
||||
async def add_decred_sstx_submission(
|
||||
self, txo: TxOutput, script_pubkey: bytes
|
||||
) -> None:
|
||||
from .layout import confirm_decred_sstx_submission
|
||||
|
||||
# NOTE: The following calls Approver.add_external_output(), not BasicApprover.add_external_output().
|
||||
# This is needed to skip calling helpers.confirm_output(), which is what BasicApprover would do.
|
||||
await super(BasicApprover, self).add_external_output(txo, script_pubkey, None)
|
||||
await helpers.confirm_decred_sstx_submission(txo, self.coin, self.amount_unit)
|
||||
await confirm_decred_sstx_submission(txo, self.coin, self.amount_unit)
|
||||
|
||||
|
||||
class DecredSigHasher:
|
||||
@ -293,8 +295,6 @@ class Decred(Bitcoin):
|
||||
if __debug__:
|
||||
progress.assert_finished()
|
||||
|
||||
await helpers.request_tx_finish(self.tx_req)
|
||||
|
||||
def check_prevtx_output(self, txo_bin: PrevOutput) -> None:
|
||||
if txo_bin.decred_script_version != 0:
|
||||
raise ProcessError("Cannot use utxo that has script_version != 0")
|
||||
|
@ -1,17 +1,13 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from trezor import utils
|
||||
from trezor.enums import RequestType
|
||||
from trezor.wire import DataError
|
||||
from trezor.wire.context import call
|
||||
|
||||
from .. import common
|
||||
from ..writers import TX_HASH_SIZE
|
||||
from . import layout
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from typing import Any, Awaitable
|
||||
|
||||
from trezor.enums import AmountUnit
|
||||
from trezor.messages import (
|
||||
PrevInput,
|
||||
PrevOutput,
|
||||
@ -24,297 +20,24 @@ if TYPE_CHECKING:
|
||||
)
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.paths import Bip32Path
|
||||
|
||||
# Machine instructions
|
||||
# ===
|
||||
|
||||
|
||||
class UiConfirm:
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
raise NotImplementedError
|
||||
|
||||
__eq__ = utils.obj_eq
|
||||
|
||||
|
||||
class UiConfirmOutput(UiConfirm):
|
||||
def __init__(
|
||||
self,
|
||||
output: TxOutput,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
output_index: int,
|
||||
chunkify: bool,
|
||||
):
|
||||
self.output = output
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
self.output_index = output_index
|
||||
self.chunkify = chunkify
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_output(
|
||||
self.output,
|
||||
self.coin,
|
||||
self.amount_unit,
|
||||
self.output_index,
|
||||
self.chunkify,
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmDecredSSTXSubmission(UiConfirm):
|
||||
def __init__(self, output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit):
|
||||
self.output = output
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_decred_sstx_submission(
|
||||
self.output, self.coin, self.amount_unit
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmPaymentRequest(UiConfirm):
|
||||
def __init__(
|
||||
self,
|
||||
payment_req: TxAckPaymentRequest,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
):
|
||||
self.payment_req = payment_req
|
||||
self.amount_unit = amount_unit
|
||||
self.coin = coin
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_payment_request(
|
||||
self.payment_req, self.coin, self.amount_unit
|
||||
)
|
||||
|
||||
__eq__ = utils.obj_eq
|
||||
|
||||
|
||||
class UiConfirmReplacement(UiConfirm):
|
||||
def __init__(self, title: str, txid: bytes):
|
||||
self.title = title
|
||||
self.txid = txid
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_replacement(self.title, self.txid)
|
||||
|
||||
|
||||
class UiConfirmModifyOutput(UiConfirm):
|
||||
def __init__(
|
||||
self,
|
||||
txo: TxOutput,
|
||||
orig_txo: TxOutput,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
):
|
||||
self.txo = txo
|
||||
self.orig_txo = orig_txo
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_modify_output(
|
||||
self.txo, self.orig_txo, self.coin, self.amount_unit
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmModifyFee(UiConfirm):
|
||||
def __init__(
|
||||
self,
|
||||
title: str,
|
||||
user_fee_change: int,
|
||||
total_fee_new: int,
|
||||
fee_rate: float,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
):
|
||||
self.title = title
|
||||
self.user_fee_change = user_fee_change
|
||||
self.total_fee_new = total_fee_new
|
||||
self.fee_rate = fee_rate
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_modify_fee(
|
||||
self.title,
|
||||
self.user_fee_change,
|
||||
self.total_fee_new,
|
||||
self.fee_rate,
|
||||
self.coin,
|
||||
self.amount_unit,
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmTotal(UiConfirm):
|
||||
def __init__(
|
||||
self,
|
||||
spending: int,
|
||||
fee: int,
|
||||
fee_rate: float,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
address_n: Bip32Path | None,
|
||||
):
|
||||
self.spending = spending
|
||||
self.fee = fee
|
||||
self.fee_rate = fee_rate
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
self.address_n = address_n
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_total(
|
||||
self.spending,
|
||||
self.fee,
|
||||
self.fee_rate,
|
||||
self.coin,
|
||||
self.amount_unit,
|
||||
self.address_n,
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmJointTotal(UiConfirm):
|
||||
def __init__(
|
||||
self, spending: int, total: int, coin: CoinInfo, amount_unit: AmountUnit
|
||||
):
|
||||
self.spending = spending
|
||||
self.total = total
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_joint_total(
|
||||
self.spending, self.total, self.coin, self.amount_unit
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmFeeOverThreshold(UiConfirm):
|
||||
def __init__(self, fee: int, coin: CoinInfo, amount_unit: AmountUnit):
|
||||
self.fee = fee
|
||||
self.coin = coin
|
||||
self.amount_unit = amount_unit
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_feeoverthreshold(self.fee, self.coin, self.amount_unit)
|
||||
|
||||
|
||||
class UiConfirmChangeCountOverThreshold(UiConfirm):
|
||||
def __init__(self, change_count: int):
|
||||
self.change_count = change_count
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_change_count_over_threshold(self.change_count)
|
||||
|
||||
|
||||
class UiConfirmUnverifiedExternalInput(UiConfirm):
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_unverified_external_input()
|
||||
|
||||
|
||||
class UiConfirmForeignAddress(UiConfirm):
|
||||
def __init__(self, address_n: list):
|
||||
self.address_n = address_n
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
from apps.common import paths
|
||||
|
||||
return paths.show_path_warning(self.address_n)
|
||||
|
||||
|
||||
class UiConfirmNonDefaultLocktime(UiConfirm):
|
||||
def __init__(self, lock_time: int, lock_time_disabled: bool):
|
||||
self.lock_time = lock_time
|
||||
self.lock_time_disabled = lock_time_disabled
|
||||
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_nondefault_locktime(
|
||||
self.lock_time, self.lock_time_disabled
|
||||
)
|
||||
|
||||
|
||||
class UiConfirmMultipleAccounts(UiConfirm):
|
||||
def confirm_dialog(self) -> Awaitable[Any]:
|
||||
return layout.confirm_multiple_accounts()
|
||||
|
||||
|
||||
def confirm_output(output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit, output_index: int, chunkify: bool) -> Awaitable[None]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmOutput(output, coin, amount_unit, output_index, chunkify))
|
||||
|
||||
|
||||
def confirm_decred_sstx_submission(output: TxOutput, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[None]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmDecredSSTXSubmission(output, coin, amount_unit))
|
||||
|
||||
|
||||
def confirm_payment_request(payment_req: TxAckPaymentRequest, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmPaymentRequest(payment_req, coin, amount_unit))
|
||||
|
||||
|
||||
def confirm_replacement(description: str, txid: bytes) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmReplacement(description, txid))
|
||||
|
||||
|
||||
def confirm_modify_output(txo: TxOutput, orig_txo: TxOutput, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmModifyOutput(txo, orig_txo, coin, amount_unit))
|
||||
|
||||
|
||||
def confirm_modify_fee(title: str, user_fee_change: int, total_fee_new: int, fee_rate: float, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (
|
||||
yield UiConfirmModifyFee(
|
||||
title, user_fee_change, total_fee_new, fee_rate, coin, amount_unit
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def confirm_total(spending: int, fee: int, fee_rate: float, coin: CoinInfo, amount_unit: AmountUnit, address_n: Bip32Path | None) -> Awaitable[None]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmTotal(spending, fee, fee_rate, coin, amount_unit, address_n))
|
||||
|
||||
|
||||
def confirm_joint_total(spending: int, total: int, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmJointTotal(spending, total, coin, amount_unit))
|
||||
|
||||
|
||||
def confirm_feeoverthreshold(fee: int, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmFeeOverThreshold(fee, coin, amount_unit))
|
||||
|
||||
|
||||
def confirm_change_count_over_threshold(change_count: int) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmChangeCountOverThreshold(change_count))
|
||||
|
||||
|
||||
def confirm_unverified_external_input() -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmUnverifiedExternalInput())
|
||||
|
||||
|
||||
def confirm_foreign_address(address_n: list) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmForeignAddress(address_n))
|
||||
|
||||
|
||||
def confirm_nondefault_locktime(lock_time: int, lock_time_disabled: bool) -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmNonDefaultLocktime(lock_time, lock_time_disabled))
|
||||
|
||||
|
||||
def confirm_multiple_accounts() -> Awaitable[Any]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmMultipleAccounts())
|
||||
|
||||
|
||||
def request_tx_meta(tx_req: TxRequest, coin: CoinInfo, tx_hash: bytes | None = None) -> Awaitable[PrevTx]: # type: ignore [awaitable-is-generator]
|
||||
async def request_tx_meta(
|
||||
tx_req: TxRequest, coin: CoinInfo, tx_hash: bytes | None = None
|
||||
) -> PrevTx:
|
||||
from trezor.messages import TxAckPrevMeta
|
||||
|
||||
assert tx_req.details is not None
|
||||
tx_req.request_type = RequestType.TXMETA
|
||||
tx_req.details.tx_hash = tx_hash
|
||||
ack = yield TxAckPrevMeta, tx_req
|
||||
ack = await call(tx_req, TxAckPrevMeta)
|
||||
_clear_tx_request(tx_req)
|
||||
return _sanitize_tx_meta(ack.tx, coin)
|
||||
|
||||
|
||||
def request_tx_extra_data(
|
||||
async def request_tx_extra_data(
|
||||
tx_req: TxRequest, offset: int, size: int, tx_hash: bytes | None = None
|
||||
) -> Awaitable[bytearray]: # type: ignore [awaitable-is-generator]
|
||||
) -> bytes:
|
||||
from trezor.messages import TxAckPrevExtraData
|
||||
|
||||
details = tx_req.details # local_cache_attribute
|
||||
@ -324,12 +47,14 @@ def request_tx_extra_data(
|
||||
details.extra_data_offset = offset
|
||||
details.extra_data_len = size
|
||||
details.tx_hash = tx_hash
|
||||
ack = yield TxAckPrevExtraData, tx_req
|
||||
ack = await call(tx_req, TxAckPrevExtraData)
|
||||
_clear_tx_request(tx_req)
|
||||
return ack.tx.extra_data_chunk
|
||||
|
||||
|
||||
def request_tx_input(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None) -> Awaitable[TxInput]: # type: ignore [awaitable-is-generator]
|
||||
async def request_tx_input(
|
||||
tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None
|
||||
) -> TxInput:
|
||||
from trezor.messages import TxAckInput
|
||||
|
||||
assert tx_req.details is not None
|
||||
@ -339,24 +64,28 @@ def request_tx_input(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes |
|
||||
else:
|
||||
tx_req.request_type = RequestType.TXINPUT
|
||||
tx_req.details.request_index = i
|
||||
ack = yield TxAckInput, tx_req
|
||||
ack = await call(tx_req, TxAckInput)
|
||||
_clear_tx_request(tx_req)
|
||||
return _sanitize_tx_input(ack.tx.input, coin)
|
||||
|
||||
|
||||
def request_tx_prev_input(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None) -> Awaitable[PrevInput]: # type: ignore [awaitable-is-generator]
|
||||
async def request_tx_prev_input(
|
||||
tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None
|
||||
) -> PrevInput:
|
||||
from trezor.messages import TxAckPrevInput
|
||||
|
||||
assert tx_req.details is not None
|
||||
tx_req.request_type = RequestType.TXINPUT
|
||||
tx_req.details.request_index = i
|
||||
tx_req.details.tx_hash = tx_hash
|
||||
ack = yield TxAckPrevInput, tx_req
|
||||
ack = await call(tx_req, TxAckPrevInput)
|
||||
_clear_tx_request(tx_req)
|
||||
return _sanitize_tx_prev_input(ack.tx.input, coin)
|
||||
|
||||
|
||||
def request_tx_output(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None) -> Awaitable[TxOutput]: # type: ignore [awaitable-is-generator]
|
||||
async def request_tx_output(
|
||||
tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None
|
||||
) -> TxOutput:
|
||||
from trezor.messages import TxAckOutput
|
||||
|
||||
assert tx_req.details is not None
|
||||
@ -366,39 +95,40 @@ def request_tx_output(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes
|
||||
else:
|
||||
tx_req.request_type = RequestType.TXOUTPUT
|
||||
tx_req.details.request_index = i
|
||||
ack = yield TxAckOutput, tx_req
|
||||
ack = await call(tx_req, TxAckOutput)
|
||||
_clear_tx_request(tx_req)
|
||||
return _sanitize_tx_output(ack.tx.output, coin)
|
||||
|
||||
|
||||
def request_tx_prev_output(tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None) -> Awaitable[PrevOutput]: # type: ignore [awaitable-is-generator]
|
||||
async def request_tx_prev_output(
|
||||
tx_req: TxRequest, i: int, coin: CoinInfo, tx_hash: bytes | None = None
|
||||
) -> PrevOutput:
|
||||
from trezor.messages import TxAckPrevOutput
|
||||
|
||||
assert tx_req.details is not None
|
||||
tx_req.request_type = RequestType.TXOUTPUT
|
||||
tx_req.details.request_index = i
|
||||
tx_req.details.tx_hash = tx_hash
|
||||
ack = yield TxAckPrevOutput, tx_req
|
||||
ack = await call(tx_req, TxAckPrevOutput)
|
||||
_clear_tx_request(tx_req)
|
||||
# return sanitize_tx_prev_output(ack.tx, coin) # no sanitize is required
|
||||
return ack.tx.output
|
||||
|
||||
|
||||
def request_payment_req(tx_req: TxRequest, i: int) -> Awaitable[TxAckPaymentRequest]: # type: ignore [awaitable-is-generator]
|
||||
async def request_payment_req(tx_req: TxRequest, i: int) -> TxAckPaymentRequest:
|
||||
from trezor.messages import TxAckPaymentRequest
|
||||
|
||||
assert tx_req.details is not None
|
||||
tx_req.request_type = RequestType.TXPAYMENTREQ
|
||||
tx_req.details.request_index = i
|
||||
ack = yield TxAckPaymentRequest, tx_req
|
||||
ack = await call(tx_req, TxAckPaymentRequest)
|
||||
_clear_tx_request(tx_req)
|
||||
return _sanitize_payment_req(ack)
|
||||
|
||||
|
||||
def request_tx_finish(tx_req: TxRequest) -> Awaitable[None]: # type: ignore [awaitable-is-generator]
|
||||
def finished_request(tx_req: TxRequest) -> TxRequest:
|
||||
tx_req.request_type = RequestType.TXFINISHED
|
||||
yield None, tx_req
|
||||
_clear_tx_request(tx_req)
|
||||
return tx_req
|
||||
|
||||
|
||||
def _clear_tx_request(tx_req: TxRequest) -> None:
|
||||
|
@ -140,8 +140,6 @@ class ZcashV4(Bitcoinlike):
|
||||
async def step7_finish(self) -> None:
|
||||
from apps.common.writers import write_compact_size
|
||||
|
||||
from . import helpers
|
||||
|
||||
serialized_tx = self.serialized_tx # local_cache_attribute
|
||||
|
||||
if self.serialize:
|
||||
@ -152,8 +150,6 @@ class ZcashV4(Bitcoinlike):
|
||||
write_compact_size(serialized_tx, 0) # nShieldedOutput
|
||||
write_compact_size(serialized_tx, 0) # nJoinSplit
|
||||
|
||||
await helpers.request_tx_finish(self.tx_req)
|
||||
|
||||
async def sign_nonsegwit_input(self, i_sign: int) -> None:
|
||||
await self.sign_nonsegwit_bip143_input(i_sign)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user