mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-16 09:32:00 +00:00
150 lines
4.5 KiB
Python
150 lines
4.5 KiB
Python
from trezor.messages.TxOutputType import TxOutputType
|
|
from trezor.messages.TxOutputBinType import TxOutputBinType
|
|
from trezor.messages.TxInputType import TxInputType
|
|
from trezor.messages.SignTx import SignTx
|
|
from trezor.messages.TxRequest import TxRequest
|
|
from trezor.messages.TransactionType import TransactionType
|
|
from trezor.messages.RequestType import TXINPUT, TXOUTPUT, TXMETA, TXEXTRADATA, TXFINISHED
|
|
from trezor.messages import InputScriptType
|
|
|
|
from apps.common.coininfo import CoinInfo
|
|
|
|
# Machine instructions
|
|
# ===
|
|
|
|
|
|
class UiConfirmOutput:
|
|
|
|
def __init__(self, output: TxOutputType, coin: CoinInfo):
|
|
self.output = output
|
|
self.coin = coin
|
|
|
|
|
|
class UiConfirmTotal:
|
|
|
|
def __init__(self, spending: int, fee: int, coin: CoinInfo):
|
|
self.spending = spending
|
|
self.fee = fee
|
|
self.coin = coin
|
|
|
|
|
|
class UiConfirmFeeOverThreshold:
|
|
|
|
def __init__(self, fee: int, coin: CoinInfo):
|
|
self.fee = fee
|
|
self.coin = coin
|
|
|
|
|
|
class UiConfirmForeignAddress:
|
|
|
|
def __init__(self, address_n: list, coin: CoinInfo):
|
|
self.address_n = address_n
|
|
self.coin = coin
|
|
|
|
|
|
def confirm_output(output: TxOutputType, coin: CoinInfo):
|
|
return (yield UiConfirmOutput(output, coin))
|
|
|
|
|
|
def confirm_total(spending: int, fee: int, coin: CoinInfo):
|
|
return (yield UiConfirmTotal(spending, fee, coin))
|
|
|
|
|
|
def confirm_feeoverthreshold(fee: int, coin: CoinInfo):
|
|
return (yield UiConfirmFeeOverThreshold(fee, coin))
|
|
|
|
|
|
def confirm_foreign_address(address_n: list, coin: CoinInfo):
|
|
return (yield UiConfirmForeignAddress(address_n, coin))
|
|
|
|
|
|
def request_tx_meta(tx_req: TxRequest, tx_hash: bytes=None):
|
|
tx_req.request_type = TXMETA
|
|
tx_req.details.tx_hash = tx_hash
|
|
tx_req.details.request_index = None
|
|
ack = yield tx_req
|
|
tx_req.serialized = None
|
|
return sanitize_tx_meta(ack.tx)
|
|
|
|
|
|
def request_tx_extra_data(tx_req: TxRequest, offset: int, size: int, tx_hash: bytes=None):
|
|
tx_req.request_type = TXEXTRADATA
|
|
tx_req.details.extra_data_offset = offset
|
|
tx_req.details.extra_data_len = size
|
|
tx_req.details.tx_hash = tx_hash
|
|
tx_req.details.request_index = None
|
|
ack = yield tx_req
|
|
tx_req.serialized = None
|
|
return ack.tx.extra_data
|
|
|
|
|
|
def request_tx_input(tx_req: TxRequest, i: int, tx_hash: bytes=None):
|
|
tx_req.request_type = TXINPUT
|
|
tx_req.details.request_index = i
|
|
tx_req.details.tx_hash = tx_hash
|
|
ack = yield tx_req
|
|
tx_req.serialized = None
|
|
return sanitize_tx_input(ack.tx)
|
|
|
|
|
|
def request_tx_output(tx_req: TxRequest, i: int, tx_hash: bytes=None):
|
|
tx_req.request_type = TXOUTPUT
|
|
tx_req.details.request_index = i
|
|
tx_req.details.tx_hash = tx_hash
|
|
ack = yield tx_req
|
|
tx_req.serialized = None
|
|
if tx_hash is None:
|
|
return sanitize_tx_output(ack.tx)
|
|
else:
|
|
return sanitize_tx_binoutput(ack.tx)
|
|
|
|
|
|
def request_tx_finish(tx_req: TxRequest):
|
|
tx_req.request_type = TXFINISHED
|
|
tx_req.details = None
|
|
yield tx_req
|
|
tx_req.serialized = None
|
|
|
|
|
|
# Data sanitizers
|
|
# ===
|
|
|
|
|
|
def sanitize_sign_tx(tx: SignTx) -> SignTx:
|
|
tx.version = tx.version if tx.version is not None else 1
|
|
tx.lock_time = tx.lock_time if tx.lock_time is not None else 0
|
|
tx.inputs_count = tx.inputs_count if tx.inputs_count is not None else 0
|
|
tx.outputs_count = tx.outputs_count if tx.outputs_count is not None else 0
|
|
tx.coin_name = tx.coin_name if tx.coin_name is not None else 'Bitcoin'
|
|
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
|
tx.overwintered = tx.overwintered if tx.overwintered is not None else False
|
|
return tx
|
|
|
|
|
|
def sanitize_tx_meta(tx: TransactionType) -> TransactionType:
|
|
tx.version = tx.version if tx.version is not None else 1
|
|
tx.lock_time = tx.lock_time if tx.lock_time is not None else 0
|
|
tx.inputs_cnt = tx.inputs_cnt if tx.inputs_cnt is not None else 0
|
|
tx.outputs_cnt = tx.outputs_cnt if tx.outputs_cnt is not None else 0
|
|
tx.extra_data_len = tx.extra_data_len if tx.extra_data_len is not None else 0
|
|
tx.expiry = tx.expiry if tx.expiry is not None else 0
|
|
tx.overwintered = tx.overwintered if tx.overwintered is not None else False
|
|
return tx
|
|
|
|
|
|
def sanitize_tx_input(tx: TransactionType) -> TxInputType:
|
|
txi = tx.inputs[0]
|
|
if txi.script_type is None:
|
|
txi.script_type = InputScriptType.SPENDADDRESS
|
|
if txi.sequence is None:
|
|
txi.sequence = 0xffffffff
|
|
return txi
|
|
|
|
|
|
def sanitize_tx_output(tx: TransactionType) -> TxOutputType:
|
|
return tx.outputs[0]
|
|
|
|
|
|
def sanitize_tx_binoutput(tx: TransactionType) -> TxOutputBinType:
|
|
return tx.bin_outputs[0]
|