diff --git a/core/src/apps/bitcoin/sign_tx/helpers.py b/core/src/apps/bitcoin/sign_tx/helpers.py index 9494463541..bfe19020dc 100644 --- a/core/src/apps/bitcoin/sign_tx/helpers.py +++ b/core/src/apps/bitcoin/sign_tx/helpers.py @@ -54,6 +54,31 @@ class UiConfirmOutput(UiConfirm): __eq__ = utils.obj_eq +class UiConfirmReplacement(UiConfirm): + def __init__(self, description: str, txid: bytes): + self.description = description + self.txid = txid + + def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: + return layout.confirm_replacement(ctx, self.description, self.txid) + + __eq__ = utils.obj_eq + + +class UiConfirmModifyFee(UiConfirm): + def __init__(self, user_fee_change: int, total_fee_new: int, coin: CoinInfo): + self.user_fee_change = user_fee_change + self.total_fee_new = total_fee_new + self.coin = coin + + def confirm_dialog(self, ctx: wire.Context) -> Awaitable[Any]: + return layout.confirm_modify_fee( + ctx, self.user_fee_change, self.total_fee_new, self.coin + ) + + __eq__ = utils.obj_eq + + class UiConfirmTotal(UiConfirm): def __init__(self, spending: int, fee: int, coin: CoinInfo): self.spending = spending @@ -126,6 +151,14 @@ def confirm_output(output: TxOutput, coin: CoinInfo) -> Awaitable[None]: # type return (yield UiConfirmOutput(output, coin)) +def confirm_replacement(description: str, txid: bytes) -> Awaitable[Any]: # type: ignore + return (yield UiConfirmReplacement(description, txid)) + + +def confirm_modify_fee(user_fee_change: int, total_fee_new: int, coin: CoinInfo) -> Awaitable[Any]: # type: ignore + return (yield UiConfirmModifyFee(user_fee_change, total_fee_new, coin)) + + def confirm_total(spending: int, fee: int, coin: CoinInfo) -> Awaitable[None]: # type: ignore return (yield UiConfirmTotal(spending, fee, coin)) diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index c6d59908a0..48755588c9 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -59,6 +59,34 @@ async def confirm_output(ctx: wire.Context, output: TxOutput, coin: CoinInfo) -> await require_confirm(ctx, text, ButtonRequestType.ConfirmOutput) +async def confirm_replacement(ctx: wire.Context, description: str, txid: bytes) -> None: + text = Text(description, ui.ICON_SEND, ui.GREEN) + text.normal("Confirm transaction ID:") + hex_data = hexlify(txid).decode() + if len(hex_data) >= 18 * 4: + hex_data = hex_data[: (18 * 4 - 3)] + "..." + text.mono(*split_op_return(hex_data)) + await require_confirm(ctx, text, ButtonRequestType.SignTx) + + +async def confirm_modify_fee( + ctx: wire.Context, user_fee_change: int, total_fee_new: int, coin: CoinInfo +) -> None: + text = Text("Fee modification", ui.ICON_SEND, ui.GREEN) + if user_fee_change == 0: + text.normal("Your fee did not change.") + else: + if user_fee_change < 0: + text.normal("Decrease your fee by:") + else: + text.normal("Increase your fee by:") + text.bold(format_coin_amount(abs(user_fee_change), coin)) + text.br_half() + text.normal("Transaction fee:") + text.bold(format_coin_amount(total_fee_new, coin)) + await require_hold_to_confirm(ctx, text, ButtonRequestType.SignTx) + + async def confirm_joint_total( ctx: wire.Context, spending: int, total: int, coin: CoinInfo ) -> None: