From 02226a6bee7fcf8f322a14c7d5eeeccffeffb2c5 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 23 Jul 2026 16:54:14 +0200 Subject: [PATCH] Show amounts for OP_RETURN outputs --- .../modules/flows/sign_psbt_common_flow.py | 4 +- .../Passport/modules/tests/test_unit.py | 4 ++ .../Passport/modules/tests/unit/sign_psbt.py | 42 +++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 ports/stm32/boards/Passport/modules/tests/unit/sign_psbt.py diff --git a/ports/stm32/boards/Passport/modules/flows/sign_psbt_common_flow.py b/ports/stm32/boards/Passport/modules/flows/sign_psbt_common_flow.py index 5bf2716ba..ebab17283 100644 --- a/ports/stm32/boards/Passport/modules/flows/sign_psbt_common_flow.py +++ b/ports/stm32/boards/Passport/modules/flows/sign_psbt_common_flow.py @@ -201,7 +201,9 @@ def render_output(self, o): dest = self.chain.render_address(o.scriptPubKey) if dest.startswith("OP_RETURN"): - return '\n{}\n{}'.format( + return '\n{}\n{}\n\n{}\n{}'.format( + recolor(HIGHLIGHT_TEXT_HEX, 'Amount'), + val, recolor(HIGHLIGHT_TEXT_HEX, 'Message'), dest.split('\n', 1)[1]) # user-defined message starts after "OP_RETURN:\n" diff --git a/ports/stm32/boards/Passport/modules/tests/test_unit.py b/ports/stm32/boards/Passport/modules/tests/test_unit.py index a088f75fb..2eb9bc04b 100644 --- a/ports/stm32/boards/Passport/modules/tests/test_unit.py +++ b/ports/stm32/boards/Passport/modules/tests/test_unit.py @@ -24,5 +24,9 @@ def test_ui(test): assert test('ui.py') == b'OK' +def test_sign_psbt(test): + assert test('sign_psbt.py') == b'OK' + + def test_foundation(test): assert test('foundation.py') == b'OK' diff --git a/ports/stm32/boards/Passport/modules/tests/unit/sign_psbt.py b/ports/stm32/boards/Passport/modules/tests/unit/sign_psbt.py new file mode 100644 index 000000000..2c0e5912a --- /dev/null +++ b/ports/stm32/boards/Passport/modules/tests/unit/sign_psbt.py @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: 2026 Foundation Devices, Inc. +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Test trusted-display rendering for PSBT outputs. + +from flows.sign_psbt_common_flow import SignPsbtCommonFlow + + +class FakeChain: + def render_value(self, value): + return (str(value), 'sats') + + def render_address(self, script): + return 'OP_RETURN:\n{}'.format(script) + + +class FakeFlow: + chain = FakeChain() + + +class FakeOutput: + def __init__(self, value, message): + self.nValue = value + self.scriptPubKey = message + + +def assert_op_return_output(value, message): + rendered = SignPsbtCommonFlow.render_output(FakeFlow(), FakeOutput(value, message)) + + amount_label = rendered.find('Amount') + amount = rendered.find('{} sats'.format(value)) + message_label = rendered.find('Message') + payload = rendered.find(message) + + assert -1 not in (amount_label, amount, message_label, payload) + assert amount_label < amount < message_label < payload + + +assert_op_return_output(0, 'zero-value-message') +assert_op_return_output(50000000, 'payment-id-12345') + +return_value.write(b'OK')