mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-20 14:39:22 +00:00
feat(core): Show source account path in BTC signing.
This commit is contained in:
parent
d4ddc78dbb
commit
60aa2e7292
1
core/.changelog.d/2151.added
Normal file
1
core/.changelog.d/2151.added
Normal file
@ -0,0 +1 @@
|
||||
Show source account path in BTC signing.
|
@ -342,7 +342,14 @@ class BasicApprover(Approver):
|
||||
)
|
||||
|
||||
if not self.external_in:
|
||||
await helpers.confirm_total(total, fee, fee_rate, coin, amount_unit)
|
||||
await helpers.confirm_total(
|
||||
total,
|
||||
fee,
|
||||
fee_rate,
|
||||
coin,
|
||||
amount_unit,
|
||||
tx_info.wallet_path.get_path(),
|
||||
)
|
||||
else:
|
||||
await helpers.confirm_joint_total(spending, total, coin, amount_unit)
|
||||
|
||||
|
@ -24,6 +24,7 @@ if TYPE_CHECKING:
|
||||
TxAckPaymentRequest,
|
||||
)
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.paths import Bip32Path
|
||||
|
||||
# Machine instructions
|
||||
# ===
|
||||
@ -139,16 +140,24 @@ class UiConfirmTotal(UiConfirm):
|
||||
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, ctx: Context) -> Awaitable[Any]:
|
||||
return layout.confirm_total(
|
||||
ctx, self.spending, self.fee, self.fee_rate, self.coin, self.amount_unit
|
||||
ctx,
|
||||
self.spending,
|
||||
self.fee,
|
||||
self.fee_rate,
|
||||
self.coin,
|
||||
self.amount_unit,
|
||||
self.address_n,
|
||||
)
|
||||
|
||||
|
||||
@ -241,8 +250,8 @@ def confirm_modify_fee(user_fee_change: int, total_fee_new: int, fee_rate: float
|
||||
)
|
||||
|
||||
|
||||
def confirm_total(spending: int, fee: int, fee_rate: float, coin: CoinInfo, amount_unit: AmountUnit) -> Awaitable[None]: # type: ignore [awaitable-is-generator]
|
||||
return (yield UiConfirmTotal(spending, fee, 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]
|
||||
|
@ -9,7 +9,11 @@ from trezor.ui.layouts import confirm_metadata
|
||||
from apps.common.paths import address_n_to_str
|
||||
|
||||
from .. import addresses
|
||||
from ..common import CHANGE_OUTPUT_TO_INPUT_SCRIPT_TYPES, format_fee_rate
|
||||
from ..common import (
|
||||
BIP32_WALLET_DEPTH,
|
||||
CHANGE_OUTPUT_TO_INPUT_SCRIPT_TYPES,
|
||||
format_fee_rate,
|
||||
)
|
||||
from ..keychain import address_n_to_name
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -21,6 +25,7 @@ if TYPE_CHECKING:
|
||||
from trezor.wire import Context
|
||||
|
||||
from apps.common.coininfo import CoinInfo
|
||||
from apps.common.paths import Bip32Path
|
||||
|
||||
_LOCKTIME_TIMESTAMP_MIN_VALUE = const(500_000_000)
|
||||
|
||||
@ -222,12 +227,21 @@ async def confirm_total(
|
||||
fee_rate: float,
|
||||
coin: CoinInfo,
|
||||
amount_unit: AmountUnit,
|
||||
address_n: Bip32Path | None,
|
||||
) -> None:
|
||||
|
||||
account_label = (
|
||||
"mixed accounts"
|
||||
if address_n is None
|
||||
else address_n_to_name(coin, list(address_n) + [0] * BIP32_WALLET_DEPTH)
|
||||
or f"path {address_n_to_str(address_n)}"
|
||||
)
|
||||
await layouts.confirm_total(
|
||||
ctx,
|
||||
format_coin_amount(spending, coin, amount_unit),
|
||||
format_coin_amount(fee, coin, amount_unit),
|
||||
fee_rate_amount=format_fee_rate(fee_rate, coin) if fee_rate >= 0 else None,
|
||||
account_label=account_label,
|
||||
)
|
||||
|
||||
|
||||
|
@ -5,6 +5,8 @@ if TYPE_CHECKING:
|
||||
|
||||
from trezor.messages import TxInput, TxOutput
|
||||
|
||||
from apps.common.paths import Bip32Path
|
||||
|
||||
T = TypeVar("T")
|
||||
else:
|
||||
# typechecker cheat: Generic[T] will be `object` which is a valid parent type
|
||||
@ -90,6 +92,11 @@ class WalletPathChecker(MatchChecker):
|
||||
return None
|
||||
return txio.address_n[:-BIP32_WALLET_DEPTH]
|
||||
|
||||
def get_path(self) -> Bip32Path | None:
|
||||
if isinstance(self.attribute, list):
|
||||
return self.attribute
|
||||
return None
|
||||
|
||||
|
||||
class MultisigFingerprintChecker(MatchChecker):
|
||||
def attribute_from_tx(self, txio: TxInput | TxOutput) -> Any:
|
||||
|
@ -216,6 +216,7 @@ async def confirm_total(
|
||||
title: str = "Confirm transaction",
|
||||
total_label: str = "Total amount:\n",
|
||||
fee_label: str = "\nincluding fee:\n",
|
||||
account_label: str | None = None,
|
||||
br_type: str = "confirm_total",
|
||||
br_code: ButtonRequestType = ButtonRequestType.SignTx,
|
||||
) -> None:
|
||||
|
@ -837,6 +837,7 @@ async def confirm_total(
|
||||
title: str = "SENDING",
|
||||
total_label: str = "Total amount:",
|
||||
fee_label: str = "Fee:",
|
||||
account_label: str | None = None,
|
||||
br_type: str = "confirm_total",
|
||||
br_code: ButtonRequestType = ButtonRequestType.SignTx,
|
||||
) -> None:
|
||||
@ -856,7 +857,7 @@ async def confirm_total(
|
||||
ctx,
|
||||
title,
|
||||
total_amount,
|
||||
total_label,
|
||||
f"From {account_label}\r\n{total_label}" if account_label else total_label,
|
||||
br_type,
|
||||
br_code,
|
||||
hold=True,
|
||||
|
@ -104,7 +104,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
|
||||
helpers.UiConfirmOutput(out2, coin, AmountUnit.BITCOIN),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(12300000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(12300000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
@ -238,7 +238,7 @@ class TestSignSegwitTxNativeP2WPKH(unittest.TestCase):
|
||||
helpers.UiConfirmForeignAddress(address_n=out2.address_n),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(5000000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(5000000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
|
@ -105,7 +105,7 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase):
|
||||
helpers.UiConfirmNonDefaultLocktime(tx.lock_time, lock_time_disabled=False),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(12300000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(12300000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
@ -236,7 +236,7 @@ class TestSignSegwitTxNativeP2WPKH_GRS(unittest.TestCase):
|
||||
helpers.UiConfirmNonDefaultLocktime(tx.lock_time, lock_time_disabled=False),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(5000000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(5000000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
|
@ -101,7 +101,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
|
||||
helpers.UiConfirmOutput(out2, coin, AmountUnit.BITCOIN),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(123445789 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(123445789 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
@ -229,7 +229,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
|
||||
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=1, tx_hash=None), serialized=EMPTY_SERIALIZED),
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out2)),
|
||||
|
||||
helpers.UiConfirmTotal(12300000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(12300000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
@ -377,7 +377,7 @@ class TestSignSegwitTxP2WPKHInP2SH(unittest.TestCase):
|
||||
TxRequest(request_type=TXOUTPUT, details=TxRequestDetailsType(request_index=1, tx_hash=None), serialized=EMPTY_SERIALIZED),
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out2)),
|
||||
|
||||
helpers.UiConfirmTotal(9 - 1, 9 - 8 - 1, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(9 - 1, 9 - 8 - 1, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
|
@ -105,7 +105,7 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase):
|
||||
helpers.UiConfirmNonDefaultLocktime(tx.lock_time, lock_time_disabled=False),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(123445789 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(123445789 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
@ -235,7 +235,7 @@ class TestSignSegwitTxP2WPKHInP2SH_GRS(unittest.TestCase):
|
||||
helpers.UiConfirmNonDefaultLocktime(tx.lock_time, lock_time_disabled=False),
|
||||
True,
|
||||
|
||||
helpers.UiConfirmTotal(12300000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(12300000 + 11000, 11000, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
|
||||
# check prev tx
|
||||
|
@ -148,7 +148,7 @@ class TestSignTxFeeThreshold(unittest.TestCase):
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out1)),
|
||||
helpers.UiConfirmOutput(out1, coin_bitcoin, AmountUnit.BITCOIN),
|
||||
True,
|
||||
helpers.UiConfirmTotal(300000 + 90000, 90000, fee_rate, coin_bitcoin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(300000 + 90000, 90000, fee_rate, coin_bitcoin, AmountUnit.BITCOIN, None),
|
||||
True,
|
||||
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=EMPTY_SERIALIZED),
|
||||
TxAckInput(tx=TxAckInputWrapper(input=inp1)),
|
||||
|
@ -113,7 +113,7 @@ class TestSignTx(unittest.TestCase):
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out1)),
|
||||
helpers.UiConfirmOutput(out1, coin_bitcoin, AmountUnit.BITCOIN),
|
||||
True,
|
||||
helpers.UiConfirmTotal(3_801_747, 50_000, fee_rate, coin_bitcoin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(3_801_747, 50_000, fee_rate, coin_bitcoin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
# ButtonRequest(code=ButtonRequest_ConfirmOutput),
|
||||
# ButtonRequest(code=ButtonRequest_SignTx),
|
||||
|
@ -112,7 +112,7 @@ class TestSignTxDecred(unittest.TestCase):
|
||||
helpers.UiConfirmOutput(out1, coin_decred, AmountUnit.BITCOIN),
|
||||
True,
|
||||
helpers.UiConfirmTotal(
|
||||
200_000_000, 100_000, fee_rate, coin_decred, AmountUnit.BITCOIN
|
||||
200_000_000, 100_000, fee_rate, coin_decred, AmountUnit.BITCOIN, inp1.address_n[:3]
|
||||
),
|
||||
True,
|
||||
TxRequest(
|
||||
@ -294,7 +294,7 @@ class TestSignTxDecred(unittest.TestCase):
|
||||
),
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out3)),
|
||||
helpers.UiConfirmTotal(
|
||||
200_000_000, 100_000, fee_rate, coin_decred, AmountUnit.BITCOIN
|
||||
200_000_000, 100_000, fee_rate, coin_decred, AmountUnit.BITCOIN, inp1.address_n[:3]
|
||||
),
|
||||
True,
|
||||
TxRequest(
|
||||
|
@ -72,7 +72,7 @@ class TestSignTx_GRS(unittest.TestCase):
|
||||
TxAckOutput(tx=TxAckOutputWrapper(output=out1)),
|
||||
helpers.UiConfirmOutput(out1, coin, AmountUnit.BITCOIN),
|
||||
True,
|
||||
helpers.UiConfirmTotal(210016, 192, fee_rate, coin, AmountUnit.BITCOIN),
|
||||
helpers.UiConfirmTotal(210016, 192, fee_rate, coin, AmountUnit.BITCOIN, inp1.address_n[:3]),
|
||||
True,
|
||||
TxRequest(request_type=TXINPUT, details=TxRequestDetailsType(request_index=0, tx_hash=None), serialized=EMPTY_SERIALIZED),
|
||||
TxAckInput(tx=TxAckInputWrapper(input=inp1)),
|
||||
|
Loading…
Reference in New Issue
Block a user