1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-04-24 02:59:03 +00:00

feat(core): Implement payment requests in Ethereum signing.

This commit is contained in:
Andrew Kozlik 2025-04-10 13:46:51 +02:00
parent 0e12ef6027
commit 3b839eac5d
5 changed files with 56 additions and 9 deletions

View File

@ -124,7 +124,7 @@ def with_keychain_from_path(
slip44 = _slip44_from_address_n(msg.address_n)
defs = _defs_from_message(msg, slip44=slip44)
schemas = _schemas_from_network(patterns, defs.network)
keychain = await get_keychain(CURVE, schemas)
keychain = await get_keychain(CURVE, schemas, [[b"SLIP-0024"]])
with keychain:
return await func(msg, keychain, defs)
@ -140,7 +140,7 @@ def with_keychain_from_chain_id(
async def wrapper(msg: MsgInSignTx) -> MsgOut:
defs = _defs_from_message(msg, chain_id=msg.chain_id)
schemas = _schemas_from_network(PATTERNS_ADDRESS, defs.network)
keychain = await get_keychain(CURVE, schemas)
keychain = await get_keychain(CURVE, schemas, [[b"SLIP-0024"]])
with keychain:
return await func(msg, keychain, defs)

View File

@ -28,7 +28,7 @@ if TYPE_CHECKING:
async def require_confirm_tx(
to_bytes: bytes,
recipient: str | None,
value: int,
address_n: list[int],
maximum_fee: str,
@ -40,12 +40,11 @@ async def require_confirm_tx(
) -> None:
from trezor.ui.layouts import confirm_ethereum_tx
to_str = address_from_bytes(to_bytes, network) if to_bytes else None
total_amount = format_ethereum_amount(value, token, network)
account, account_path = get_account_and_path(address_n)
await confirm_ethereum_tx(
to_str,
recipient,
total_amount,
account,
account_path,

View File

@ -7,7 +7,7 @@ from trezor.wire import DataError
from apps.ethereum import staking_tx_constants as constants
from .helpers import bytes_from_address
from .helpers import address_from_bytes, bytes_from_address
from .keychain import with_keychain_from_chain_id
if TYPE_CHECKING:
@ -21,6 +21,7 @@ if TYPE_CHECKING:
)
from apps.common.keychain import Keychain
from apps.common.payment_request import PaymentRequestVerifier
from .definitions import Definitions
from .keychain import MsgInSignTx
@ -67,7 +68,25 @@ async def sign_tx(
gas_limit,
defs.network,
)
await confirm_tx_data(msg, defs, address_bytes, maximum_fee, fee_items, data_total)
payment_req_verifier = None
if msg.payment_req:
from apps.common.payment_request import PaymentRequestVerifier
slip44_id = paths.unharden(msg.address_n[1])
payment_req_verifier = PaymentRequestVerifier(
msg.payment_req, slip44_id, keychain
)
await confirm_tx_data(
msg,
defs,
address_bytes,
maximum_fee,
fee_items,
data_total,
payment_req_verifier,
)
progress_obj = progress(title=TR.progress__signing_transaction)
progress_obj.report(30)
@ -121,6 +140,7 @@ async def confirm_tx_data(
maximum_fee: str,
fee_items: Iterable[tuple[str, str]],
data_total_len: int,
payment_req_verifier: PaymentRequestVerifier | None,
) -> None:
# function distinguishes between staking / smart contracts / regular transactions
from .layout import require_confirm_other_data, require_confirm_tx
@ -131,13 +151,19 @@ async def confirm_tx_data(
# Handle ERC-20, currently only 'transfer' function
token, recipient, value = await _handle_erc20_transfer(msg, defs, address_bytes)
recipient_str = address_from_bytes(recipient, defs.network) if recipient else None
if msg.payment_req and payment_req_verifier:
payment_req_verifier.add_output(value, recipient_str or "")
payment_req_verifier.verify()
recipient_str = msg.payment_req.recipient_name
is_contract_interaction = token is None and data_total_len > 0
if is_contract_interaction:
await require_confirm_other_data(msg.data_initial_chunk, data_total_len)
await require_confirm_tx(
recipient,
recipient_str,
value,
msg.address_n,
maximum_fee,

View File

@ -69,7 +69,25 @@ async def sign_tx_eip1559(
gas_limit,
defs.network,
)
await confirm_tx_data(msg, defs, address_bytes, maximum_fee, fee_items, data_total)
payment_req_verifier = None
if msg.payment_req:
from apps.common.payment_request import PaymentRequestVerifier
slip44_id = paths.unharden(msg.address_n[1])
payment_req_verifier = PaymentRequestVerifier(
msg.payment_req, slip44_id, keychain
)
await confirm_tx_data(
msg,
defs,
address_bytes,
maximum_fee,
fee_items,
data_total,
payment_req_verifier,
)
# transaction data confirmed, proceed with signing
data = bytearray()

View File

@ -208,6 +208,7 @@ def sign_tx(
tx_type: Optional[int] = None,
definitions: Optional[messages.EthereumDefinitions] = None,
chunkify: bool = False,
payment_req: Optional[messages.PaymentRequest] = None,
) -> Tuple[int, bytes, bytes]:
if chain_id is None:
raise exceptions.TrezorException("Chain ID cannot be undefined")
@ -223,6 +224,7 @@ def sign_tx(
tx_type=tx_type,
definitions=definitions,
chunkify=chunkify,
payment_req=payment_req,
)
if data is None:
@ -269,6 +271,7 @@ def sign_tx_eip1559(
access_list: Optional[List[messages.EthereumAccessList]] = None,
definitions: Optional[messages.EthereumDefinitions] = None,
chunkify: bool = False,
payment_req: Optional[messages.PaymentRequest] = None,
) -> Tuple[int, bytes, bytes]:
length = len(data)
data, chunk = data[1024:], data[:1024]
@ -286,6 +289,7 @@ def sign_tx_eip1559(
data_initial_chunk=chunk,
definitions=definitions,
chunkify=chunkify,
payment_req=payment_req,
)
response = client.call(msg)