diff --git a/core/src/apps/bitcoin/common.py b/core/src/apps/bitcoin/common.py index 67f60b4c7..db6b553bf 100644 --- a/core/src/apps/bitcoin/common.py +++ b/core/src/apps/bitcoin/common.py @@ -6,6 +6,7 @@ from trezor.crypto import bech32, bip32, der from trezor.crypto.curve import bip340, secp256k1 from trezor.crypto.hashlib import sha256 from trezor.enums import InputScriptType, OutputScriptType +from trezor.strings import format_amount from trezor.utils import HashWriter, ensure if TYPE_CHECKING: @@ -179,3 +180,20 @@ def tagged_hashwriter(tag: bytes) -> HashWriter: ctx = sha256(tag_digest) ctx.update(tag_digest) return HashWriter(ctx) + + +def format_fee_rate( + fee_rate: float, coin: CoinInfo, include_shortcut: bool = False +) -> str: + # Use format_amount to get correct thousands separator -- micropython's built-in + # formatting doesn't add thousands sep to floating point numbers. + # We multiply by 100 to get a fixed-point integer with two decimal places, + # and add 0.5 to round to the nearest integer. + fee_rate_formatted = format_amount(int(fee_rate * 100 + 0.5), 2) + + if include_shortcut and coin.coin_shortcut != "BTC": + shortcut = " " + coin.coin_shortcut + else: + shortcut = "" + + return f"{fee_rate_formatted} sat{shortcut}/{'v' if coin.segwit else ''}B" diff --git a/core/src/apps/bitcoin/sign_tx/layout.py b/core/src/apps/bitcoin/sign_tx/layout.py index e897d93ad..be0110f3c 100644 --- a/core/src/apps/bitcoin/sign_tx/layout.py +++ b/core/src/apps/bitcoin/sign_tx/layout.py @@ -8,6 +8,7 @@ from trezor.strings import format_amount, format_timestamp from trezor.ui import layouts from .. import addresses +from ..common import format_fee_rate from . import omni if not utils.BITCOIN_ONLY: @@ -165,7 +166,7 @@ async def confirm_modify_fee( user_fee_change, format_coin_amount(abs(user_fee_change), coin, amount_unit), format_coin_amount(total_fee_new, coin, amount_unit), - fee_rate_amount=_get_fee_rate_str(fee_rate, coin), + fee_rate_amount=format_fee_rate(fee_rate, coin) if fee_rate >= 0 else None, ) @@ -183,18 +184,6 @@ async def confirm_joint_total( ) -def _get_fee_rate_str(fee_rate: float, coin: CoinInfo) -> str | None: - if fee_rate >= 0: - # Use format_amount to get correct thousands separator -- micropython's built-in - # formatting doesn't add thousands sep to floating point numbers. - # We multiply by 100 to get a fixed-point integer with two decimal places, - # and add 0.5 to round to the nearest integer. - fee_rate_formatted = format_amount(int(fee_rate * 100 + 0.5), 2) - return f"({fee_rate_formatted} sat/{'v' if coin.segwit else ''}B)" - else: - return None - - async def confirm_total( ctx: wire.Context, spending: int, @@ -207,7 +196,7 @@ async def confirm_total( ctx, total_amount=format_coin_amount(spending, coin, amount_unit), fee_amount=format_coin_amount(fee, coin, amount_unit), - fee_rate_amount=_get_fee_rate_str(fee_rate, coin), + fee_rate_amount=format_fee_rate(fee_rate, coin) if fee_rate >= 0 else None, ) diff --git a/core/src/trezor/ui/layouts/tt/__init__.py b/core/src/trezor/ui/layouts/tt/__init__.py index 3cb5fb24d..2d2c580fa 100644 --- a/core/src/trezor/ui/layouts/tt/__init__.py +++ b/core/src/trezor/ui/layouts/tt/__init__.py @@ -886,7 +886,7 @@ async def confirm_total( text.bold(fee_amount) if fee_rate_amount is not None: - text.normal("\n" + fee_rate_amount) + text.normal(f"\n({fee_rate_amount})") await raise_if_cancelled(interact(ctx, HoldToConfirm(text), br_type, br_code)) @@ -999,7 +999,7 @@ async def confirm_modify_fee( text.normal("Transaction fee:\n") text.bold(total_fee_new) if fee_rate_amount is not None: - text.normal("\n" + fee_rate_amount) + text.normal(f"\n({fee_rate_amount})") await raise_if_cancelled( interact(ctx, HoldToConfirm(text), "modify_fee", ButtonRequestType.SignTx) )